Reworked Utils.
This commit is contained in:
parent
aef7d1fa6a
commit
86cc8b1519
7 changed files with 257 additions and 271 deletions
|
@ -2,12 +2,11 @@
|
||||||
<SmellBaseline>
|
<SmellBaseline>
|
||||||
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
||||||
<CurrentIssues>
|
<CurrentIssues>
|
||||||
<ID>LongMethod:UtilsTest.kt$UtilsTest$@Test fun testSystemProperties()</ID>
|
<ID>MagicNumber:Utils.kt$3</ID>
|
||||||
<ID>MagicNumber:Utils.kt$Utils$3</ID>
|
<ID>MagicNumber:Utils.kt$4</ID>
|
||||||
<ID>MagicNumber:Utils.kt$Utils$4</ID>
|
<ID>MagicNumber:Utils.kt$5</ID>
|
||||||
<ID>MagicNumber:Utils.kt$Utils$5</ID>
|
<ID>NestedBlockDepth:Utils.kt$fun File.loadProperties(): Properties</ID>
|
||||||
<ID>NestedBlockDepth:Utils.kt$Utils$fun loadProperties(file: File): Properties</ID>
|
<ID>NestedBlockDepth:Utils.kt$fun parseSemVer(input: String?, version: Version): Boolean</ID>
|
||||||
<ID>NestedBlockDepth:Utils.kt$Utils$fun parseSemVer(input: String?, version: Version): Boolean</ID>
|
<ID>NestedBlockDepth:Utils.kt$fun saveProperties(projectDir: File, config: SemverConfig, version: Version)</ID>
|
||||||
<ID>NestedBlockDepth:Utils.kt$Utils$fun saveProperties(projectDir: File, config: SemverConfig, version: Version)</ID>
|
|
||||||
</CurrentIssues>
|
</CurrentIssues>
|
||||||
</SmellBaseline>
|
</SmellBaseline>
|
||||||
|
|
|
@ -59,7 +59,7 @@ open class SemverIncrementBuildMetaTask @Inject constructor(
|
||||||
version.buildMeta = buildMeta
|
version.buildMeta = buildMeta
|
||||||
project.version = version.semver
|
project.version = version.semver
|
||||||
if (logger.isLifecycleEnabled) logger.lifecycle("Version: ${project.version}")
|
if (logger.isLifecycleEnabled) logger.lifecycle("Version: ${project.version}")
|
||||||
Utils.saveProperties(project.projectDir, config, version)
|
saveProperties(project.projectDir, config, version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,6 @@ open class SemverIncrementTask @Inject constructor(
|
||||||
)
|
)
|
||||||
project.version = version.semver
|
project.version = version.semver
|
||||||
if (logger.isLifecycleEnabled) logger.lifecycle("Version: ${project.version}")
|
if (logger.isLifecycleEnabled) logger.lifecycle("Version: ${project.version}")
|
||||||
Utils.saveProperties(project.projectDir, config, version)
|
saveProperties(project.projectDir, config, version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class SemverPlugin : Plugin<Project> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun afterEvaluate(project: Project) {
|
private fun afterEvaluate(project: Project) {
|
||||||
val propsFile = Utils.getPropertiesFile(project.projectDir, config.properties)
|
val propsFile = getPropertiesFile(project.projectDir, config.properties)
|
||||||
|
|
||||||
if (project.version != "unspecified" && project.logger.isWarnEnabled) {
|
if (project.version != "unspecified" && project.logger.isWarnEnabled) {
|
||||||
project.logger.warn(
|
project.logger.warn(
|
||||||
|
@ -77,15 +77,15 @@ class SemverPlugin : Plugin<Project> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val props = Utils.loadProperties(this)
|
val props = this.loadProperties()
|
||||||
val requiredProps = setOf(
|
val requiredProps = setOf(
|
||||||
config.semverKey, config.majorKey, config.minorKey, config.patchKey,
|
config.semverKey, config.majorKey, config.minorKey, config.patchKey,
|
||||||
config.preReleaseKey, config.buildMetaKey
|
config.preReleaseKey, config.buildMetaKey
|
||||||
)
|
)
|
||||||
val hasReqProps = !isNew && props.stringPropertyNames().containsAll(requiredProps) &&
|
val hasReqProps = !isNew && props.stringPropertyNames().containsAll(requiredProps) &&
|
||||||
Utils.isNotSystemProperty(requiredProps)
|
requiredProps.isNotSystemProperty()
|
||||||
|
|
||||||
Utils.loadVersion(config, version, props)
|
loadVersion(config, version, props)
|
||||||
|
|
||||||
project.tasks.withType(SemverIncrementBuildMetaTask::class.java) {
|
project.tasks.withType(SemverIncrementBuildMetaTask::class.java) {
|
||||||
buildMeta = version.buildMeta
|
buildMeta = version.buildMeta
|
||||||
|
@ -100,7 +100,7 @@ class SemverPlugin : Plugin<Project> {
|
||||||
if (project.logger.isInfoEnabled) {
|
if (project.logger.isInfoEnabled) {
|
||||||
project.logger.info("[$simpleName] Saving version properties to `$absoluteFile`.")
|
project.logger.info("[$simpleName] Saving version properties to `$absoluteFile`.")
|
||||||
}
|
}
|
||||||
Utils.saveProperties(project.projectDir, config, version)
|
saveProperties(project.projectDir, config, version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
/*
|
|
||||||
* Utils.kt
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018-2022, Erik C. Thauvin (erik@thauvin.net)
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* Neither the name of this project nor the names of its contributors may be
|
|
||||||
* used to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.thauvin.erik.gradle.semver
|
|
||||||
|
|
||||||
import org.gradle.api.GradleException
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.Properties
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The <code>Utils</code> class.
|
|
||||||
*
|
|
||||||
* @author <a href="https://erik.thauvin.net/" target="_blank">Erik C. Thauvin</a>
|
|
||||||
* @created 2019-04-10
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
object Utils {
|
|
||||||
fun File.canReadFile(): Boolean {
|
|
||||||
return canRead() && isFile
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Properties.put(key: String, value: String, isValidCondition: Boolean) {
|
|
||||||
if (isValidCondition) put(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isNotSystemProperty(keys: Set<String>): Boolean {
|
|
||||||
keys.forEach {
|
|
||||||
if (System.getProperties().containsKey(it)) return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPropertiesFile(projectDir: File, propsFile: String): File {
|
|
||||||
return if (File(propsFile).isAbsolute) {
|
|
||||||
File(propsFile)
|
|
||||||
} else {
|
|
||||||
File(projectDir, propsFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadProperties(file: File): Properties {
|
|
||||||
var isNew = false
|
|
||||||
val props = Properties()
|
|
||||||
file.apply {
|
|
||||||
try {
|
|
||||||
if (!exists() && createNewFile()) {
|
|
||||||
isNew = true
|
|
||||||
}
|
|
||||||
} catch (e: IOException) {
|
|
||||||
throw GradleException("Unable to create: `$absoluteFile`", e)
|
|
||||||
}
|
|
||||||
if (canReadFile()) {
|
|
||||||
FileInputStream(this).reader().use { reader ->
|
|
||||||
props.apply {
|
|
||||||
if (!isNew) {
|
|
||||||
load(reader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw GradleException("Unable to read version from: `$absoluteFile`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadIntProperty(props: Properties, key: String, default: Int): Int {
|
|
||||||
try {
|
|
||||||
return loadProperty(props, key, default.toString()).toInt()
|
|
||||||
} catch (e: java.lang.NumberFormatException) {
|
|
||||||
throw GradleException("Unable to parse $key property. (${e.message})", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadProperty(props: Properties, key: String, default: String): String {
|
|
||||||
return System.getProperty(key, if (props.isNotEmpty()) props.getProperty(key, default) else default)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadVersion(config: SemverConfig, version: Version, props: Properties) {
|
|
||||||
props.apply {
|
|
||||||
if (!parseSemVer(System.getProperty(config.semverKey), version)) {
|
|
||||||
version.major = loadIntProperty(this, config.majorKey, Version.DEFAULT_MAJOR)
|
|
||||||
version.minor = loadIntProperty(this, config.minorKey, Version.DEFAULT_MINOR)
|
|
||||||
version.patch = loadIntProperty(this, config.patchKey, Version.DEFAULT_PATCH)
|
|
||||||
version.preRelease = loadProperty(this, config.preReleaseKey, Version.DEFAULT_EMPTY)
|
|
||||||
version.buildMeta = loadProperty(this, config.buildMetaKey, Version.DEFAULT_EMPTY)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isEmpty) {
|
|
||||||
version.preReleasePrefix =
|
|
||||||
getProperty(config.preReleasePrefixKey, Version.DEFAULT_PRERELEASE_PREFIX)
|
|
||||||
version.buildMetaPrefix =
|
|
||||||
getProperty(config.buildMetaPrefixKey, Version.DEFAULT_BUILDMETA_PREFIX)
|
|
||||||
version.separator = getProperty(config.separatorKey, Version.DEFAULT_SEPARATOR)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parseSemVer(input: String?, version: Version): Boolean {
|
|
||||||
if (input.isNullOrBlank()) return false
|
|
||||||
|
|
||||||
try {
|
|
||||||
val max = 5
|
|
||||||
val min = 3
|
|
||||||
|
|
||||||
val parts = input.split(
|
|
||||||
Regex("[\\Q${version.separator}${version.preReleasePrefix}${version.buildMetaPrefix}\\E]"),
|
|
||||||
max
|
|
||||||
)
|
|
||||||
|
|
||||||
if (parts.size >= min) {
|
|
||||||
version.major = parts[0].toInt()
|
|
||||||
version.minor = parts[1].toInt()
|
|
||||||
version.patch = parts[2].toInt()
|
|
||||||
version.preRelease = ""
|
|
||||||
version.buildMeta = ""
|
|
||||||
|
|
||||||
if (parts.size > min) {
|
|
||||||
when (parts.size) {
|
|
||||||
max -> {
|
|
||||||
version.preRelease = parts[3]
|
|
||||||
version.buildMeta = parts[4]
|
|
||||||
}
|
|
||||||
4 -> {
|
|
||||||
if (input.endsWith(version.buildMetaPrefix + parts[3])) {
|
|
||||||
version.buildMeta = parts[3]
|
|
||||||
} else {
|
|
||||||
version.preRelease = parts[3]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw NumberFormatException("Not enough parts.")
|
|
||||||
}
|
|
||||||
} catch (e: NumberFormatException) {
|
|
||||||
throw GradleException("Unable to parse version: \"$input\" (${e.message})", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun saveProperties(projectDir: File, config: SemverConfig, version: Version) {
|
|
||||||
val propsFile = getPropertiesFile(projectDir, config.properties)
|
|
||||||
SortedProperties().apply {
|
|
||||||
try {
|
|
||||||
propsFile.apply {
|
|
||||||
if (canReadFile()) {
|
|
||||||
FileInputStream(this).reader().use { load(it) }
|
|
||||||
} else {
|
|
||||||
createNewFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
put(config.semverKey, version.semver)
|
|
||||||
put(config.majorKey, version.major.toString())
|
|
||||||
put(config.minorKey, version.minor.toString())
|
|
||||||
put(config.patchKey, version.patch.toString())
|
|
||||||
put(config.preReleaseKey, version.preRelease)
|
|
||||||
put(config.buildMetaKey, version.buildMeta)
|
|
||||||
put(config.semverKey, version.semver)
|
|
||||||
|
|
||||||
put(
|
|
||||||
config.buildMetaPrefixKey, version.buildMetaPrefix,
|
|
||||||
version.buildMetaPrefix != Version.DEFAULT_BUILDMETA_PREFIX ||
|
|
||||||
containsKey(config.buildMetaPrefixKey)
|
|
||||||
)
|
|
||||||
put(
|
|
||||||
config.preReleasePrefixKey, version.preReleasePrefix,
|
|
||||||
version.preReleasePrefix != Version.DEFAULT_PRERELEASE_PREFIX ||
|
|
||||||
containsKey(config.preReleasePrefixKey)
|
|
||||||
)
|
|
||||||
put(
|
|
||||||
config.separatorKey, version.separator,
|
|
||||||
version.separator != Version.DEFAULT_SEPARATOR ||
|
|
||||||
containsKey(config.separatorKey)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (canWrite()) {
|
|
||||||
FileOutputStream(this).writer().use {
|
|
||||||
store(it, "Generated by the Semver Plugin for Gradle")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw IOException("Can't write.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: IOException) {
|
|
||||||
throw GradleException("Unable to write version to: `${propsFile.absoluteFile}`", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
214
src/main/kotlin/net/thauvin/erik/gradle/semver/utils.kt
Normal file
214
src/main/kotlin/net/thauvin/erik/gradle/semver/utils.kt
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* utils.kt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2022, Erik C. Thauvin (erik@thauvin.net)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of this project nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.thauvin.erik.gradle.semver
|
||||||
|
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
private fun Properties.put(key: String, value: String, isValidCondition: Boolean) {
|
||||||
|
if (isValidCondition) put(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.canReadFile(): Boolean {
|
||||||
|
return canRead() && isFile
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPropertiesFile(projectDir: File, propsFile: String): File {
|
||||||
|
return if (File(propsFile).isAbsolute) {
|
||||||
|
File(propsFile)
|
||||||
|
} else {
|
||||||
|
File(projectDir, propsFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Set<String>.isNotSystemProperty(): Boolean {
|
||||||
|
this.forEach {
|
||||||
|
if (System.getProperties().containsKey(it)) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.loadProperties(): Properties {
|
||||||
|
var isNew = false
|
||||||
|
val props = Properties()
|
||||||
|
this.apply {
|
||||||
|
try {
|
||||||
|
if (!exists() && createNewFile()) {
|
||||||
|
isNew = true
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw GradleException("Unable to create: `$absoluteFile`", e)
|
||||||
|
}
|
||||||
|
if (canReadFile()) {
|
||||||
|
FileInputStream(this).reader().use { reader ->
|
||||||
|
props.apply {
|
||||||
|
if (!isNew) {
|
||||||
|
load(reader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw GradleException("Unable to read version from: `$absoluteFile`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadIntProperty(props: Properties, key: String, default: Int): Int {
|
||||||
|
try {
|
||||||
|
return loadProperty(props, key, default.toString()).toInt()
|
||||||
|
} catch (e: java.lang.NumberFormatException) {
|
||||||
|
throw GradleException("Unable to parse $key property. (${e.message})", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadProperty(props: Properties, key: String, default: String): String {
|
||||||
|
return System.getProperty(key, if (props.isNotEmpty()) props.getProperty(key, default) else default)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadVersion(config: SemverConfig, version: Version, props: Properties) {
|
||||||
|
props.apply {
|
||||||
|
if (!parseSemVer(System.getProperty(config.semverKey), version)) {
|
||||||
|
version.major = loadIntProperty(this, config.majorKey, Version.DEFAULT_MAJOR)
|
||||||
|
version.minor = loadIntProperty(this, config.minorKey, Version.DEFAULT_MINOR)
|
||||||
|
version.patch = loadIntProperty(this, config.patchKey, Version.DEFAULT_PATCH)
|
||||||
|
version.preRelease = loadProperty(this, config.preReleaseKey, Version.DEFAULT_EMPTY)
|
||||||
|
version.buildMeta = loadProperty(this, config.buildMetaKey, Version.DEFAULT_EMPTY)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty) {
|
||||||
|
version.preReleasePrefix =
|
||||||
|
getProperty(config.preReleasePrefixKey, Version.DEFAULT_PRERELEASE_PREFIX)
|
||||||
|
version.buildMetaPrefix =
|
||||||
|
getProperty(config.buildMetaPrefixKey, Version.DEFAULT_BUILDMETA_PREFIX)
|
||||||
|
version.separator = getProperty(config.separatorKey, Version.DEFAULT_SEPARATOR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseSemVer(input: String?, version: Version): Boolean {
|
||||||
|
if (input.isNullOrBlank()) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
val max = 5
|
||||||
|
val min = 3
|
||||||
|
|
||||||
|
val parts = input.split(
|
||||||
|
Regex("[\\Q${version.separator}${version.preReleasePrefix}${version.buildMetaPrefix}\\E]"),
|
||||||
|
max
|
||||||
|
)
|
||||||
|
|
||||||
|
if (parts.size >= min) {
|
||||||
|
version.major = parts[0].toInt()
|
||||||
|
version.minor = parts[1].toInt()
|
||||||
|
version.patch = parts[2].toInt()
|
||||||
|
version.preRelease = ""
|
||||||
|
version.buildMeta = ""
|
||||||
|
|
||||||
|
if (parts.size > min) {
|
||||||
|
when (parts.size) {
|
||||||
|
max -> {
|
||||||
|
version.preRelease = parts[3]
|
||||||
|
version.buildMeta = parts[4]
|
||||||
|
}
|
||||||
|
4 -> {
|
||||||
|
if (input.endsWith(version.buildMetaPrefix + parts[3])) {
|
||||||
|
version.buildMeta = parts[3]
|
||||||
|
} else {
|
||||||
|
version.preRelease = parts[3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw NumberFormatException("Not enough parts.")
|
||||||
|
}
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
throw GradleException("Unable to parse version: \"$input\" (${e.message})", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveProperties(projectDir: File, config: SemverConfig, version: Version) {
|
||||||
|
val propsFile = getPropertiesFile(projectDir, config.properties)
|
||||||
|
SortedProperties().apply {
|
||||||
|
try {
|
||||||
|
propsFile.apply {
|
||||||
|
if (canReadFile()) {
|
||||||
|
FileInputStream(this).reader().use { load(it) }
|
||||||
|
} else {
|
||||||
|
createNewFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
put(config.semverKey, version.semver)
|
||||||
|
put(config.majorKey, version.major.toString())
|
||||||
|
put(config.minorKey, version.minor.toString())
|
||||||
|
put(config.patchKey, version.patch.toString())
|
||||||
|
put(config.preReleaseKey, version.preRelease)
|
||||||
|
put(config.buildMetaKey, version.buildMeta)
|
||||||
|
put(config.semverKey, version.semver)
|
||||||
|
|
||||||
|
put(
|
||||||
|
config.buildMetaPrefixKey, version.buildMetaPrefix,
|
||||||
|
version.buildMetaPrefix != Version.DEFAULT_BUILDMETA_PREFIX ||
|
||||||
|
containsKey(config.buildMetaPrefixKey)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
config.preReleasePrefixKey, version.preReleasePrefix,
|
||||||
|
version.preReleasePrefix != Version.DEFAULT_PRERELEASE_PREFIX ||
|
||||||
|
containsKey(config.preReleasePrefixKey)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
config.separatorKey, version.separator,
|
||||||
|
version.separator != Version.DEFAULT_SEPARATOR ||
|
||||||
|
containsKey(config.separatorKey)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (canWrite()) {
|
||||||
|
FileOutputStream(this).writer().use {
|
||||||
|
store(it, "Generated by the Semver Plugin for Gradle")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw IOException("Can't write.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw GradleException("Unable to write version to: `${propsFile.absoluteFile}`", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* UtilsTest.kt
|
* est.kt
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2022, Erik C. Thauvin (erik@thauvin.net)
|
* Copyright (c) 2018-2022, Erik C. Thauvin (erik@thauvin.net)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
package net.thauvin.erik.gradle.semver
|
package net.thauvin.erik.gradle.semver
|
||||||
|
|
||||||
import net.thauvin.erik.gradle.semver.Utils.canReadFile
|
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
@ -42,7 +41,7 @@ import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Utils] Tests
|
* Tests
|
||||||
*/
|
*/
|
||||||
class UtilsTest {
|
class UtilsTest {
|
||||||
private val version = Version()
|
private val version = Version()
|
||||||
|
@ -53,16 +52,16 @@ class UtilsTest {
|
||||||
@Test
|
@Test
|
||||||
fun testExceptions() {
|
fun testExceptions() {
|
||||||
assertFailsWith<GradleException>("2.1.1a") {
|
assertFailsWith<GradleException>("2.1.1a") {
|
||||||
Utils.parseSemVer("2.1.1a", version)
|
parseSemVer("2.1.1a", version)
|
||||||
}
|
}
|
||||||
assertFailsWith<GradleException>("2a.1.1") {
|
assertFailsWith<GradleException>("2a.1.1") {
|
||||||
Utils.parseSemVer("2a.1.1", version)
|
parseSemVer("2a.1.1", version)
|
||||||
}
|
}
|
||||||
assertFailsWith<GradleException>("2.1a.1") {
|
assertFailsWith<GradleException>("2.1a.1") {
|
||||||
Utils.parseSemVer("2.1a.1", version)
|
parseSemVer("2.1a.1", version)
|
||||||
}
|
}
|
||||||
assertFailsWith<GradleException>("2.1") {
|
assertFailsWith<GradleException>("2.1") {
|
||||||
Utils.parseSemVer("2.1", version)
|
parseSemVer("2.1", version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ class UtilsTest {
|
||||||
fooDir.mkdir()
|
fooDir.mkdir()
|
||||||
val fooFile = File(fooDir, propsFile.name)
|
val fooFile = File(fooDir, propsFile.name)
|
||||||
config.properties = fooFile.absolutePath
|
config.properties = fooFile.absolutePath
|
||||||
Utils.saveProperties(projectDir, config, version)
|
saveProperties(projectDir, config, version)
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
fooFile.canReadFile(),
|
fooFile.canReadFile(),
|
||||||
|
@ -80,7 +79,7 @@ class UtilsTest {
|
||||||
"foo properties file should exists and be readable"
|
"foo properties file should exists and be readable"
|
||||||
)
|
)
|
||||||
|
|
||||||
val fooProps = Utils.loadProperties(fooFile)
|
val fooProps = fooFile.loadProperties()
|
||||||
fooFile.delete()
|
fooFile.delete()
|
||||||
fooDir.delete()
|
fooDir.delete()
|
||||||
|
|
||||||
|
@ -94,14 +93,14 @@ class UtilsTest {
|
||||||
@Test
|
@Test
|
||||||
fun testLoadSaveProperties() {
|
fun testLoadSaveProperties() {
|
||||||
config.properties = propsFile.name
|
config.properties = propsFile.name
|
||||||
Utils.saveProperties(projectDir, config, version)
|
saveProperties(projectDir, config, version)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
propsFile.canReadFile(),
|
propsFile.canReadFile(),
|
||||||
propsFile.canRead() && propsFile.isFile,
|
propsFile.canRead() && propsFile.isFile,
|
||||||
"properties file should exists and be readable"
|
"properties file should exists and be readable"
|
||||||
)
|
)
|
||||||
|
|
||||||
val props = Utils.loadProperties(propsFile)
|
val props = propsFile.loadProperties()
|
||||||
|
|
||||||
assertEquals(props.getProperty(config.majorKey), version.major.toString(), "Major")
|
assertEquals(props.getProperty(config.majorKey), version.major.toString(), "Major")
|
||||||
assertEquals(props.getProperty(config.minorKey), version.minor.toString(), "Minor")
|
assertEquals(props.getProperty(config.minorKey), version.minor.toString(), "Minor")
|
||||||
|
@ -121,7 +120,7 @@ class UtilsTest {
|
||||||
var locked = File("locked")
|
var locked = File("locked")
|
||||||
|
|
||||||
assertFailsWith<GradleException> {
|
assertFailsWith<GradleException> {
|
||||||
Utils.loadProperties(File(locked, propsFile.name))
|
File(locked, propsFile.name).loadProperties()
|
||||||
}
|
}
|
||||||
locked.delete()
|
locked.delete()
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ class UtilsTest {
|
||||||
|
|
||||||
if (!locked.canWrite()) {
|
if (!locked.canWrite()) {
|
||||||
assertFailsWith<GradleException> {
|
assertFailsWith<GradleException> {
|
||||||
Utils.saveProperties(locked.parentFile, config, version)
|
saveProperties(locked.parentFile, config, version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locked.delete()
|
locked.delete()
|
||||||
|
@ -143,9 +142,9 @@ class UtilsTest {
|
||||||
val props = SortedProperties()
|
val props = SortedProperties()
|
||||||
props["foo"] = "bar"
|
props["foo"] = "bar"
|
||||||
|
|
||||||
assertFailsWith<GradleException> { Utils.loadIntProperty(props, "foo", 1) }
|
assertFailsWith<GradleException> { loadIntProperty(props, "foo", 1) }
|
||||||
|
|
||||||
assertEquals(Utils.loadIntProperty(props, "none", 1), 1, "default int value")
|
assertEquals(loadIntProperty(props, "none", 1), 1, "default int value")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -154,7 +153,7 @@ class UtilsTest {
|
||||||
version.buildMetaPrefix = "."
|
version.buildMetaPrefix = "."
|
||||||
|
|
||||||
listOf("2.1.0.beta.1", "2.1.1.1", "3.2.1.beta.1.007").forEach {
|
listOf("2.1.0.beta.1", "2.1.1.1", "3.2.1.beta.1.007").forEach {
|
||||||
assertTrue(Utils.parseSemVer(it, version), "parsing semver: $it")
|
assertTrue(parseSemVer(it, version), "parsing semver: $it")
|
||||||
assertEquals(it, version.semver, it)
|
assertEquals(it, version.semver, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,37 +172,34 @@ class UtilsTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
Utils.isNotSystemProperty(
|
setOf(
|
||||||
setOf(
|
config.majorKey,
|
||||||
config.majorKey,
|
config.minorKey,
|
||||||
config.minorKey,
|
config.patchKey,
|
||||||
config.patchKey,
|
config.preReleaseKey,
|
||||||
config.preReleaseKey,
|
config.buildMetaKey
|
||||||
config.buildMetaKey
|
).isNotSystemProperty(), "none should already exists"
|
||||||
)
|
|
||||||
),
|
|
||||||
"none should already exists"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val props = Utils.loadProperties(propsFile)
|
val props = propsFile.loadProperties()
|
||||||
|
|
||||||
sysProps.forEach {
|
sysProps.forEach {
|
||||||
val msg = "${it.first} should match system properties"
|
val msg = "${it.first} should match system properties"
|
||||||
System.getProperties().setProperty(it.first, it.second)
|
System.getProperties().setProperty(it.first, it.second)
|
||||||
if (it.first == config.majorKey || it.first == config.minorKey || it.first == config.patchKey) {
|
if (it.first == config.majorKey || it.first == config.minorKey || it.first == config.patchKey) {
|
||||||
assertEquals(Utils.loadIntProperty(props, it.first, -1), it.second.toInt(), msg)
|
assertEquals(loadIntProperty(props, it.first, -1), it.second.toInt(), msg)
|
||||||
} else {
|
} else {
|
||||||
assertEquals(Utils.loadProperty(props, it.first, ""), it.second, msg)
|
assertEquals(loadProperty(props, it.first, ""), it.second, msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils.loadVersion(config, version, props)
|
loadVersion(config, version, props)
|
||||||
assertEquals(version.semver, "2.1.1-beta+007", "version should be identical")
|
assertEquals(version.semver, "2.1.1-beta+007", "version should be identical")
|
||||||
|
|
||||||
Utils.saveProperties(projectDir, config, version)
|
saveProperties(projectDir, config, version)
|
||||||
|
|
||||||
val newPropsFile = File(config.properties)
|
val newPropsFile = File(config.properties)
|
||||||
val newProps = Utils.loadProperties(newPropsFile)
|
val newProps = newPropsFile.loadProperties()
|
||||||
|
|
||||||
sysProps.forEach {
|
sysProps.forEach {
|
||||||
assertEquals(newProps.getProperty(it.first), it.second, "new properties should validate")
|
assertEquals(newProps.getProperty(it.first), it.second, "new properties should validate")
|
||||||
|
@ -213,7 +209,7 @@ class UtilsTest {
|
||||||
|
|
||||||
System.getProperties().setProperty(config.semverKey, "3.2.2")
|
System.getProperties().setProperty(config.semverKey, "3.2.2")
|
||||||
props["foo"] = "bar"
|
props["foo"] = "bar"
|
||||||
Utils.loadVersion(config, version, props)
|
loadVersion(config, version, props)
|
||||||
assertEquals(version.semver, System.getProperty(config.semverKey), "versions should match")
|
assertEquals(version.semver, System.getProperty(config.semverKey), "versions should match")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +224,7 @@ class UtilsTest {
|
||||||
"111.11.11-beta",
|
"111.11.11-beta",
|
||||||
"1111.111.11-beta+001.12"
|
"1111.111.11-beta+001.12"
|
||||||
).forEach {
|
).forEach {
|
||||||
assertTrue(Utils.parseSemVer(it, version), "parsing semver: $it")
|
assertTrue(parseSemVer(it, version), "parsing semver: $it")
|
||||||
assertEquals(it, version.semver, it)
|
assertEquals(it, version.semver, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue