Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding org.ajoberstar.grgit Gradle plugin #187

Merged
merged 7 commits into from
Jul 30, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'org.ajoberstar.defaults' version '0.7.3'
id 'java-gradle-plugin'
id 'groovy'
}

Expand All @@ -14,10 +15,21 @@ repositories {

def jgitVersion = '4.8.0.201706111038-r'

sourceSets {
compatTest {
compileClasspath += main.output
runtimeClasspath += main.output
}
}

configurations.compatTestCompile.extendsFrom configurations.compile

dependencies {
// groovy
compileOnly 'org.codehaus.groovy:groovy-all:2.4.12'
testCompile 'org.codehaus.groovy:groovy-all:2.4.12'

// gradle
compileOnly gradleApi()

// jgit
compile "org.eclipse.jgit:org.eclipse.jgit:$jgitVersion"
Expand All @@ -35,7 +47,8 @@ dependencies {
testRuntime 'org.slf4j:slf4j-simple:1.7.25'

// testing
testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude group: 'org.codehaus.groovy' }
testCompile('org.spockframework:spock-core:1.1-groovy-2.4')
compatTestCompile('org.spockframework:spock-core:1.1-groovy-2.4')
}

test {
Expand All @@ -57,6 +70,10 @@ test {
}
}

stutter {
supports '3.0', '3.1', '3.2', '3.2.1', '3.3', '3.4', '3.5', '3.5.1', '4.0', '4.0.1', '4.0.2', '4.1-rc-1'
}

model {
bintray {
owner = 'ajoberstar'
Expand All @@ -65,6 +82,24 @@ model {
}
}

pluginBundle {
website = 'https://github.com/ajoberstar/grgit'
vcsUrl = 'https://github.com/ajoberstar/grgit.git'
description = 'The Groovy way to use Git'
plugins {
publishPlugin {
id = 'org.ajoberstar.grgit'
displayName = 'The Groovy way to use Git'
tags = ['git', 'groovy']
}
}
mavenCoordinates {
groupId = project.group
artifactId = project.name
version = project.version
}
}

wrapper {
gradleVersion = '3.5.1'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2012-2017 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.grgit.gradle

import spock.lang.Specification
import spock.lang.Unroll

import org.ajoberstar.grgit.Grgit
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Rule
import org.junit.rules.TemporaryFolder

class BaseCompatTest extends Specification {
@Rule TemporaryFolder tempDir = new TemporaryFolder()
File projectDir
File buildFile

def setup() {
projectDir = tempDir.newFolder('project')
buildFile = projectFile('build.gradle')

}

def 'with no repo, plugin sets grgit to null'() {
given:
buildFile << '''\
plugins {
id 'org.ajoberstar.grgit'
}

task doStuff {
doLast {
assert grgit == null
}
}
'''
when:
def result = build('doStuff')
then:
result.task(':doStuff').outcome == TaskOutcome.SUCCESS
}

def 'with repo, plugin opens the repo as grgit'() {
given:
Grgit git = Grgit.init(dir: projectDir)
projectFile('1.txt') << '1'
git.add(patterns: ['1.txt'])
git.commit(message: 'yay')
git.tag.add(name: '1.0.0')

buildFile << '''\
plugins {
id 'org.ajoberstar.grgit'
}

task doStuff {
doLast {
println grgit.describe()
}
}
'''
when:
def result = build('doStuff', '--quiet')
then:
result.task(':doStuff').outcome == TaskOutcome.SUCCESS
result.output.normalize() == '1.0.0\n'
}

def 'with repo, plugin closes the repo after build is finished'() {
given:
Grgit git = Grgit.init(dir: projectDir)
projectFile('1.txt') << '1'
git.add(patterns: ['1.txt'])
git.commit(message: 'yay')
git.tag.add(name: '1.0.0')

buildFile << '''\
plugins {
id 'org.ajoberstar.grgit'
}

task doStuff {
doLast {
println grgit.describe()
}
}
'''
when:
def result = build('doStuff', '--info')
then:
result.task(':doStuff').outcome == TaskOutcome.SUCCESS
result.output.contains('Closing Git repo')
}

private BuildResult build(String... args) {
return GradleRunner.create()
.withGradleVersion(System.properties['compat.gradle.version'])
.withPluginClasspath()
.withProjectDir(projectDir)
.forwardOutput()
.withArguments((args + '--stacktrace') as String[])
.build()
}

private File projectFile(String path) {
File file = new File(projectDir, path)
file.parentFile.mkdirs()
return file
}
}
55 changes: 55 additions & 0 deletions src/main/groovy/org/ajoberstar/grgit/gradle/GrgitPlugin.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2012-2017 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.grgit.gradle

import org.ajoberstar.grgit.Grgit
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task

/**
* Plugin adding a {@code grgit} property to all projects
* that searches for a Git repo from the project's
* directory.
* @since 2.0.0
*/
class GrgitPlugin implements Plugin<Project> {
private static final String CLOSE_TASK = 'gitClose'

@Override
void apply(Project project) {
try {
Grgit grgit = Grgit.open(currentDir: project.rootDir)

// Make sure Git repo is closed when the build is over. Ideally, this avoids issues with the daemon.
project.gradle.buildFinished {
project.logger.info "Closing Git repo: ${grgit.repository.rootDir}"
grgit.close()
}

project.allprojects { prj ->
if (prj.ext.has('grgit')) {
prj.logger.warn("Project ${prj.path} already has a grgit property. Remove org.ajoberstar.grgit from either ${prj.path} or ${project.path}.")
}
prj.ext.grgit = grgit
}
} catch (Exception e) {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAJOR The type Exception should not be caught rule

project.logger.error("No git repository found for ${project.path}. Accessing grgit will cause an NPE.")
project.logger.debug("Failed trying to find git repository for ${project.path}", e)
project.ext.grgit = null
}
}
}
7 changes: 0 additions & 7 deletions src/main/groovy/org/ajoberstar/grgit/internal/OpSyntax.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.ajoberstar.grgit.internal

import java.util.concurrent.Callable
import java.util.function.Consumer

import groovy.transform.PackageScope

Expand All @@ -36,12 +35,6 @@ class OpSyntax {
return op.call()
}

static def consumerOperation(Class<Callable> opClass, Object[] classArgs, Consumer arg) {
def op = opClass.newInstance(classArgs)
arg.accept(op)
return op.call()
}

static def closureOperation(Class<Callable> opClass, Object[] classArgs, Closure closure) {
def op = opClass.newInstance(classArgs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
Expand Down Expand Up @@ -88,7 +87,6 @@ private void makeMethods(ClassNode targetClass, ClassNode opClass, boolean isSta

targetClass.addMethod(makeNoArgMethod(targetClass, opName, opClass, opReturn, isStatic));
targetClass.addMethod(makeMapMethod(targetClass, opName, opClass, opReturn, isStatic));
targetClass.addMethod(makeConsumerMethod(targetClass, opName, opClass, opReturn, isStatic));
targetClass.addMethod(makeClosureMethod(targetClass, opName, opClass, opReturn, isStatic));
}

Expand Down Expand Up @@ -138,31 +136,6 @@ private MethodNode makeMapMethod(
return new MethodNode(opName, modifiers(isStatic), opReturn, parms, new ClassNode[] {}, code);
}

private MethodNode makeConsumerMethod(
ClassNode targetClass,
String opName,
ClassNode opClass,
ClassNode opReturn,
boolean isStatic) {
ClassNode parmType = classFromType(Consumer.class);
GenericsType[] generics = new GenericsType[] {new GenericsType(opReturn)};
parmType.setGenericsTypes(generics);
Parameter[] parms = new Parameter[] {new Parameter(parmType, "arg")};

Statement code =
new ExpressionStatement(
new StaticMethodCallExpression(
classFromType(OpSyntax.class),
"consumerOperation",
new ArgumentListExpression(
new ClassExpression(opClass),
new ArrayExpression(
classFromType(Object.class), opConstructorParms(targetClass, isStatic)),
new VariableExpression("arg"))));

return new MethodNode(opName, modifiers(isStatic), opReturn, parms, new ClassNode[] {}, code);
}

private MethodNode makeClosureMethod(
ClassNode targetClass,
String opName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=org.ajoberstar.grgit.gradle.GrgitPlugin