Skip to content

Commit

Permalink
feat: Replaced dynamic property handling in grovvy with fields #353 #288
Browse files Browse the repository at this point in the history
  • Loading branch information
Hillkorn committed May 31, 2022
1 parent 118db22 commit 3a178a5
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 85 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ release {

This are all possible configuration options and its default values:

```
``` build.gradle
release {
failOnCommitNeeded = true
failOnPublishNeeded = true
Expand All @@ -216,7 +216,7 @@ release {
versionPatterns = [
/(\d+)([^\d]*$)/: { Matcher m, Project p -> m.replaceAll("${(m[0][1] as int) + 1}${m[0][2]}") }
]
pushReleaseVersionBranch = false
pushReleaseVersionBranch = null
scmAdapters = [
net.researchgate.release.GitAdapter,
net.researchgate.release.SvnAdapter,
Expand All @@ -240,6 +240,30 @@ release {
}
```

### Kotlin DSL Example

``` build.gradle.kts
import net.researchgate.release.ReleaseExtension
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'net.researchgate:gradle-release:3.0.0'
}

apply(plugin = "base")
apply(plugin = "net.researchgate.release")

configure<ReleaseExtension> {
ignoredSnapshotDependencies.set(listOf("net.researchgate:gradle-release"))
with(git) {
requireBranch = "master"
}
}
```

### Custom release steps

To add a step to the release process is very easy. Gradle provides a very nice mechanism for [manipulating existing tasks](http://gradle.org/docs/current/userguide/tutorial_using_tasks.html#N102B2). There are two available hooks provided: `beforeReleaseBuild` which runs before build and `afterReleaseBuild` which runs afterwards.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ abstract class BaseScmAdapter extends PluginHelper {
extension = project.extensions['release'] as ReleaseExtension
}

abstract Object createNewConfig()

abstract boolean isSupported(File directory)

abstract void init()
Expand Down
5 changes: 0 additions & 5 deletions src/main/groovy/net/researchgate/release/BzrAdapter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ class BzrAdapter extends BaseScmAdapter {
super(project, attributes)
}

@Override
Object createNewConfig() {
return null
}

@Override
boolean isSupported(File directory) {
if (!directory.list().grep('.bzr')) {
Expand Down
16 changes: 0 additions & 16 deletions src/main/groovy/net/researchgate/release/GitAdapter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,14 @@ class GitAdapter extends BaseScmAdapter {
def pushOptions = []
boolean signTag = false

/** @deprecated Remove in version 3.0 */
@Deprecated
boolean pushToCurrentBranch = false
String pushToBranchPrefix
boolean commitVersionFileOnly = false

void setProperty(String name, Object value) {
if (name == 'pushToCurrentBranch') {
project.logger?.warn("You are setting the deprecated and unused option '${name}'. You can safely remove it. The deprecated option will be removed in 3.0")
}

metaClass.setProperty(this, name, value)
}
}

GitAdapter(Project project, Map<String, Object> attributes) {
super(project, attributes)
}

@Override
Object createNewConfig() {
return new GitConfig()
}

@Override
boolean isSupported(File directory) {
if (!directory.list().grep('.git')) {
Expand Down
5 changes: 0 additions & 5 deletions src/main/groovy/net/researchgate/release/HgAdapter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ class HgAdapter extends BaseScmAdapter {
super(project, attributes)
}

@Override
Object createNewConfig() {
return null
}

@Override
boolean isSupported(File directory) {
if (!directory.list().grep('.hg')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class PluginHelper {
project.version = getReleaseVersion('1.0.0')
}

if (!useAutomaticVersion() && promptYesOrNo('Do you want to use SNAPSHOT versions inbetween releases')) {
if (!useAutomaticVersion() && promptYesOrNo('Do you want to use SNAPSHOT versions in between releases')) {
attributes.usesSnapshot = true
}

Expand Down
64 changes: 32 additions & 32 deletions src/main/groovy/net/researchgate/release/ReleaseExtension.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,95 @@ package net.researchgate.release
import org.gradle.api.Project
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
import org.gradle.util.ConfigureUtil

import java.util.regex.Matcher
import java.util.regex.Pattern

class ReleaseExtension {

@Input
Property<Boolean> failOnCommitNeeded = project.objects.property(Boolean.class).convention(true)

@Input
Property<Boolean> failOnPublishNeeded = project.objects.property(Boolean.class).convention(true)

@Input
Property<Boolean> failOnSnapshotDependencies = project.objects.property(Boolean.class).convention(true)

@Input
Property<Boolean> failOnUnversionedFiles = project.objects.property(Boolean.class).convention(true)

@Input
Property<Boolean> failOnUpdateNeeded = project.objects.property(Boolean.class).convention(true)

@Input
Property<Boolean> revertOnFail = project.objects.property(Boolean.class).convention(true)

@Input
@Optional
Property<String> pushReleaseVersionBranch = project.objects.property(String.class)

@Input
Property<String> preCommitText = project.objects.property(String.class).convention('')

@Input
Property<String> preTagCommitMessage = project.objects.property(String.class).convention('[Gradle Release Plugin] - pre tag commit: ')

@Input
Property<String> tagCommitMessage = project.objects.property(String.class).convention('[Gradle Release Plugin] - creating tag: ')

@Input
Property<String> newVersionCommitMessage = project.objects.property(String.class).convention('[Gradle Release Plugin] - new version commit: ')

@Input
Property<String> snapshotSuffix = project.objects.property(String.class).convention('-SNAPSHOT')

@Input
Property<String> tagTemplate = project.objects.property(String.class).convention('$version')

@Input
Property<String> versionPropertyFile = project.objects.property(String.class).convention('gradle.properties')

@Input
ListProperty<String> versionProperties = project.objects.listProperty(String.class).convention([])

@Input
ListProperty<String> buildTasks = project.objects.listProperty(String.class).convention([])

@Input
ListProperty<String> ignoredSnapshotDependencies = project.objects.listProperty(String.class).convention([])

@Input
Map<String, Closure<String>> versionPatterns = [
// Increments last number: "2.5-SNAPSHOT" => "2.6-SNAPSHOT"
/(\d+)([^\d]*$)/: { Matcher m, Project p -> m.replaceAll("${(m[0][1] as int) + 1}${m[0][2]}") }
]

@Nested
GitAdapter.GitConfig git = new GitAdapter.GitConfig()

@Nested
SvnAdapter.SvnConfig svn = new SvnAdapter.SvnConfig()

List<Class<? extends BaseScmAdapter>> scmAdapters = [
GitAdapter,
SvnAdapter,
HgAdapter,
BzrAdapter
]

@Internal
BaseScmAdapter scmAdapter

@Internal
private Project project

@Internal
Map<String, Object> attributes // General plugin attributes

ReleaseExtension(Project project, Map<String, Object> attributes) {
Expand All @@ -80,38 +112,6 @@ class ReleaseExtension {
metaClass = mc
}

def propertyMissing(String name) {
BaseScmAdapter adapter = getAdapterForName(name)
Object result = adapter?.createNewConfig()

if (!adapter || !result) {
throw new MissingPropertyException(name, this.class)
}

metaClass."$name" = result
}

def propertyMissing(String name, value) {
BaseScmAdapter adapter = getAdapterForName(name)

if (!adapter) {
throw new MissingPropertyException(name, this.class)
}
metaClass."$name" = value
}

def methodMissing(String name, args) {
metaClass."$name" = { Closure varClosure ->
return ConfigureUtil.configure(varClosure, this."$name")
}

try {
return ConfigureUtil.configure(args[0] as Closure, this."$name")
} catch (MissingPropertyException ignored) {
throw new MissingMethodException(name, this.class, args)
}
}

private BaseScmAdapter getAdapterForName(String name) {
BaseScmAdapter adapter = null
scmAdapters.find {
Expand Down
5 changes: 0 additions & 5 deletions src/main/groovy/net/researchgate/release/SvnAdapter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ class SvnAdapter extends BaseScmAdapter {
boolean pinExternals = false
}

@Override
Object createNewConfig() {
return new SvnConfig();
}

@Override
boolean isSupported(File directory) {
if (!directory.list().grep('.svn')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import org.apache.tools.ant.BuildException
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.slf4j.Logger
import org.slf4j.LoggerFactory

Expand All @@ -17,9 +20,13 @@ class BaseReleaseTask extends DefaultTask {
private static final String LINE_SEP = System.getProperty('line.separator')
private static final String PROMPT = "${LINE_SEP}??>"

@Nested
ReleaseExtension extension

@Internal
Map<String, Object> pluginAttributes

@Internal
Project getRootProject() {
def project = getProject()
if (project.getParent() != null) {
Expand All @@ -34,6 +41,7 @@ class BaseReleaseTask extends DefaultTask {
pluginAttributes = extension.attributes
}

@Internal
BaseScmAdapter getScmAdapter() {
return extension.scmAdapter
}
Expand All @@ -46,6 +54,7 @@ class BaseReleaseTask extends DefaultTask {
*
* @return SLF4J {@link org.slf4j.Logger} instance
*/
@Internal
Logger getLog() { getProject()?.logger ?: LoggerFactory.getLogger(this.class) }

boolean useAutomaticVersion() {
Expand Down Expand Up @@ -91,6 +100,7 @@ class BaseReleaseTask extends DefaultTask {
}
}

@Internal
boolean isVersionDefined() {
getProject().version && Project.DEFAULT_VERSION != getProject().version
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@

package net.researchgate.release

import net.researchgate.release.cli.Executor
import org.eclipse.jgit.api.ResetCommand
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome

import static org.eclipse.jgit.lib.Repository.shortenRefName

class GitReleasePluginIntegrationTests extends GitSpecification {

File settingsFile
Expand Down Expand Up @@ -57,6 +61,7 @@ class GitReleasePluginIntegrationTests extends GitSpecification {
}
"""
}

}

def cleanup() {
Expand All @@ -76,19 +81,24 @@ class GitReleasePluginIntegrationTests extends GitSpecification {
.withPluginClasspath()
.build()
def st = localGit.status().call()
gitCheckoutBranch(remoteGit)
remoteGit.reset().setMode(ResetCommand.ResetType.HARD).setRef("HEAD").call()
then: 'execution was successful'
result.tasks.each {it.outcome == TaskOutcome.SUCCESS }
// and: 'project version updated'
// propertiesFile.text == 'version=1.2\n'
// and: 'mo modified files in local repo'
// st.modified.size() == 0 && st.added.size() == 0 && st.changed.size() == 0
// and: 'tag with old version 1.1 created in local repo'
// localGit.tagList().call().any { shortenRefName(it.name) == '1.1' }
// and: 'property file updated to new version in local repo'
// localGit.repository.workTree.listFiles().any { it.name == 'gradle.properties' && it.text.contains("version=1.2") }
// and: 'property file with new version pushed to remote repo'
// remoteGit.repository.workTree.listFiles().any { it.name == 'gradle.properties' && it.text.contains("version=1.2") }
// and: 'tag with old version 1.1 pushed to remote repo'
// remoteGit.tagList().call().any { shortenRefName(it.name) == '1.1' }
and: 'project version updated'
propertiesFile.text == 'version=1.2\n'
and: 'mo modified files in local repo'
st.modified.size() == 0
st.added.size() == 0
st.changed.size() == 0
st.uncommittedChanges.size() == 0
and: 'tag with old version 1.1 created in local repo'
localGit.tagList().call().any { shortenRefName(it.name) == '1.1' }
and: 'tag with old version 1.1 pushed to remote repo'
remoteGit.tagList().call().any { shortenRefName(it.name) == '1.1' }
and: 'property file updated to new version in local repo'
new File(localGit.repository.workTree.getAbsolutePath(), 'gradle.properties').text == 'version=1.2\n'
and: 'property file with new version pushed to remote repo'
new File(remoteGit.repository.workTree.getAbsolutePath(), 'gradle.properties').text == 'version=1.2\n'
}
}
Loading

0 comments on commit 3a178a5

Please sign in to comment.