diff --git a/samples/.gitignore b/samples/.gitignore new file mode 100644 index 00000000..f644f2e1 --- /dev/null +++ b/samples/.gitignore @@ -0,0 +1,3 @@ +*/gradle +*/gradlew +*/gradlew.bat diff --git a/samples/git-clone/README.md b/samples/git-clone/README.md new file mode 100644 index 00000000..c8695f42 --- /dev/null +++ b/samples/git-clone/README.md @@ -0,0 +1,12 @@ + +This sample shows how `grgit` can be used to clone a repository and +interact with it. + +To run the sample, using bash, +```` + git clone http://github.com/ajoberstar/grgit grgit + cd grgit/samples/git-clone + ../../gradlew clone + ../../gradlew log + ../../gradlew clean +``` diff --git a/samples/git-clone/build.gradle b/samples/git-clone/build.gradle new file mode 100644 index 00000000..b865ba90 --- /dev/null +++ b/samples/git-clone/build.gradle @@ -0,0 +1,72 @@ + +/* + Grgit can extend a Gradle project to support direct interaction with the + git repository the Gradle project is part of, but it can also be used to + create clones and carry out operations on any repository in the local + file system. This example shows how a clone can be created and manipulated + without applying the Grgit Gradle plugin. + + The destination directory we're cloning into is the project build + directory by default, or can be set with -PdestinationDir=. + + The remote origin we're cloning from is a small test repository by default + or can be set with -Porigin=. + + Set the number of commits to print from the git commit log; this is 10 + commits by default or can be set with -PmaxCommits=. +*/ + +plugins { + // Include grgit on the class path without applying the plugin: + id 'org.ajoberstar.grgit' version '4.0.2' apply false +} + +// An explicit import is necessary because the plugin was not applied: +import org.ajoberstar.grgit.Grgit + +ext { + destinationDir = project.hasProperty('destinationDir') ? destinationDir : buildDir + origin = (project.hasProperty('origin') + ? origin + : 'https://github.com/ajoberstar/test-repo.git') + maxCommits = project.hasProperty('maxCommits') ? maxCommits : 10 +} + +// The example tasks create a clone, print the git log and destroy the clone: + +task clone { + group = 'Grgit Example' + description = 'Clones a test repository into the project build directory' + onlyIf { !new File(destinationDir, '.git').exists() } + doLast { + Grgit.clone( + dir: destinationDir, + uri: origin) + logger.lifecycle("Cloned ${origin} into ${destinationDir}") + } +} + +task log(dependsOn: clone) { + group = 'Grgit Example' + description = 'Prints the test repository commit log.' + doLast { + Grgit.open(dir: destinationDir).log(maxCommits: project.maxCommits).each { + logger.lifecycle("""commit ${it.id} +Author: ${it.author} +Date: ${it.dateTime} + + ${it.shortMessage} + +""") + } + } +} + +task clean { + group = 'Grgit Example' + description = 'Removes a previously created repository clone, if present.' + doLast { + if (destinationDir.exists()) + delete(destinationDir) + } +} diff --git a/samples/git-clone/settings.gradle b/samples/git-clone/settings.gradle new file mode 100644 index 00000000..1a5f7d32 --- /dev/null +++ b/samples/git-clone/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'grgit-git-clone' diff --git a/samples/jar-manifest/README.md b/samples/jar-manifest/README.md new file mode 100644 index 00000000..14247e9f --- /dev/null +++ b/samples/jar-manifest/README.md @@ -0,0 +1,12 @@ + +This sample shows how `grgit` can be used to interact with the +repository the Gradle scripts belong to, by applying the plugin +and using the `project.grgit` object. + +To run the sample, using bash, +```` + git clone http://github.com/ajoberstar/grgit grgit + cd grgit/samples/jar-manifest + ../../gradlew run + ../../gradlew runJar +``` diff --git a/samples/jar-manifest/build.gradle b/samples/jar-manifest/build.gradle new file mode 100644 index 00000000..944e2922 --- /dev/null +++ b/samples/jar-manifest/build.gradle @@ -0,0 +1,38 @@ + +/* + Grgit can extend a Gradle project to support direct interaction with the + git repository the Gradle project is part of. This minimal example shows + how the common use case of including repository information in jar manifests + can be implemented. + */ + +plugins { + id 'application' + // Apply the grgit plugin to create project.grgit: + id 'org.ajoberstar.grgit' version '4.0.2' +} + +version = '1.0.0' +group = 'org.ajoberstar.grgit.sample' + +application { + mainClassName = 'org.ajoberstar.grgit.samples.Main' +} + +jar { + manifest { + attributes( + 'Build-Date': new Date(), + 'Git-Branch': grgit.branch.current.fullName, + 'Git-Commit': grgit.log(maxCommits: 1).get(0).id, + 'Main-Class': application.mainClassName) + } +} + +// The run task results in an exception because no jar is generated. + +task runJar(type: JavaExec) { + group = 'Grgit Example' + description = 'Runs the sample application to print repository information.' + classpath = files(jar) +} diff --git a/samples/jar-manifest/settings.gradle b/samples/jar-manifest/settings.gradle new file mode 100644 index 00000000..1f9d3885 --- /dev/null +++ b/samples/jar-manifest/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'grgit-jar-manifest' diff --git a/samples/jar-manifest/src/main/java/org/ajoberstar/grgit/samples/Main.java b/samples/jar-manifest/src/main/java/org/ajoberstar/grgit/samples/Main.java new file mode 100644 index 00000000..54f6cb46 --- /dev/null +++ b/samples/jar-manifest/src/main/java/org/ajoberstar/grgit/samples/Main.java @@ -0,0 +1,79 @@ +package org.ajoberstar.grgit.samples; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +public class Main { + + public static void main(String[] args) throws Exception { + System.out.println( + String.format("Executing %s#main...", Main.class.getCanonicalName())); + try (InputStream stream = Manifests.openStream(Main.class)) { + Manifest manifest = new Manifest(stream); + Attributes attributes = manifest.getMainAttributes(); + String date = attributes.getValue("Build-Date"); + String branch = attributes.getValue("Git-Branch"); + String commit = attributes.getValue("Git-Commit"); + System.out.println( + String.format("Class: %s\nBuilt: %s\nBranch: %s\nCommit: %s", + Main.class.getCanonicalName(), date, branch, commit)); + } catch (UnsupportedOperationException x) { + System.out.println( + "Unable to open jar manifest to retrieve git commit and branch."); + System.out.println( + "Make sure you're running the generated jar, not from Gradle or an IDE."); + } + } +} + +class Manifests { + + /** + *

Opens an input stream for the manifest resource of the jar the + * parameter class belongs to.

+ * + *

Throws UnsupportedOperationException if the class + * does not belong to a jar.

+ * + * @param clss The class to open the jar manifest strea for + * @return A jar manifest stream for the parameter class + * @throws IOException If unable to open the stream + * @throws UnsupportedOperationException If the class is not from a jar + */ + public static InputStream openStream(Class clss) throws IOException { + String manifestPath = getResourcePath(clss); + if (null == manifestPath) + throw new UnsupportedOperationException(); + return new URL(manifestPath).openStream(); + } + + /** + * Returns the manifest resource path for the jar the parameter class + * belongs to, or null if it is not part of a jar. + * + * @param clss The class to locate a jar manifest for + * @return The manifest resource path for the parameter class + */ + public static String getResourcePath(Class clss) { + String resourcePath = Classes.getResourcePath(clss); + if (!resourcePath.startsWith("jar")) + return null; + int offset = resourcePath.lastIndexOf("!") + 1; + return resourcePath.substring(0, offset) + "/META-INF/MANIFEST.MF"; + } +} + +class Classes { + + public static String getResourcePath(Class clss) { + return clss.getResource(getResourceName(clss)).toString(); + } + + public static String getResourceName(Class clss) { + return clss.getSimpleName() + ".class"; + } +} +