1/* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package androidx.build 18 19import java.io.File 20import java.util.regex.Matcher 21import java.util.regex.Pattern 22 23/** 24 * Utility class which represents a version 25 */ 26data class Version( 27 val major: Int, 28 val minor: Int, 29 val patch: Int, 30 val extra: String? = null 31) : Comparable<Version> { 32 33 constructor(versionString: String) : this( 34 Integer.parseInt(checkedMatcher(versionString).group(1)), 35 Integer.parseInt(checkedMatcher(versionString).group(2)), 36 Integer.parseInt(checkedMatcher(versionString).group(3)), 37 if (checkedMatcher(versionString).groupCount() == 4) checkedMatcher( 38 versionString).group(4) else null) 39 40 fun isPatch(): Boolean = patch != 0 41 42 fun isSnapshot(): Boolean = "-SNAPSHOT" == extra 43 44 fun isAlpha(): Boolean = extra?.toLowerCase()?.startsWith("-alpha") ?: false 45 46 fun isFinalApi(): Boolean = !isSnapshot() && !isAlpha() 47 48 override fun compareTo(other: Version) = compareValuesBy(this, other, 49 { it.major }, 50 { it.minor }, 51 { it.patch }, 52 { it.extra == null }, // False (no extra) sorts above true (has extra) 53 { it.extra } // gradle uses lexicographic ordering 54 ) 55 56 override fun toString(): String { 57 return "$major.$minor.$patch${extra ?: ""}" 58 } 59 60 companion object { 61 private val VERSION_FILE_REGEX = Pattern.compile("^(\\d+\\.\\d+\\.\\d+).txt$") 62 private val VERSION_REGEX = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)(-.+)?$") 63 64 private fun checkedMatcher(versionString: String): Matcher { 65 val matcher = VERSION_REGEX.matcher(versionString) 66 if (!matcher.matches()) { 67 throw IllegalArgumentException("Can not parse version: " + versionString) 68 } 69 return matcher 70 } 71 72 /** 73 * @return Version or null, if a name of the given file doesn't match 74 */ 75 fun parseOrNull(file: File): Version? { 76 if (!file.isFile) return null 77 val matcher = VERSION_FILE_REGEX.matcher(file.name) 78 return if (matcher.matches()) Version(matcher.group(1)) else null 79 } 80 81 /** 82 * @return Version or null, if the given string doesn't match 83 */ 84 fun parseOrNull(versionString: String): Version? { 85 val matcher = VERSION_REGEX.matcher(versionString) 86 return if (matcher.matches()) Version(versionString) else null 87 } 88 } 89} 90