Skip to content

Commit

Permalink
feat: update to Grgit 2
Browse files Browse the repository at this point in the history
Closes tschulte#30

BREAKING CHANGE:
  • Loading branch information
grv87 committed Jun 7, 2018
1 parent a63734f commit 10de2a0
Show file tree
Hide file tree
Showing 28 changed files with 2,931 additions and 3 deletions.
5 changes: 3 additions & 2 deletions compile-dependencies.gradle
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'
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SemanticReleasePlugin implements Plugin<Project> {

void apply(Project project) {
project.with {
plugins.apply(org.ajoberstar.gradle.git.base.GrgitPlugin)
plugins.apply(org.ajoberstar.grgit.gradle.GrgitPlugin)
plugins.apply(org.ajoberstar.gradle.git.release.base.BaseReleasePlugin)
SemanticReleasePluginExtension semanticReleaseExtension = extensions.create("semanticRelease", SemanticReleasePluginExtension, project)
ReleasePluginExtension releaseExtension = extensions.findByType(ReleasePluginExtension)
Expand Down
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.')
}
}
}
}
}
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)
}
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
}
}
}
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
}
Loading

0 comments on commit 10de2a0

Please sign in to comment.