From d1a3a842fc00d5e443f01f537b41302e09c73a7a Mon Sep 17 00:00:00 2001 From: Dave Fennell Date: Fri, 22 Feb 2013 15:02:47 +0000 Subject: [PATCH] Added injectAllReactorProjects flag to turn off property injection and corrected .git directory searching to work with git submodules. --- .../project13/maven/git/GitCommitIdMojo.java | 93 ++++++----- .../pl/project13/maven/git/GitDirLocator.java | 152 +++++++++++++++--- 2 files changed, 182 insertions(+), 63 deletions(-) diff --git a/src/main/java/pl/project13/maven/git/GitCommitIdMojo.java b/src/main/java/pl/project13/maven/git/GitCommitIdMojo.java index 9714c7d6..97a37b73 100644 --- a/src/main/java/pl/project13/maven/git/GitCommitIdMojo.java +++ b/src/main/java/pl/project13/maven/git/GitCommitIdMojo.java @@ -92,8 +92,17 @@ public class GitCommitIdMojo extends AbstractMojo { * @parameter expression="${reactorProjects}" * @readonly */ - private List reactorProjects; + private List reactorProjects; + /** + * Tell git-commit-id to inject the git properties into all + * reactor projects not just the current one. + * + * @parameter default-value="true" + */ + @SuppressWarnings("UnusedDeclaration") + private boolean injectAllReactorProjects; + /** * Specifies whether the goal runs in verbose mode. * To be more specific, this means more info being printed out while scanning for paths and also @@ -215,38 +224,46 @@ public class GitCommitIdMojo extends AbstractMojo { boolean runningTests = false; @NotNull - LoggerBridge loggerBridge = new MavenLoggerBridge(getLog(), verbose); + LoggerBridge loggerBridge = new MavenLoggerBridge(getLog(), true); + + @NotNull + LoggerBridge verboseLoggerBridge = new MavenLoggerBridge(getLog(), true); public void execute() throws MojoExecutionException { + // Set the verbose setting now it should be correctly loaded from maven. + loggerBridge.setVerbose(verbose); + alwaysLog("Verbose Setting: " + Boolean.valueOf(verbose)); + if (isPomProject(project) && skipPoms) { - log("Skipping the execution as it is a project with packaging type: 'pom'"); + alwaysLog("Skipping the execution as it is a project with packaging type: 'pom'"); return; } dotGitDirectory = lookupGitDirectory(); throwWhenRequiredDirectoryNotFound(dotGitDirectory, failOnNoGitDirectory, ".git directory could not be found! Please specify a valid [dotGitDirectory] in your pom.xml"); - if(dotGitDirectory != null) { - log("Running on '%s' repository...", dotGitDirectory.getAbsolutePath()); + if (dotGitDirectory != null) { + alwaysLog("Running on '%s' repository...", dotGitDirectory.getAbsolutePath()); } else { - log(".git directory could not be found, skipping execution"); + alwaysLog(".git directory could not be found, skipping execution"); return; } try { properties = initProperties(); prefixDot = prefix + "."; - + loadGitData(properties); loadBuildTimeData(properties); - logProperties(properties); if (generateGitPropertiesFile) { generatePropertiesFile(properties, generateGitPropertiesFilename); } - appendPropertiesToMaven(properties); + if (injectAllReactorProjects) { + appendPropertiesToReactorProjects(properties); + } } catch (IOException e) { throw new MojoExecutionException("Could not complete Mojo execution...", e); } @@ -254,28 +271,23 @@ public void execute() throws MojoExecutionException { log("Finished running."); } - private void appendPropertiesToMaven(@NotNull Properties properies) { - log("Appending to Maven properties"); + private void appendPropertiesToReactorProjects(@NotNull Properties properies) { + log("Appending git properties to all reactor projects:"); - if (project != null) { - if (reactorProjects != null) { - Iterator projIter = reactorProjects.iterator(); - - while (projIter.hasNext()) { - MavenProject nextProj = (MavenProject) projIter.next(); - Properties mavenProperties = nextProj.getProperties(); - - log("Injecting Git properties to \"%s\" project", nextProj.getName()); - - for (Object key : properties.keySet()) { - mavenProperties.put(key, properties.get(key)); - } + if (reactorProjects != null) { + for (MavenProject mavenProject : reactorProjects) { + Properties mavenProperties = mavenProject.getProperties(); + + log("Injecting Git properties to \"%s\" project", mavenProject.getName()); + + for (Object key : properties.keySet()) { + mavenProperties.put(key, properties.get(key)); } } } } -private void throwWhenRequiredDirectoryNotFound(File dotGitDirectory, Boolean required, String message) throws MojoExecutionException { + private void throwWhenRequiredDirectoryNotFound(File dotGitDirectory, Boolean required, String message) throws MojoExecutionException { if (required && directoryDoesNotExits(dotGitDirectory)) { throw new MojoExecutionException(message); } @@ -288,12 +300,7 @@ private void throwWhenRequiredDirectoryNotFound(File dotGitDirectory, Boolean re * @return the File representation of the .git directory */ private File lookupGitDirectory() throws MojoExecutionException { - return getGitDirLocator().lookupGitDirectory(project, dotGitDirectory); - } - - @NotNull - GitDirLocator getGitDirLocator() { - return new GitDirLocator(); + return new GitDirLocator(project, reactorProjects).lookupGitDirectory(dotGitDirectory); } private Properties initProperties() throws MojoExecutionException { @@ -310,15 +317,15 @@ private Properties initProperties() throws MojoExecutionException { } private void logProperties(@NotNull Properties properties) { - log("------------------git properties loaded------------------"); + alwaysLog("------------------git properties loaded------------------"); for (Object key : properties.keySet()) { String keyString = key.toString(); if (isOurProperty(keyString)) { - log(String.format("%s = %s", key, properties.getProperty(keyString))); + alwaysLog(String.format("%s = %s", key, properties.getProperty(keyString))); } } - log("---------------------------------------------------------"); + alwaysLog("---------------------------------------------------------"); } private boolean isOurProperty(@NotNull String keyString) { @@ -481,16 +488,12 @@ private void put(@NotNull Properties properties, String key, String value) { } private void putWithoutPrefix(@NotNull Properties properties, String key, String value) { - if (verbose) { - String s = String.format("Storing: %s = %s", key, value); - log(s); + if (!isNotEmpty(value)) { + value = "Unknown"; } - if (isNotEmpty(value)) { - properties.put(key, value); - } else { - properties.put(key, "Unknown"); - } + log("Storing: %s = %s", key, value); + properties.put(key, value); } private boolean isNotEmpty(@Nullable String value) { @@ -498,7 +501,11 @@ private boolean isNotEmpty(@Nullable String value) { } void log(String message, String... interpolations) { - loggerBridge.log(logPrefix + message, interpolations); + loggerBridge.log(logPrefix + message, (Object[]) interpolations); + } + + void alwaysLog(String message, String... interpolations) { + verboseLoggerBridge.log(logPrefix + message, (Object[]) interpolations); } private boolean directoryExists(@Nullable File fileLocation) { diff --git a/src/main/java/pl/project13/maven/git/GitDirLocator.java b/src/main/java/pl/project13/maven/git/GitDirLocator.java index c6bc7c9e..c1be44c1 100644 --- a/src/main/java/pl/project13/maven/git/GitDirLocator.java +++ b/src/main/java/pl/project13/maven/git/GitDirLocator.java @@ -17,56 +17,168 @@ package pl.project13.maven.git; -import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.artifact.Artifact; import org.apache.maven.project.MavenProject; import org.eclipse.jgit.lib.Constants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.List; /** * Encapsulates logic to locate a valid .git directory * @author Konrad 'ktoso' Malawski */ public class GitDirLocator { - + final MavenProject mavenProject; + final List reactorProjects; + + public GitDirLocator(MavenProject mavenProject, List reactorProjects){ + this.mavenProject = mavenProject; + this.reactorProjects = reactorProjects; + } + @Nullable - public File lookupGitDirectory(MavenProject project, File manualyConfiguredDir) throws MojoExecutionException { + public File lookupGitDirectory(File manuallyConfiguredDir) { - if (isExistingDirectory(manualyConfiguredDir)) { - return manualyConfiguredDir; + if (manuallyConfiguredDir != null && manuallyConfiguredDir.exists()) { + + // If manuallyConfiguredDir is a directory then we can use it as the git path. + if (manuallyConfiguredDir.isDirectory()) { + return manuallyConfiguredDir; + } + + // If the path exists but is not a directory it might be a git submodule "gitdir" link. + File gitDirLinkPath = processGitDirFile(manuallyConfiguredDir); + + // If the linkPath was found from the file and it exists then use it. + if (isExistingDirectory(gitDirLinkPath)) + { + return gitDirLinkPath; + } + + /** + * FIXME: I think we should fail here because a manual path was set and it was not found + * but I'm leaving it falling back to searching for the git path because that is the current + * behaviour - Unluckypixie. + */ } - MavenProject mavenProject = project; + return findProjectGitDirectory(); + } - File dir; - while (mavenProject != null) { - dir = currentProjectGitDir(mavenProject); + /** + * Search up all the maven parent project heirarchy until a .git + * directory is found. + * + * @return File the location of the .git directory or NULL if none found. + */ + private File findProjectGitDirectory() + { + MavenProject project = this.mavenProject; + + while (project != null) { + File dir = getProjectGitDir(project); + if (isExistingDirectory(dir)) { return dir; } - if (mavenProject.getBasedir() != null) { - dir = new File(mavenProject.getBasedir().getParentFile(), Constants.DOT_GIT); - if (isExistingDirectory(dir)) { - return dir; - } + /** + * project.getParent always returns NULL for me, but if getParentArtifact returns + * not null then there is actually a parent - seems like a bug in maven to me. + */ + if (project.getParent() == null && project.getParentArtifact() != null) { + project = getReactorParentProject(project); + } else { + // Get the parent, or NULL if no parent AND no parentArtifact. + project = project.getParent(); } + } - mavenProject = mavenProject.getParent(); + return null; + } + + /** + * Find a project in the reactor by its artifact, I'm new to maven coding + * so there may be a better way to do this, it would not be necessary + * if project.getParent() actually worked. + * + * @param MavenProject project + * @return MavenProject parent project or NULL if no parent available + */ + private MavenProject getReactorParentProject(MavenProject project) { + Artifact parentArtifact = project.getParentArtifact(); + + if (parentArtifact != null) { + for (MavenProject reactorProject : this.reactorProjects) { + if (reactorProject.getArtifactId().equals(parentArtifact.getArtifactId())){ + return reactorProject; + } + } } + return null; } + + /** + * Load a ".git" git submodule file and read the gitdir path from it. + * + * @param file + * @return File object with path loaded or null + */ + private File processGitDirFile(@NotNull File file) { + try { + BufferedReader reader = null; + + try { + reader = new BufferedReader(new FileReader(file)); + // There should be just one line in the file, e.g. + // "gitdir: /usr/local/src/parentproject/.git/modules/submodule" + String line = reader.readLine(); + + // Separate the key and the value in the string. + String[] parts = line.split(": "); + + // If we don't have 2 parts or if the key is not gitdir then give up. + if (parts.length != 2 || !parts[0].equals("gitdir")) { + return null; + } + + // All seems ok so return the "gitdir" value read from the file. + return new File(parts[1]); + } + catch (FileNotFoundException e) + { + return null; + } + finally + { + if (reader != null) + { + reader.close(); + } + } + } + catch (IOException e) + { + return null; + } + } + @NotNull - private File currentProjectGitDir(@NotNull MavenProject mavenProject) { + private File getProjectGitDir(@NotNull MavenProject mavenProject) { + // FIXME Shouldn't this look at the dotGitDirectory property (if set) for the given project? return new File(mavenProject.getBasedir(), Constants.DOT_GIT); } - public static boolean isExistingDirectory(@Nullable File fileLocation) { + public boolean isExistingDirectory(@Nullable File fileLocation) { return fileLocation != null && fileLocation.exists() && fileLocation.isDirectory(); } - - -} \ No newline at end of file +}