forked from tschulte/gradle-semantic-release-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes tschulte#30 BREAKING CHANGE: Incompatible with other plugins still using Grgit 1, namely `org.ajoberstar.release-*` and `org.ajoberstar.github-pages`
- Loading branch information
Showing
28 changed files
with
2,931 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
dependencies { | ||
compile localGroovy() | ||
compile gradleApi() | ||
compile "org.ajoberstar:gradle-git:1.7.2" | ||
compile "com.jcabi:jcabi-github:0.28" | ||
compile "org.ajoberstar:grgit:2.2.1" | ||
compile "com.jcabi:jcabi-github:0.33.1" | ||
compile 'com.github.zafarkhaja:java-semver:0.9.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
src/main/groovy/org/ajoberstar/gradle/git/release/base/BaseReleasePlugin.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright 2012-2015 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.ajoberstar.gradle.git.release.base | ||
|
||
import org.gradle.api.GradleException | ||
import org.gradle.api.Plugin | ||
import org.gradle.api.Project | ||
|
||
import org.slf4j.Logger | ||
import org.slf4j.LoggerFactory | ||
|
||
/** | ||
* Plugin providing the base structure of gradle-git's flavor of release | ||
* behavior. The plugin can be applied using the {@code org.ajoberstar.release-base} id. | ||
* | ||
* <p> | ||
* The plugin adds the {@link ReleasePluginExtension} and a {@code release} task. | ||
* </p> | ||
* | ||
* @see org.ajoberstar.gradle.git.release.opinion.Strategies | ||
* @see <a href="https://github.com/ajoberstar/gradle-git/wiki/org.ajoberstar.release-base">Wiki Doc</a> | ||
*/ | ||
class BaseReleasePlugin implements Plugin<Project> { | ||
private static final Logger logger = LoggerFactory.getLogger(BaseReleasePlugin) | ||
private static final String PREPARE_TASK_NAME = 'prepare' | ||
private static final String RELEASE_TASK_NAME = 'release' | ||
|
||
void apply(Project project) { | ||
def extension = project.extensions.create('release', ReleasePluginExtension, project) | ||
addPrepareTask(project, extension) | ||
addReleaseTask(project, extension) | ||
project.plugins.withId('org.ajoberstar.grgit') { | ||
extension.grgit = project.grgit | ||
} | ||
} | ||
|
||
private void addPrepareTask(Project project, ReleasePluginExtension extension) { | ||
project.tasks.create(PREPARE_TASK_NAME) { | ||
description = 'Verifies that the project could be released.' | ||
doLast { | ||
ext.grgit = extension.grgit | ||
|
||
logger.info('Fetching changes from remote: {}', extension.remote) | ||
grgit.fetch(remote: extension.remote) | ||
|
||
// if branch is tracking another, make sure it's not behind | ||
if (grgit.branch.current.trackingBranch && grgit.branch.status(name: grgit.branch.current.fullName).behindCount > 0) { | ||
throw new GradleException('Current branch is behind the tracked branch. Cannot release.') | ||
} | ||
} | ||
} | ||
|
||
project.tasks.all { task -> | ||
if (name != PREPARE_TASK_NAME) { | ||
task.shouldRunAfter PREPARE_TASK_NAME | ||
} | ||
} | ||
} | ||
|
||
private void addReleaseTask(Project project, ReleasePluginExtension extension) { | ||
project.tasks.create(RELEASE_TASK_NAME) { | ||
description = 'Releases this project.' | ||
dependsOn PREPARE_TASK_NAME | ||
doLast { | ||
// force version inference if it hasn't happened already | ||
project.version.toString() | ||
|
||
ext.grgit = extension.grgit | ||
ext.toPush = [] | ||
|
||
// if not on detached HEAD, push branch | ||
if (grgit.branch.current.fullName != 'HEAD') { | ||
ext.toPush << grgit.branch.current.fullName | ||
} | ||
|
||
ext.tagName = extension.tagStrategy.maybeCreateTag(grgit, project.version.inferredVersion) | ||
if (tagName) { | ||
toPush << tagName | ||
} | ||
|
||
if (toPush) { | ||
logger.warn('Pushing changes in {} to {}', toPush, extension.remote) | ||
grgit.push(remote: extension.remote, refsOrSpecs: toPush) | ||
} else { | ||
logger.warn('Nothing to push.') | ||
} | ||
} | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/groovy/org/ajoberstar/gradle/git/release/base/DefaultVersionStrategy.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright 2012-2015 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.ajoberstar.gradle.git.release.base | ||
|
||
import org.ajoberstar.grgit.Grgit | ||
|
||
import org.gradle.api.Project | ||
|
||
/** | ||
* Strategy to infer a version from the project's and Git repository's state. This | ||
* also supports being selected as a default strategy. This is a temporary interface | ||
* and should be replaced in some other way in gradle-git 2.0.0. | ||
* @see org.ajoberstar.gradle.git.release.semver.SemVerStrategy | ||
* @see org.ajoberstar.gradle.git.release.opinion.Strategies | ||
*/ | ||
interface DefaultVersionStrategy extends VersionStrategy { | ||
/** | ||
* Determines if the strategy can be used as a default strategy for inferring | ||
* the project's version. A return of {@code false} does not mean that the | ||
* strategy cannot be used as the default. | ||
* @param project the project the version should be inferred for | ||
* @param grgit the repository the version should be inferred from | ||
* @return {@code true} if the strategy can be used to infer the version | ||
*/ | ||
boolean defaultSelector(Project project, Grgit grgit) | ||
} |
135 changes: 135 additions & 0 deletions
135
src/main/groovy/org/ajoberstar/gradle/git/release/base/ReleasePluginExtension.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright 2012-2015 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.ajoberstar.gradle.git.release.base | ||
|
||
import org.ajoberstar.gradle.git.release.base.ReleaseVersion | ||
import org.ajoberstar.gradle.git.release.base.TagStrategy | ||
import org.ajoberstar.gradle.git.release.base.DefaultVersionStrategy | ||
import org.ajoberstar.gradle.git.release.base.VersionStrategy | ||
import org.ajoberstar.grgit.Grgit | ||
import org.gradle.util.ConfigureUtil | ||
|
||
import org.gradle.api.GradleException | ||
import org.gradle.api.Project | ||
|
||
import org.slf4j.Logger | ||
import org.slf4j.LoggerFactory | ||
|
||
/** | ||
* Extension providing configuration options for gradle-git's release plugins. | ||
* | ||
* <p> | ||
* Sets the version to a {@link DelayedVersion} which will infer the version | ||
* when {@code toString()} is called on it. A strategy will be selected from the | ||
* ones configured on this extension and then used to infer the version. | ||
* </p> | ||
* | ||
* @see org.ajoberstar.gradle.git.release.base.BaseReleasePlugin | ||
*/ | ||
class ReleasePluginExtension { | ||
private static final Logger logger = LoggerFactory.getLogger(ReleasePluginExtension) | ||
protected final Project project | ||
private final Map<String, VersionStrategy> versionStrategies = [:] | ||
|
||
/** | ||
* The strategy to use when creating a tag for the inferred version. | ||
*/ | ||
final TagStrategy tagStrategy = new TagStrategy() | ||
|
||
/** | ||
* The strategy to use if all of the ones in {@code versionStrategies} return | ||
* false from their {@code selector()} methods. This strategy can be, but is | ||
* not required to be, one from {@code versionStrategies}. | ||
*/ | ||
VersionStrategy defaultVersionStrategy | ||
|
||
/** | ||
* The repository to infer the version from. | ||
*/ | ||
Grgit grgit | ||
|
||
/** | ||
* The remote to fetch changes from and push changes to. | ||
*/ | ||
String remote = 'origin' | ||
|
||
ReleasePluginExtension(Project project) { | ||
this.project = project | ||
def sharedVersion = new DelayedVersion() | ||
project.rootProject.allprojects { | ||
version = sharedVersion | ||
} | ||
} | ||
|
||
/** | ||
* Gets all strategies in the order they were inserted into the extension. | ||
*/ | ||
List<VersionStrategy> getVersionStrategies() { | ||
return versionStrategies.collect { key, value -> value }.asImmutable() | ||
} | ||
|
||
/** | ||
* Adds a strategy to the extension. If the strategy has the same name as | ||
* one already configured, it will replace the existing one. | ||
*/ | ||
void versionStrategy(VersionStrategy strategy) { | ||
versionStrategies[strategy.name] = strategy | ||
} | ||
|
||
/** | ||
* Configures the tag strategy with the provided closure. | ||
*/ | ||
void tagStrategy(Closure closure) { | ||
ConfigureUtil.configure(tagStrategy, closure) | ||
} | ||
|
||
// TODO: Decide if this should be thread-safe. | ||
private class DelayedVersion { | ||
ReleaseVersion inferredVersion | ||
|
||
private void infer() { | ||
VersionStrategy selectedStrategy = versionStrategies.find { strategy -> | ||
strategy.selector(project, grgit) | ||
} | ||
|
||
if (!selectedStrategy) { | ||
boolean useDefault | ||
if (defaultVersionStrategy instanceof DefaultVersionStrategy) { | ||
useDefault = defaultVersionStrategy.defaultSelector(project, grgit) | ||
} else { | ||
useDefault = defaultVersionStrategy?.selector(project, grgit) | ||
} | ||
|
||
if (useDefault) { | ||
logger.info('Falling back to default strategy: {}', defaultVersionStrategy.name) | ||
selectedStrategy = defaultVersionStrategy | ||
} else { | ||
throw new GradleException('No version strategies were selected. Run build with --info for more detail.') | ||
} | ||
} | ||
|
||
inferredVersion = selectedStrategy.infer(project, grgit) | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (!inferredVersion) { | ||
infer() | ||
} | ||
return inferredVersion.version | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/groovy/org/ajoberstar/gradle/git/release/base/ReleaseVersion.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright 2012-2015 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.ajoberstar.gradle.git.release.base | ||
|
||
import groovy.transform.Immutable | ||
|
||
/** | ||
* Represents an inferred version and any related metadata to be used after the | ||
* inference. | ||
*/ | ||
@Immutable | ||
class ReleaseVersion { | ||
/** | ||
* The version that should be used by the project. | ||
*/ | ||
String version | ||
/** | ||
* The latest version, as determined by the strategy's logic. | ||
*/ | ||
String previousVersion | ||
/** | ||
* Whether or not to create a tag for the release. | ||
*/ | ||
boolean createTag | ||
} |
Oops, something went wrong.