import javax.inject.Inject import org.gradle.api.provider.ValueSourceParameters import java.nio.charset.Charset ext { buildVersionCode = { def versionCode = buildNumberCode() def versionName = getVersionName() def (major, minor, patch) = versionName.toLowerCase().tokenize('.') (major, minor, patch) = [major, minor, patch].collect { it.toInteger() } (major * 10_000_000) + (minor * 10_000) + (patch * 1_000) + versionCode } getVersionName = { def props = new Properties() file("$rootDir/app/version/version.properties").withInputStream { props.load(it) } return props.getProperty("VERSION") } getVersionNameSuffix = { if (project.hasProperty("versionNameSuffix")) { return project["versionNameSuffix"] } else { return "" } } buildVersionName = { def suffix = getVersionNameSuffix() if (suffix?.trim()) { return getVersionName() + "." + buildNumberCode() + getVersionNameSuffix() } else { return getVersionName() } } getStoredTag = { if(project.hasProperty("latestTag")) { return project["latestTag"] } else { def latestGitTagProvider = providers.of(LatestGitTagValueSource.class) {} return latestGitTagProvider.get() } } buildNumberCode = { def suffix = getVersionNameSuffix() if (suffix?.trim()) { def tag = getStoredTag() if (tag.contains('nightly')) { def (major, minor, patch, nightly) = tag.toLowerCase().tokenize('.') (major, minor, patch, nightly) = [major, minor, patch, nightly].collect { it.toString() } def (code, sufix) = nightly.toLowerCase().tokenize('-') (code, sufix) = [code, sufix].collect { it.toString() } def newCode = Integer.parseInt(code) + 1 return newCode } else { return 1 } } else { return 0 } } } tasks.register("setBuildNumber") { doLast { if(!project.hasProperty("number")) { throw new IllegalArgumentException("Missing argument: 'number' must be provided") } filePath = "${CI_HOME_DIR}/build_number.properties" if(!new File(filePath).exists()) { throw new IllegalStateException("build number file could not be found at: $filePath") } String buildNumberString = project["number"] Integer buildNumberInt = Integer.parseInt(buildNumberString) if(buildNumberInt >= 1000) { throw new IllegalStateException("Build number limited to 3 digits; cannot exceed 1,000") } println("Setting build number to: $buildNumberInt") def props = new Properties() props.load(new FileInputStream(filePath)) props["build"] = buildNumberInt.toString() def os = new FileOutputStream(filePath) props.store(os, null) } } tasks.register('incrementBuildNumber') { doLast { filePath = "${CI_HOME_DIR}/build_number.properties" if(!new File(filePath).exists()) { return } def props = new Properties() props.load(new FileInputStream(filePath)) String currentBuildNumber = props["build"] Integer buildNumber = Integer.parseInt(currentBuildNumber) buildNumber++ if(buildNumber >= 1000) { throw new IllegalStateException("Build number limited to 3 digits; cannot exceed 1,000") } props["build"] = buildNumber.toString() def os = new FileOutputStream(filePath) props.store(os, null) } } tasks.register('getBuildVersionName') { doLast { print buildVersionName() } } tasks.register('getBuildVersionCode') { doLast { print buildNumberCode() } } abstract class LatestGitTagValueSource implements ValueSource { @Inject abstract ExecOperations getExecOperations() String obtain() { ByteArrayOutputStream output = new ByteArrayOutputStream() execOperations.exec { it.commandLine "git", "describe", "--tags", "--abbrev=0" it.standardOutput = output } return new String(output.toByteArray(), Charset.defaultCharset()) } }