Skip to content

Commit a68346d

Browse files
author
TheSnoozer
authored
Merge pull request #340 from TheSnoozer/master
Adressing #337, #338, #339 and other minor improvements
2 parents 88378e0 + 0cb6a71 commit a68346d

18 files changed

+760
-394
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!--- Please follow the instructions below -->
2+
3+
<!--- Provide a brief summary of the issue in the title above -->
4+
5+
### Expected Behavior
6+
<!--- If you're describing a bug, tell us what should happen -->
7+
<!--- If you're suggesting a change/improvement, tell us how it should work -->
8+
9+
### Current Behavior
10+
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
11+
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
12+
13+
14+
15+
<!-- The following needs to be completed as best as possible **for bugs only** -->
16+
### Steps to Reproduce (for bugs only)
17+
<!-- If describing a bug, please include the **full** configuration of the plugin -->
18+
<!-- If describing a bug, is there a (public) project where this issue can be reproduced? -->
19+
<!-- If describing a bug, please include any stack-traces or any error messages -->
20+
21+
### Environment (for bugs only)
22+
<!-- If describing a bug, please provide the plugin version is being used -->
23+
<!-- If describing a bug, please provide the Java-Version is being used (please include details about oracle-jdk VS open-jdk) -->
24+
<!-- If describing a bug, please provide the Maven-Version is being used (output of ``mvn --version``) -->
25+
<!-- If describing a bug, please let us know on what Operating System you experience the bug (on Linux run ``lsb_release -a``) -->
26+
<!-- 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, ...) -->
27+
<!-- If describing a bug, please let us know how maven is being executed (e.g. ``mvn clean deploy`` VS ``mvn deploy:deploy``) -->

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ matrix:
2727
env: CUSTOM_MVN_VERION="3.3.9"
2828
- jdk: oraclejdk9
2929
env: CUSTOM_MVN_VERION="3.5.0"
30+
- jdk: oraclejdk9
31+
env: CUSTOM_MVN_VERION="3.5.2"
3032
- stage: checkstyle
3133
jdk: oraclejdk9
3234
script: mvn clean verify -Pcheckstyle -Dcheckstyle.version=8.2 -Dmaven.test.skip=true -B

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ It's really simple to setup this plugin; below is a sample pom that you may base
472472
-->
473473
<forceLongFormat>false</forceLongFormat>
474474
</gitDescribe>
475+
475476
<!-- @since 2.2.2 -->
476477
<!--
477478
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.
@@ -495,13 +496,29 @@ It's really simple to setup this plugin; below is a sample pom that you may base
495496
</validationProperty>
496497
<!-- the next validationProperty you would like to validate -->
497498
</validationProperties>
499+
498500
<!-- @since 2.2.2 -->
499501
<!--
500502
true by default, controls whether the validation will fail if *at least one* of the validationProperties does not match with it's expected values.
501503
If you don't care about this, you may want to set this value to false (this makes the configuration of validationProperties useless).
502504
*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.
503505
-->
504506
<validationShouldFailIfNoMatch>true</validationShouldFailIfNoMatch>
507+
508+
<!-- @since 2.2.4 -->
509+
<!--
510+
Allow to tell the plugin what commit should be used as reference to generate the properties from.
511+
By default this property is simply set to `HEAD` which should reference to the latest commit in your repository.
512+
513+
In general this property can be set to something generic like `HEAD^1` or point to a branch or tag-name.
514+
To support any kind or use-case this configuration can also be set to an entire commit-hash or it's abbreviated version.
515+
516+
A use-case for this feature can be found in https://github.com/ktoso/maven-git-commit-id-plugin/issues/338.
517+
518+
Please note that for security purposes not all references might be allowed as configuration.
519+
If you have a specific use-case that is currently not white listed feel free to file an issue.
520+
-->
521+
<evaluateOnCommit>HEAD</evaluateOnCommit>
505522
</configuration>
506523

507524
</plugin>
@@ -882,6 +899,7 @@ Optional parameters:
882899

883900
*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.
884901
*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.
902+
* **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.
885903

886904
**gitDescribe**:
887905
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.

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@
163163
<scope>test</scope>
164164
</dependency>
165165

166+
<dependency>
167+
<groupId>com.github.stefanbirkner</groupId>
168+
<artifactId>system-rules</artifactId>
169+
<version>1.16.0</version>
170+
<scope>test</scope>
171+
</dependency>
172+
166173
<!--to avoid complaints during tests-->
167174
<dependency>
168175
<groupId>org.slf4j</groupId>

src/main/java/pl/project13/jgit/DescribeCommand.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,12 @@
2727
import org.eclipse.jgit.lib.ObjectReader;
2828
import org.eclipse.jgit.lib.Repository;
2929
import org.eclipse.jgit.revwalk.RevCommit;
30-
import org.eclipse.jgit.revwalk.RevWalk;
3130
import org.jetbrains.annotations.NotNull;
3231
import org.jetbrains.annotations.Nullable;
3332

34-
import pl.project13.jgit.dummy.DatedRevTag;
3533
import pl.project13.maven.git.GitDescribeConfig;
3634
import pl.project13.maven.git.log.LoggerBridge;
3735
import pl.project13.maven.git.util.Pair;
38-
39-
import java.io.IOException;
4036
import java.util.*;
4137

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

4743
private LoggerBridge log;
4844
private JGitCommon jGitCommon;
45+
private String evaluateOnCommit;
4946

5047
// TODO not yet implemented options:
5148
// private boolean containsFlag = false;
@@ -86,17 +83,18 @@ public class DescribeCommand extends GitCommand<DescribeResult> {
8683
* @param log logger bridge to direct logs to
8784
*/
8885
@NotNull
89-
public static DescribeCommand on(Repository repo, LoggerBridge log) {
90-
return new DescribeCommand(repo, log);
86+
public static DescribeCommand on(String evaluateOnCommit, Repository repo, LoggerBridge log) {
87+
return new DescribeCommand(evaluateOnCommit, repo, log);
9188
}
9289

9390
/**
9491
* Creates a new describe command which interacts with a single repository
9592
*
9693
* @param repo the {@link org.eclipse.jgit.lib.Repository} this command should interact with
9794
*/
98-
private DescribeCommand(Repository repo, @NotNull LoggerBridge log) {
95+
private DescribeCommand(@NotNull String evaluateOnCommit, @NotNull Repository repo, @NotNull LoggerBridge log) {
9996
super(repo);
97+
this.evaluateOnCommit = evaluateOnCommit;
10098
this.jGitCommon = new JGitCommon(log);
10199
this.log = log;
102100
}
@@ -259,14 +257,14 @@ public DescribeResult call() throws GitAPIException {
259257
Map<ObjectId, List<String>> tagObjectIdToName = jGitCommon.findTagObjectIds(repo, tagsFlag, matchPattern);
260258

261259
// get current commit
262-
RevCommit headCommit = findHeadObjectId(repo);
263-
ObjectId headCommitId = headCommit.getId();
260+
RevCommit evalCommit = findEvalCommitObjectId(evaluateOnCommit, repo);
261+
ObjectId evalCommitId = evalCommit.getId();
264262

265263
// check if dirty
266264
boolean dirty = findDirtyState(repo);
267265

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

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

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

294292
// check how far away from a tag we are
295293

296-
int distance = jGitCommon.distanceBetween(repo, headCommit, commits.get(0));
294+
int distance = jGitCommon.distanceBetween(repo, evalCommit, commits.get(0));
297295
String tagName = tagObjectIdToName.get(commits.get(0)).iterator().next();
298296
Pair<Integer, String> howFarFromWhichTag = Pair.of(distance, tagName);
299297

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

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

347-
RevCommit findHeadObjectId(@NotNull Repository repo) throws RuntimeException {
348-
return jGitCommon.findHeadObjectId(repo);
345+
RevCommit findEvalCommitObjectId(@NotNull String evaluateOnCommit, @NotNull Repository repo) throws RuntimeException {
346+
return jGitCommon.findEvalCommitObjectId(evaluateOnCommit, repo);
349347
}
350348

351349
private String createMatchPattern() {

src/main/java/pl/project13/jgit/JGitCommon.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.eclipse.jgit.api.Status;
2626
import org.eclipse.jgit.api.errors.GitAPIException;
2727
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
28-
import org.eclipse.jgit.lib.Constants;
2928
import org.eclipse.jgit.lib.ObjectId;
3029
import org.eclipse.jgit.lib.Ref;
3130
import org.eclipse.jgit.lib.Repository;
@@ -53,27 +52,31 @@ public JGitCommon(LoggerBridge log) {
5352
this.log = log;
5453
}
5554

56-
public Collection<String> getTags(Repository repo, final ObjectId headId) throws GitAPIException {
55+
public Collection<String> getTags(Repository repo, final ObjectId objectId) throws GitAPIException {
5756
try (Git git = Git.wrap(repo)) {
5857
try (RevWalk walk = new RevWalk(repo)) {
59-
Collection<String> tags = getTags(git, headId, walk);
58+
Collection<String> tags = getTags(git, objectId, walk);
6059
walk.dispose();
6160
return tags;
6261
}
6362
}
6463
}
6564

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

87-
public String getClosestTagName(@NotNull Repository repo, GitDescribeConfig gitDescribe) {
90+
public String getClosestTagName(@NotNull String evaluateOnCommit, @NotNull Repository repo, GitDescribeConfig gitDescribe) {
8891
// TODO: Why does some tests fail when it gets headCommit from JGitprovider?
89-
RevCommit headCommit = findHeadObjectId(repo);
92+
RevCommit headCommit = findEvalCommitObjectId(evaluateOnCommit, repo);
9093
Pair<RevCommit, String> pair = getClosestRevCommit(repo, headCommit, gitDescribe);
9194
return pair.second;
9295
}
9396

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

138-
protected RevCommit findHeadObjectId(@NotNull Repository repo) throws RuntimeException {
141+
protected RevCommit findEvalCommitObjectId(@NotNull String evaluateOnCommit, @NotNull Repository repo) throws RuntimeException {
139142
try {
140-
ObjectId headId = repo.resolve(Constants.HEAD);
143+
ObjectId evalCommitId = repo.resolve(evaluateOnCommit);
141144

142145
try (RevWalk walk = new RevWalk(repo)) {
143-
RevCommit headCommit = walk.lookupCommit(headId);
146+
RevCommit evalCommit = walk.parseCommit(evalCommitId);
144147
walk.dispose();
145148

146-
log.info("HEAD is [{}]", headCommit.getName());
147-
return headCommit;
149+
log.info("evalCommit is [{}]", evalCommit.getName());
150+
return evalCommit;
148151
}
149152
} catch (IOException ex) {
150-
throw new RuntimeException("Unable to obtain HEAD commit!", ex);
153+
throw new RuntimeException("Unable to obtain " + evaluateOnCommit + " commit!", ex);
151154
}
152155
}
153156

src/main/java/pl/project13/maven/git/GitCommitIdMojo.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.Map;
3737
import java.util.Properties;
3838
import java.util.TimeZone;
39+
import java.util.regex.Pattern;
3940

4041
import org.apache.maven.execution.MavenSession;
4142
import org.apache.maven.plugin.AbstractMojo;
@@ -304,6 +305,23 @@ public class GitCommitIdMojo extends AbstractMojo {
304305
@Parameter
305306
@VisibleForTesting List<ReplacementProperty> replacementProperties;
306307

308+
/**
309+
* Allow to tell the plugin what commit should be used as reference to generate the properties from.
310+
* By default this property is simply set to <p>HEAD</p> which should reference to the latest commit in your repository.
311+
*
312+
* In general this property can be set to something generic like <p>HEAD^1</p> or point to a branch or tag-name.
313+
* To support any kind or use-case this configuration can also be set to an entire commit-hash or it's abbreviated version.
314+
*
315+
* A use-case for this feature can be found in https://github.com/ktoso/maven-git-commit-id-plugin/issues/338.
316+
*
317+
* Please note that for security purposes not all references might be allowed as configuration.
318+
* If you have a specific use-case that is currently not white listed feel free to file an issue.
319+
* @since 2.2.4
320+
*/
321+
@Parameter(defaultValue = "HEAD")
322+
private String evaluateOnCommit;
323+
protected static final Pattern allowedCharactersForEvaluateOnCommit = Pattern.compile("[a-zA-Z0-9\\_\\-\\^\\/\\.]+");
324+
307325
/**
308326
* The properties we store our data in and then expose them.
309327
*/
@@ -369,6 +387,11 @@ public void execute() throws MojoExecutionException {
369387
return;
370388
}
371389

390+
if ((evaluateOnCommit == null) || !allowedCharactersForEvaluateOnCommit.matcher(evaluateOnCommit).matches()) {
391+
log.error("suspicious argument for evaluateOnCommit, aborting execution!");
392+
return;
393+
}
394+
372395
try {
373396
try {
374397
commitIdGenerationModeEnum = CommitIdGenerationMode.valueOf(commitIdGenerationMode.toUpperCase());
@@ -515,7 +538,7 @@ void loadGitDataWithNativeGit(@NotNull Properties properties) throws GitCommitId
515538
.setGitDescribe(gitDescribe)
516539
.setCommitIdGenerationMode(commitIdGenerationModeEnum);
517540

518-
nativeGitProvider.loadGitData(properties);
541+
nativeGitProvider.loadGitData(evaluateOnCommit, properties);
519542
} catch (IOException e) {
520543
throw new GitCommitIdExecutionException(e);
521544
}
@@ -531,7 +554,7 @@ void loadGitDataWithJGit(@NotNull Properties properties) throws GitCommitIdExecu
531554
.setGitDescribe(gitDescribe)
532555
.setCommitIdGenerationMode(commitIdGenerationModeEnum);
533556

534-
jGitProvider.loadGitData(properties);
557+
jGitProvider.loadGitData(evaluateOnCommit, properties);
535558
}
536559

537560
void maybeGeneratePropertiesFile(@NotNull Properties localProperties, File base, String propertiesFilename) throws GitCommitIdExecutionException {
@@ -787,4 +810,12 @@ static class CannotReadFileException extends Exception {
787810
@VisibleForTesting void setFailOnUnableToExtractRepoInfo(boolean failOnUnableToExtractRepoInfo) {
788811
this.failOnUnableToExtractRepoInfo = failOnUnableToExtractRepoInfo;
789812
}
813+
814+
@VisibleForTesting String getEvaluateOnCommit() {
815+
return evaluateOnCommit;
816+
}
817+
818+
@VisibleForTesting void setEvaluateOnCommit(String evaluateOnCommit) {
819+
this.evaluateOnCommit = evaluateOnCommit;
820+
}
790821
}

src/main/java/pl/project13/maven/git/GitDataProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public abstract class GitDataProvider implements GitProvider {
4949

5050
protected CommitIdGenerationMode commitIdGenerationMode;
5151

52+
protected String evaluateOnCommit;
53+
5254
public GitDataProvider(@NotNull LoggerBridge log) {
5355
this.log = log;
5456
}
@@ -83,7 +85,8 @@ public GitDataProvider setDateFormatTimeZone(String dateFormatTimeZone) {
8385
return this;
8486
}
8587

86-
public void loadGitData(@NotNull Properties properties) throws GitCommitIdExecutionException {
88+
public void loadGitData(@NotNull String evaluateOnCommit, @NotNull Properties properties) throws GitCommitIdExecutionException {
89+
this.evaluateOnCommit = evaluateOnCommit;
8790
init();
8891
// git.user.name
8992
put(properties, GitCommitPropertyConstant.BUILD_AUTHOR_NAME, getBuildAuthorName());

0 commit comments

Comments
 (0)