diff --git a/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverConfig.kt b/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverConfig.kt index f3f9c42..88609d2 100644 --- a/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverConfig.kt +++ b/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverConfig.kt @@ -63,4 +63,19 @@ open class SemverConfig { var separatorKey = DEFAULT_SEPARATOR get() = "$keysPrefix$field" var keysPrefix = DEFAULT_KEYS_PREFIX + + override fun toString(): String { + return "SemverConfig(" + + "properties='$properties', " + + "majorKey='$majorKey', " + + "minorKey='$minorKey', " + + "patchKey='$patchKey', " + + "preReleaseKey='$preReleaseKey', " + + "preReleasePrefixKey='$preReleasePrefixKey', " + + "buildMetaKey='$buildMetaKey', " + + "buildMetaPrefixKey='$buildMetaPrefixKey', " + + "separator='$separatorKey', " + + "keysPrefix='$keysPrefix')" + + ")" + } } diff --git a/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverPlugin.kt b/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverPlugin.kt index 774787d..5da1f23 100644 --- a/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverPlugin.kt +++ b/src/main/kotlin/net/thauvin/erik/gradle/semver/SemverPlugin.kt @@ -36,8 +36,6 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.util.GradleVersion import java.io.File -import java.io.FileInputStream -import java.util.Properties class SemverPlugin : Plugin { private val simpleName = SemverPlugin::class.simpleName @@ -61,48 +59,39 @@ class SemverPlugin : Plugin { private fun afterEvaluate(project: Project) { val propsFile = File(config.properties) + if (project.version != "unspecified") { project.logger.warn( "Please specify the version in ${propsFile.name} and remove it from ${project.buildFile.name}") } + propsFile.apply { + val isNew = !exists() + project.logger.info( - "[$simpleName] Attempting to read properties from: `$absoluteFile`. [exists: ${exists()}, isFile: $isFile, canRead: ${canRead()}]") - var hasReqProps = false - if (canRead() && isFile) { - FileInputStream(this).reader().use { reader -> - Properties().apply { - load(reader) + "[$simpleName] Attempting to read properties from: `$absoluteFile`. [exists: $isNew, isFile: $isFile, canRead: ${propsFile.canRead()}]") - val requiredProps = setOf(config.majorKey, config.minorKey, config.patchKey, - config.preReleaseKey, config.buildMetaKey) - hasReqProps = stringPropertyNames().containsAll(requiredProps) && - Utils.isNotSystemProperty(requiredProps) + val props = Utils.loadProperties(propsFile) + val requiredProps = setOf(config.majorKey, config.minorKey, config.patchKey, config.preReleaseKey, + config.buildMetaKey) + val hasReqProps = !isNew && props.stringPropertyNames().containsAll(requiredProps) && + Utils.isNotSystemProperty(requiredProps) - version.major = Utils.loadProperty(this, config.majorKey, Version.DEFAULT_MAJOR) - version.minor = Utils.loadProperty(this, config.minorKey, Version.DEFAULT_MINOR) - version.patch = Utils.loadProperty(this, config.patchKey, Version.DEFAULT_PATCH) - version.preRelease = Utils.loadProperty(this, config.preReleaseKey, Version.DEFAULT_EMPTY) - version.preReleasePrefix = - getProperty(config.preReleasePrefixKey, Version.DEFAULT_PRERELEASE_PREFIX) - version.buildMeta = Utils.loadProperty(this, config.buildMetaKey, Version.DEFAULT_EMPTY) - version.buildMetaPrefix = - getProperty(config.buildMetaPrefixKey, Version.DEFAULT_BUILDMETA_PREFIX) - version.separator = getProperty(config.separatorKey, Version.DEFAULT_SEPARATOR) + println(isNew) + println(props.stringPropertyNames().containsAll(requiredProps)) + println(Utils.isNotSystemProperty(requiredProps)) - project.tasks.withType(SemverIncrementBuildMetaTask::class.java) { - buildMeta = version.buildMeta - } - } - } - } else if (exists()) { - throw GradleException("Unable to read version from: `$absoluteFile`") + Utils.loadVersion(config, version, props) + + project.tasks.withType(SemverIncrementBuildMetaTask::class.java) { + buildMeta = version.buildMeta } + project.version = version.semver project.logger.info("[$simpleName] Project version set to: ${project.version}") + if (!hasReqProps || !isFile) { - // If first time running and there is no props file, and the required version properties are missing, - // then version props would never have been saved before + project.logger.info("[$simpleName] Saving version properties to `${config.properties}`.") Utils.saveProperties(config, version) } } diff --git a/src/main/kotlin/net/thauvin/erik/gradle/semver/Utils.kt b/src/main/kotlin/net/thauvin/erik/gradle/semver/Utils.kt index f1497f1..ae93ba6 100644 --- a/src/main/kotlin/net/thauvin/erik/gradle/semver/Utils.kt +++ b/src/main/kotlin/net/thauvin/erik/gradle/semver/Utils.kt @@ -14,45 +14,94 @@ import java.util.Properties * @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): Boolean { keys.forEach { - if (!System.getProperties().containsKey(it)) return true + if (System.getProperties().containsKey(it)) return false } - return false + return true + } + + fun loadProperties(file: File): Properties { + var isNew = false + val props = Properties() + file.apply { + if (!exists()) { + if (!createNewFile()) { + throw GradleException("Unable to create: `$absoluteFile`") + } else { + isNew = true + } + } + 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 loadProperty(props: Properties, key: String, default: String): String { - return System.getProperty(key, props.getProperty(key, default)) + return System.getProperty(key, if (props.isNotEmpty()) props.getProperty(key, default) else default) + } + + fun loadVersion(config: SemverConfig, version: Version, props: Properties) { + props.apply { + version.major = loadProperty(this, config.majorKey, Version.DEFAULT_MAJOR) + version.minor = loadProperty(this, config.minorKey, Version.DEFAULT_MINOR) + version.patch = loadProperty(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 saveProperties(config: SemverConfig, version: Version) { val propsFile = File(config.properties) SortedProperties().apply { propsFile.apply { - if (canRead() && isFile) { + if (canReadFile()) { FileInputStream(this).reader().use { load(it) } - } - } - - put(config.majorKey, version.major) - put(config.minorKey, version.minor) - put(config.patchKey, version.patch) - put(config.preReleaseKey, version.preRelease) - put(config.buildMetaKey, version.buildMeta) - if (version.buildMetaPrefix != Version.DEFAULT_BUILDMETA_PREFIX || - containsKey(config.buildMetaPrefixKey)) - put(config.buildMetaPrefixKey, version.buildMetaPrefix) - if (version.preReleasePrefix != Version.DEFAULT_PRERELEASE_PREFIX || - containsKey(config.preReleasePrefixKey)) - put(config.preReleasePrefixKey, version.preReleasePrefix) - if (version.separator != Version.DEFAULT_SEPARATOR || containsKey(config.separatorKey)) - put(config.separatorKey, version.separator) - - propsFile.apply { - if (!exists()) { - // Need to create the file as canWrite() will not work unless the file exists + } else { createNewFile() } + + put(config.majorKey, version.major) + put(config.minorKey, version.minor) + put(config.patchKey, version.patch) + put(config.preReleaseKey, version.preRelease) + put(config.buildMetaKey, version.buildMeta) + 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") diff --git a/src/main/kotlin/net/thauvin/erik/gradle/semver/Version.kt b/src/main/kotlin/net/thauvin/erik/gradle/semver/Version.kt index 7179745..1ff5cb4 100644 --- a/src/main/kotlin/net/thauvin/erik/gradle/semver/Version.kt +++ b/src/main/kotlin/net/thauvin/erik/gradle/semver/Version.kt @@ -68,4 +68,17 @@ class Version { } if (isPatch) patch = (patch.toInt() + 1).toString() } + + override fun toString(): String { + return "Version(" + + "major='$major', " + + "minor='$minor', " + + "patch='$patch', " + + "preRelease='$preRelease', " + + "preReleasePrefix='$preReleasePrefix', " + + "buildMeta='$buildMeta', " + + "buildMetaPrefix='$buildMetaPrefix', " + + "separator='$separator'" + + ")" + } } diff --git a/src/test/kotlin/net/thauvin/erik/gradle/semver/UtilsSpec.kt b/src/test/kotlin/net/thauvin/erik/gradle/semver/UtilsSpec.kt index 791c5fb..d742885 100644 --- a/src/test/kotlin/net/thauvin/erik/gradle/semver/UtilsSpec.kt +++ b/src/test/kotlin/net/thauvin/erik/gradle/semver/UtilsSpec.kt @@ -31,10 +31,10 @@ */ package net.thauvin.erik.gradle.semver +import net.thauvin.erik.gradle.semver.Utils.canReadFile import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe import java.io.File -import java.nio.file.Files import java.util.Properties import kotlin.test.assertEquals import kotlin.test.assertNull @@ -43,30 +43,23 @@ import kotlin.test.assertTrue @Suppress("unused") object UtilsSpec : Spek({ describe("a config and version") { - val version by memoized { Version() } - val config by memoized { SemverConfig() } - val configFile = File("test.properties") + val version = Version() + val config = SemverConfig() + val propsFile = File("test.properties") lateinit var props: Properties - before { - config.properties = configFile.name - } - describe("save properties") { - it("should save properties") { + it("save properties") { + config.properties = propsFile.name Utils.saveProperties(config, version) - assertTrue(configFile.exists()) + assertTrue(propsFile.canReadFile()) } it("load the properties") { - props = Properties().apply { - Files.newInputStream(configFile.toPath()).use { nis -> - load(nis) - } - configFile.delete() - } + props = Utils.loadProperties(propsFile) + propsFile.delete() } } - describe("validate the properties file") { + describe("validate the properties") { it("version should be the same") { assertEquals(props.getProperty(config.majorKey), version.major, "Major") assertEquals(props.getProperty(config.minorKey), version.minor, "Minor") @@ -95,6 +88,20 @@ object UtilsSpec : Spek({ assertEquals(Utils.loadProperty(props, it.first, ""), it.second) } } + it("load version") { + Utils.loadVersion(config, version, props) + assertEquals(version.semver, "2.1.1-beta+007") + } + it("save new properties") { + Utils.saveProperties(config, version) + } + it("check saved properties") { + val newProps = Utils.loadProperties(propsFile) + newVersion.forEach { + assertEquals(newProps.getProperty(it.first), it.second, it.second) + } + propsFile.delete() + } } } })