Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!--- Please follow the instructions below -->

<!--- Provide a brief summary of the issue in the title above -->

### Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->

### Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->



<!-- The following needs to be completed as best as possible **for bugs only** -->
### Steps to Reproduce (for bugs only)
<!-- If describing a bug, please include the **full** configuration of the plugin -->
<!-- If describing a bug, is there a (public) project where this issue can be reproduced? -->
<!-- If describing a bug, please include any stack-traces or any error messages -->

### Environment (for bugs only)
<!-- If describing a bug, please provide the plugin version is being used -->
<!-- If describing a bug, please provide the Java-Version is being used (please include details about oracle-jdk VS open-jdk) -->
<!-- If describing a bug, please provide the Maven-Version is being used (output of ``mvn --version``) -->
<!-- If describing a bug, please let us know on what Operating System you experience the bug (on Linux run ``lsb_release -a``) -->
<!-- If describing a bug, please let us know in what context maven is being executed (e.g. inside Windows Terminal, Powershell, Git Bash, /bin/bash, ...) -->
<!-- If describing a bug, please let us know how maven is being executed (e.g. ``mvn clean deploy`` VS ``mvn deploy:deploy``) -->
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ matrix:
env: CUSTOM_MVN_VERION="3.3.9"
- jdk: oraclejdk9
env: CUSTOM_MVN_VERION="3.5.0"
- jdk: oraclejdk9
env: CUSTOM_MVN_VERION="3.5.2"
- stage: checkstyle
jdk: oraclejdk9
script: mvn clean verify -Pcheckstyle -Dcheckstyle.version=8.2 -Dmaven.test.skip=true -B
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ It's really simple to setup this plugin; below is a sample pom that you may base
-->
<forceLongFormat>false</forceLongFormat>
</gitDescribe>

<!-- @since 2.2.2 -->
<!--
Since version **2.2.2** the maven-git-commit-id-plugin comes equipped with an additional validation utility which can be used to verify if your project properties are set as you would like to have them set.
Expand All @@ -495,13 +496,29 @@ It's really simple to setup this plugin; below is a sample pom that you may base
</validationProperty>
<!-- the next validationProperty you would like to validate -->
</validationProperties>

<!-- @since 2.2.2 -->
<!--
true by default, controls whether the validation will fail if *at least one* of the validationProperties does not match with it's expected values.
If you don't care about this, you may want to set this value to false (this makes the configuration of validationProperties useless).
*Note*: This configuration will only be taken into account when the additional goal `validateRevision` is configured inside an execution and at least one validationProperty is defined.
-->
<validationShouldFailIfNoMatch>true</validationShouldFailIfNoMatch>

<!-- @since 2.2.4 -->
<!--
Allow to tell the plugin what commit should be used as reference to generate the properties from.
By default this property is simply set to `HEAD` which should reference to the latest commit in your repository.

In general this property can be set to something generic like `HEAD^1` or point to a branch or tag-name.
To support any kind or use-case this configuration can also be set to an entire commit-hash or it's abbreviated version.

A use-case for this feature can be found in https://github.com/ktoso/maven-git-commit-id-plugin/issues/338.

Please note that for security purposes not all references might be allowed as configuration.
If you have a specific use-case that is currently not white listed feel free to file an issue.
-->
<evaluateOnCommit>HEAD</evaluateOnCommit>
</configuration>

</plugin>
Expand Down Expand Up @@ -882,6 +899,7 @@ Optional parameters:

*Note*: Depending on your plugin configuration you obviously can choose the 'prefix' of your properties by setting it accordingly in the plugin's configuration. As a result this is therefore only an illustration what the switch means when the 'prefix' is set to it's default value.
*Note*: If you set the value to something that's not equal to 'flat' or 'full' (ignoring the case) the plugin will output a warning and will fallback to the default 'flat' mode.
* **evaluateOnCommit** - `(default: HEAD)` *(available since v2.2.4)* Allow to tell the plugin what commit should be used as reference to generate the properties from. By default this property is simply set to `HEAD` which should reference to the latest commit in your repository. In general this property can be set to something generic like `HEAD^1` or point to a branch or tag-name. To support any kind or use-case this configuration can also be set to an entire commit-hash or it's abbreviated version. Please note that for security purposes not all references might be allowed as configuration. If you have a specific use-case that is currently not white listed feel free to file an issue.

**gitDescribe**:
Worth pointing out is, that git-commit-id tries to be 1-to-1 compatible with git's plain output, even though the describe functionality has been reimplemented manually using JGit (you don't have to have a git executable to use the plugin). So if you're familiar with [git-describe](https://github.com/ktoso/maven-git-commit-id-plugin#git-describe---short-intro-to-an-awesome-command), you probably can skip this section, as it just explains the same options that git provides.
Expand Down
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
<version>1.16.0</version>
<scope>test</scope>
</dependency>

<!--to avoid complaints during tests-->
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
32 changes: 15 additions & 17 deletions src/main/java/pl/project13/jgit/DescribeCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,12 @@
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import pl.project13.jgit.dummy.DatedRevTag;
import pl.project13.maven.git.GitDescribeConfig;
import pl.project13.maven.git.log.LoggerBridge;
import pl.project13.maven.git.util.Pair;

import java.io.IOException;
import java.util.*;

/**
Expand All @@ -46,6 +42,7 @@ public class DescribeCommand extends GitCommand<DescribeResult> {

private LoggerBridge log;
private JGitCommon jGitCommon;
private String evaluateOnCommit;

// TODO not yet implemented options:
// private boolean containsFlag = false;
Expand Down Expand Up @@ -86,17 +83,18 @@ public class DescribeCommand extends GitCommand<DescribeResult> {
* @param log logger bridge to direct logs to
*/
@NotNull
public static DescribeCommand on(Repository repo, LoggerBridge log) {
return new DescribeCommand(repo, log);
public static DescribeCommand on(String evaluateOnCommit, Repository repo, LoggerBridge log) {
return new DescribeCommand(evaluateOnCommit, repo, log);
}

/**
* Creates a new describe command which interacts with a single repository
*
* @param repo the {@link org.eclipse.jgit.lib.Repository} this command should interact with
*/
private DescribeCommand(Repository repo, @NotNull LoggerBridge log) {
private DescribeCommand(@NotNull String evaluateOnCommit, @NotNull Repository repo, @NotNull LoggerBridge log) {
super(repo);
this.evaluateOnCommit = evaluateOnCommit;
this.jGitCommon = new JGitCommon(log);
this.log = log;
}
Expand Down Expand Up @@ -259,14 +257,14 @@ public DescribeResult call() throws GitAPIException {
Map<ObjectId, List<String>> tagObjectIdToName = jGitCommon.findTagObjectIds(repo, tagsFlag, matchPattern);

// get current commit
RevCommit headCommit = findHeadObjectId(repo);
ObjectId headCommitId = headCommit.getId();
RevCommit evalCommit = findEvalCommitObjectId(evaluateOnCommit, repo);
ObjectId evalCommitId = evalCommit.getId();

// check if dirty
boolean dirty = findDirtyState(repo);

if (hasTags(headCommit, tagObjectIdToName) && !forceLongFormat) {
String tagName = tagObjectIdToName.get(headCommit).iterator().next();
if (hasTags(evalCommit, tagObjectIdToName) && !forceLongFormat) {
String tagName = tagObjectIdToName.get(evalCommit).iterator().next();
log.info("The commit we're on is a Tag ([{}]) and forceLongFormat == false, returning.", tagName);

return new DescribeResult(tagName, dirty, dirtyOption);
Expand All @@ -275,7 +273,7 @@ public DescribeResult call() throws GitAPIException {
// get commits, up until the nearest tag
List<RevCommit> commits;
try {
commits = jGitCommon.findCommitsUntilSomeTag(repo, headCommit, tagObjectIdToName);
commits = jGitCommon.findCommitsUntilSomeTag(repo, evalCommit, tagObjectIdToName);
} catch (Exception e) {
if (alwaysFlag) {
// Show uniquely abbreviated commit object as fallback
Expand All @@ -287,18 +285,18 @@ public DescribeResult call() throws GitAPIException {

// if there is no tags or any tag is not on that branch then return generic describe
if (foundZeroTags(tagObjectIdToName) || commits.isEmpty()) {
return new DescribeResult(objectReader, headCommitId, dirty, dirtyOption)
return new DescribeResult(objectReader, evalCommitId, dirty, dirtyOption)
.withCommitIdAbbrev(abbrev);
}

// check how far away from a tag we are

int distance = jGitCommon.distanceBetween(repo, headCommit, commits.get(0));
int distance = jGitCommon.distanceBetween(repo, evalCommit, commits.get(0));
String tagName = tagObjectIdToName.get(commits.get(0)).iterator().next();
Pair<Integer, String> howFarFromWhichTag = Pair.of(distance, tagName);

// if it's null, no tag's were found etc, so let's return just the commit-id
return createDescribeResult(objectReader, headCommitId, dirty, howFarFromWhichTag);
return createDescribeResult(objectReader, evalCommitId, dirty, howFarFromWhichTag);
}

/**
Expand Down Expand Up @@ -344,8 +342,8 @@ static boolean hasTags(ObjectId headCommit, @NotNull Map<ObjectId, List<String>>
return tagObjectIdToName.containsKey(headCommit);
}

RevCommit findHeadObjectId(@NotNull Repository repo) throws RuntimeException {
return jGitCommon.findHeadObjectId(repo);
RevCommit findEvalCommitObjectId(@NotNull String evaluateOnCommit, @NotNull Repository repo) throws RuntimeException {
return jGitCommon.findEvalCommitObjectId(evaluateOnCommit, repo);
}

private String createMatchPattern() {
Expand Down
43 changes: 23 additions & 20 deletions src/main/java/pl/project13/jgit/JGitCommon.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
Expand Down Expand Up @@ -53,27 +52,31 @@ public JGitCommon(LoggerBridge log) {
this.log = log;
}

public Collection<String> getTags(Repository repo, final ObjectId headId) throws GitAPIException {
public Collection<String> getTags(Repository repo, final ObjectId objectId) throws GitAPIException {
try (Git git = Git.wrap(repo)) {
try (RevWalk walk = new RevWalk(repo)) {
Collection<String> tags = getTags(git, headId, walk);
Collection<String> tags = getTags(git, objectId, walk);
walk.dispose();
return tags;
}
}
}

private Collection<String> getTags(final Git git, final ObjectId headId, final RevWalk finalWalk) throws GitAPIException {
private Collection<String> getTags(final Git git, final ObjectId objectId, final RevWalk finalWalk) throws GitAPIException {
List<Ref> tagRefs = git.tagList().call();
Collection<Ref> tagsForHeadCommit = Collections2.filter(tagRefs, new Predicate<Ref>() {
@Override public boolean apply(Ref tagRef) {
boolean lightweightTag = tagRef.getObjectId().equals(headId);
@Override
public boolean apply(Ref tagRef) {
try {
// TODO make this configurable (most users shouldn't really care too much what kind of tag it is though)
return lightweightTag || finalWalk.parseTag(tagRef.getObjectId()).getObject().getId().equals(headId); // or normal tag
} catch (IOException e) {
return false;
final RevCommit tagCommit = finalWalk.parseCommit(tagRef.getObjectId());
final RevCommit objectCommit = finalWalk.parseCommit(objectId);
if (finalWalk.isMergedInto(objectCommit, tagCommit)) {
return true;
}
} catch (Exception ignored) {
log.debug("Failed while getTags [{}] -- ", tagRef, ignored);
}
return false;
}
});
Collection<String> tags = Collections2.transform(tagsForHeadCommit, new Function<Ref, String>() {
Expand All @@ -84,16 +87,16 @@ private Collection<String> getTags(final Git git, final ObjectId headId, final R
return tags;
}

public String getClosestTagName(@NotNull Repository repo, GitDescribeConfig gitDescribe) {
public String getClosestTagName(@NotNull String evaluateOnCommit, @NotNull Repository repo, GitDescribeConfig gitDescribe) {
// TODO: Why does some tests fail when it gets headCommit from JGitprovider?
RevCommit headCommit = findHeadObjectId(repo);
RevCommit headCommit = findEvalCommitObjectId(evaluateOnCommit, repo);
Pair<RevCommit, String> pair = getClosestRevCommit(repo, headCommit, gitDescribe);
return pair.second;
}

public String getClosestTagCommitCount(@NotNull Repository repo, GitDescribeConfig gitDescribe) {
public String getClosestTagCommitCount(@NotNull String evaluateOnCommit, @NotNull Repository repo, GitDescribeConfig gitDescribe) {
// TODO: Why does some tests fail when it gets headCommit from JGitprovider?
RevCommit headCommit = findHeadObjectId(repo);
RevCommit headCommit = findEvalCommitObjectId(evaluateOnCommit, repo);
Pair<RevCommit, String> pair = getClosestRevCommit(repo, headCommit, gitDescribe);
RevCommit revCommit = pair.first;
int distance = distanceBetween(repo, headCommit, revCommit);
Expand Down Expand Up @@ -135,19 +138,19 @@ protected Map<ObjectId, List<String>> findTagObjectIds(@NotNull Repository repo,
return commitIdsToTagNames;
}

protected RevCommit findHeadObjectId(@NotNull Repository repo) throws RuntimeException {
protected RevCommit findEvalCommitObjectId(@NotNull String evaluateOnCommit, @NotNull Repository repo) throws RuntimeException {
try {
ObjectId headId = repo.resolve(Constants.HEAD);
ObjectId evalCommitId = repo.resolve(evaluateOnCommit);

try (RevWalk walk = new RevWalk(repo)) {
RevCommit headCommit = walk.lookupCommit(headId);
RevCommit evalCommit = walk.parseCommit(evalCommitId);
walk.dispose();

log.info("HEAD is [{}]", headCommit.getName());
return headCommit;
log.info("evalCommit is [{}]", evalCommit.getName());
return evalCommit;
}
} catch (IOException ex) {
throw new RuntimeException("Unable to obtain HEAD commit!", ex);
throw new RuntimeException("Unable to obtain " + evaluateOnCommit + " commit!", ex);
}
}

Expand Down
35 changes: 33 additions & 2 deletions src/main/java/pl/project13/maven/git/GitCommitIdMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
import java.util.regex.Pattern;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
Expand Down Expand Up @@ -304,6 +305,23 @@ public class GitCommitIdMojo extends AbstractMojo {
@Parameter
@VisibleForTesting List<ReplacementProperty> replacementProperties;

/**
* Allow to tell the plugin what commit should be used as reference to generate the properties from.
* By default this property is simply set to <p>HEAD</p> which should reference to the latest commit in your repository.
*
* In general this property can be set to something generic like <p>HEAD^1</p> or point to a branch or tag-name.
* To support any kind or use-case this configuration can also be set to an entire commit-hash or it's abbreviated version.
*
* A use-case for this feature can be found in https://github.com/ktoso/maven-git-commit-id-plugin/issues/338.
*
* Please note that for security purposes not all references might be allowed as configuration.
* If you have a specific use-case that is currently not white listed feel free to file an issue.
* @since 2.2.4
*/
@Parameter(defaultValue = "HEAD")
private String evaluateOnCommit;
protected static final Pattern allowedCharactersForEvaluateOnCommit = Pattern.compile("[a-zA-Z0-9\\_\\-\\^\\/\\.]+");

/**
* The properties we store our data in and then expose them.
*/
Expand Down Expand Up @@ -369,6 +387,11 @@ public void execute() throws MojoExecutionException {
return;
}

if ((evaluateOnCommit == null) || !allowedCharactersForEvaluateOnCommit.matcher(evaluateOnCommit).matches()) {
log.error("suspicious argument for evaluateOnCommit, aborting execution!");
return;
}

try {
try {
commitIdGenerationModeEnum = CommitIdGenerationMode.valueOf(commitIdGenerationMode.toUpperCase());
Expand Down Expand Up @@ -515,7 +538,7 @@ void loadGitDataWithNativeGit(@NotNull Properties properties) throws GitCommitId
.setGitDescribe(gitDescribe)
.setCommitIdGenerationMode(commitIdGenerationModeEnum);

nativeGitProvider.loadGitData(properties);
nativeGitProvider.loadGitData(evaluateOnCommit, properties);
} catch (IOException e) {
throw new GitCommitIdExecutionException(e);
}
Expand All @@ -531,7 +554,7 @@ void loadGitDataWithJGit(@NotNull Properties properties) throws GitCommitIdExecu
.setGitDescribe(gitDescribe)
.setCommitIdGenerationMode(commitIdGenerationModeEnum);

jGitProvider.loadGitData(properties);
jGitProvider.loadGitData(evaluateOnCommit, properties);
}

void maybeGeneratePropertiesFile(@NotNull Properties localProperties, File base, String propertiesFilename) throws GitCommitIdExecutionException {
Expand Down Expand Up @@ -787,4 +810,12 @@ static class CannotReadFileException extends Exception {
@VisibleForTesting void setFailOnUnableToExtractRepoInfo(boolean failOnUnableToExtractRepoInfo) {
this.failOnUnableToExtractRepoInfo = failOnUnableToExtractRepoInfo;
}

@VisibleForTesting String getEvaluateOnCommit() {
return evaluateOnCommit;
}

@VisibleForTesting void setEvaluateOnCommit(String evaluateOnCommit) {
this.evaluateOnCommit = evaluateOnCommit;
}
}
5 changes: 4 additions & 1 deletion src/main/java/pl/project13/maven/git/GitDataProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public abstract class GitDataProvider implements GitProvider {

protected CommitIdGenerationMode commitIdGenerationMode;

protected String evaluateOnCommit;

public GitDataProvider(@NotNull LoggerBridge log) {
this.log = log;
}
Expand Down Expand Up @@ -83,7 +85,8 @@ public GitDataProvider setDateFormatTimeZone(String dateFormatTimeZone) {
return this;
}

public void loadGitData(@NotNull Properties properties) throws GitCommitIdExecutionException {
public void loadGitData(@NotNull String evaluateOnCommit, @NotNull Properties properties) throws GitCommitIdExecutionException {
this.evaluateOnCommit = evaluateOnCommit;
init();
// git.user.name
put(properties, GitCommitPropertyConstant.BUILD_AUTHOR_NAME, getBuildAuthorName());
Expand Down
Loading