Skip to content

Commit b9bd821

Browse files
author
Marc ROZANC
committed
Add describeTagMaxDepth config to limit the repository scan
In case we have a more specific tag pattern to search on a branch, and this pattern does not match any tag in the branch, it's preferable to have a limit to the describe search for performance reasons.
1 parent b094b98 commit b9bd821

File tree

8 files changed

+161
-33
lines changed

8 files changed

+161
-33
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ You can configure the version and properties adjustments for specific branches a
5858
```xml
5959
<configuration xmlns="https://github.com/qoomon/maven-git-versioning-extension"
6060
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
61-
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-9.4.0.xsd">
61+
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-9.8.2.xsd">
6262

6363
<refs>
6464
<ref type="branch">
@@ -93,6 +93,10 @@ You can configure the version and properties adjustments for specific branches a
9393
- has to be a **full match pattern** e.g. `v(.+)`, default is `.*`
9494
- `<describeTagFirstParent>` Enable(`true`) or disable(`false`) following only the first parent in a merge commit
9595
- default is `true`
96+
- `<describeTagMaxDepth>` An integer that describes the maximum number of commits to scan in search of a tag matching
97+
`<describeTagPattern>`.
98+
- By default, it is set to `Integer.MAX_VALUE`.
99+
- For convenience, any strictly negative value will also remove the limitation.
96100

97101
- `<updatePom>` Enable(`true`)/disable(`false`) version and properties update in original pom file, default is `false`
98102
- Can be overridden by command option, see [Parameters & Environment Variables](#parameters--environment-variables).
@@ -114,6 +118,10 @@ You can configure the version and properties adjustments for specific branches a
114118
- will override global `<describeTagPattern>` value
115119
- `<describeTagFirstParent>` Enable(`true`) or disable(`false`) following only the first parent in a merge commit
116120
- default is `true`
121+
- `<describeTagMaxDepth>` An integer that describes the maximum number of commits to scan in search of a tag matching
122+
`<describeTagPattern>`.
123+
- By default, it is set to `Integer.MAX_VALUE`.
124+
- For convenience, any strictly negative value will also remove the limitation.
117125
<br><br>
118126

119127
- `<version>` The new version format, see [Format Placeholders](#format-placeholders)

docs/configuration-9.8.2.xsd

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<xs:schema xmlns="https://github.com/qoomon/maven-git-versioning-extension"
4+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
5+
targetNamespace="https://github.com/qoomon/maven-git-versioning-extension"
6+
elementFormDefault="qualified">
7+
8+
<xs:element name="configuration">
9+
<xs:complexType>
10+
<xs:all>
11+
<xs:element name="disable" type="xs:boolean" minOccurs="0"/>
12+
13+
<xs:element name="projectVersionPattern" type="xs:string" minOccurs="0"/>
14+
15+
<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
16+
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
17+
<xs:element name="describeTagMaxDepth" type="xs:int" minOccurs="0"/>
18+
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>
19+
20+
<xs:element name="refs" minOccurs="0">
21+
<xs:complexType>
22+
<xs:sequence>
23+
<xs:element name="ref" type="RefPatchDescription" minOccurs="0" maxOccurs="unbounded"/>
24+
</xs:sequence>
25+
26+
<xs:attribute name="considerTagsOnBranches" type="xs:boolean"/>
27+
</xs:complexType>
28+
</xs:element>
29+
30+
<xs:element name="rev" type="PatchDescription" minOccurs="0"/>
31+
32+
<xs:element name="relatedProjects" minOccurs="0">
33+
<xs:complexType>
34+
<xs:sequence>
35+
<xs:element name="project" type="RelatedProject" minOccurs="0" maxOccurs="unbounded"/>
36+
</xs:sequence>
37+
</xs:complexType>
38+
</xs:element>
39+
</xs:all>
40+
</xs:complexType>
41+
</xs:element>
42+
43+
<xs:complexType name="PatchDescription">
44+
<xs:all>
45+
<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
46+
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
47+
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>
48+
49+
<xs:element name="version" type="xs:string" minOccurs="0"/>
50+
<xs:element name="properties" minOccurs="0">
51+
<xs:complexType>
52+
<xs:sequence>
53+
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
54+
</xs:sequence>
55+
</xs:complexType>
56+
</xs:element>
57+
</xs:all>
58+
</xs:complexType>
59+
60+
<xs:complexType name="RefPatchDescription">
61+
<xs:all>
62+
<xs:element name="pattern" type="xs:string" minOccurs="0"/>
63+
<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
64+
<xs:element name="describeTagMaxDepth" type="xs:int" minOccurs="0"/>
65+
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
66+
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>
67+
68+
<xs:element name="version" type="xs:string" minOccurs="0"/>
69+
<xs:element name="properties" minOccurs="0">
70+
<xs:complexType>
71+
<xs:sequence>
72+
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
73+
</xs:sequence>
74+
</xs:complexType>
75+
</xs:element>
76+
</xs:all>
77+
78+
<xs:attribute name="type" use="required">
79+
<xs:simpleType>
80+
<xs:restriction base="xs:string">
81+
<xs:enumeration value="tag"/>
82+
<xs:enumeration value="branch"/>
83+
</xs:restriction>
84+
</xs:simpleType>
85+
</xs:attribute>
86+
</xs:complexType>
87+
88+
<xs:complexType name="RelatedProject">
89+
<xs:all>
90+
<xs:element name="groupId" type="xs:string"/>
91+
<xs:element name="artifactId" type="xs:string"/>
92+
</xs:all>
93+
</xs:complexType>
94+
95+
</xs:schema>

docs/example-configuration.xml

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

33
<configuration xmlns="https://github.com/qoomon/maven-git-versioning-extension" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-6.4.0.xsd">
4+
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-9.8.2.xsd">
55

66
<disable>false</disable>
77
<updatePom>false</updatePom>
8-
<preferTags>false</preferTags>
8+
<describeTagMaxDepth>100</describeTagMaxDepth>
99

10-
<branch>
11-
<pattern>.*</pattern>
12-
<versionFormat>${branch}-SNAPSHOT</versionFormat>
13-
<property>
14-
<name>name</name>
15-
<valueFormat>value</valueFormat>
16-
</property>
17-
<property>
18-
<name>name</name>
19-
<valueFormat>value</valueFormat>
20-
</property>
21-
</branch>
10+
<refs considerTagsOnBranches="true">
11+
<ref type="tag">
12+
<pattern>v(.*)</pattern>
13+
<version>${ref.1}</version>
14+
</ref>
2215

23-
<tag>
24-
<pattern>v(.*)</pattern>
25-
<versionFormat>${1}</versionFormat>
26-
</tag>
16+
<ref type="branch">
17+
<pattern>.*</pattern>
18+
<version>${ref}</version>
19+
<properties>
20+
<name>value</name>
21+
</properties>
22+
</ref>
23+
</refs>
2724

28-
<commit>
29-
<versionFormat>${commit}</versionFormat>
30-
</commit>
25+
<rev>
26+
<version>${commit}</version>
27+
</rev>
3128

3229
</configuration>

src/main/java/me/qoomon/gitversioning/commons/GitSituation.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class GitSituation {
3636

3737
private boolean firstParent = true;
3838

39-
private Supplier<GitDescription> description = Lazy.by(this::describe);
39+
private Supplier<GitDescription> description = Lazy.by(() -> this.describe(Integer.MAX_VALUE));
4040

4141
public GitSituation(Repository repository) throws IOException {
4242
this.repository = repository;
@@ -121,9 +121,9 @@ public boolean isClean() {
121121
return clean.get();
122122
}
123123

124-
public void setDescribeTagPattern(Pattern describeTagPattern) {
124+
public void setDescribeTagPattern(Pattern describeTagPattern, Integer describeTagMaxDepth) {
125125
this.describeTagPattern = requireNonNull(describeTagPattern);
126-
this.description = Lazy.by(this::describe);
126+
this.description = Lazy.by(() -> this.describe(describeTagMaxDepth));
127127
}
128128

129129
public Pattern getDescribeTagPattern() {
@@ -162,7 +162,7 @@ private boolean clean() throws GitAPIException {
162162
return GitUtil.status(repository).isClean();
163163
}
164164

165-
private GitDescription describe() throws IOException {
166-
return GitUtil.describe(head, describeTagPattern, repository, firstParent);
165+
private GitDescription describe(Integer maxDepth) throws IOException {
166+
return GitUtil.describe(head, describeTagPattern, repository, firstParent, maxDepth);
167167
}
168168
}

src/main/java/me/qoomon/gitversioning/commons/GitUtil.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static List<String> tagsPointAt(ObjectId revObjectId, Repository reposito
5050
return reverseTagRefMap(repository).getOrDefault(revObjectId, emptyList());
5151
}
5252

53-
public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern, Repository repository, boolean firstParent) throws IOException {
53+
public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern, Repository repository, boolean firstParent, Integer maxDepth) throws IOException {
5454
Repository commonRepository = worktreesFix_getCommonRepository(repository);
5555
if (revObjectId == null) {
5656
return new GitDescription(NO_COMMIT, "root", 0, false);
@@ -64,8 +64,9 @@ public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern,
6464
walk.setFirstParent(firstParent);
6565
walk.markStart(walk.parseCommit(revObjectId));
6666
Iterator<RevCommit> walkIterator = walk.iterator();
67+
final int positiveMaxDepth = maxDepth == null || maxDepth < 0 ? Integer.MAX_VALUE : maxDepth;
6768
int depth = 0;
68-
while (walkIterator.hasNext()) {
69+
while (walkIterator.hasNext() && depth < positiveMaxDepth) {
6970
RevCommit rev = walkIterator.next();
7071
Optional<String> matchingTag = objectIdListMap.getOrDefault(rev, emptyList()).stream()
7172
.filter(tag -> tagPattern.matcher(tag).matches())

src/main/java/me/qoomon/maven/gitversioning/Configuration.java

+5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public Pattern describeTagPattern() {
5555
return Pattern.compile(describeTagPattern);
5656
}
5757

58+
public Integer describeTagMaxDepth = Integer.MAX_VALUE;
59+
5860
public Boolean updatePom = false;
5961

6062
public RefPatchDescriptionList refs = new RefPatchDescriptionList();
@@ -79,6 +81,8 @@ public Pattern describeTagPattern() {
7981
return Pattern.compile(describeTagPattern);
8082
}
8183

84+
public Integer describeTagMaxDepth;
85+
8286
@JsonDeserialize(using = IgnoreWhitespaceDeserializer.class)
8387
public String version;
8488

@@ -120,6 +124,7 @@ public RefPatchDescription(GitRefType type, Pattern pattern, PatchDescription de
120124
this.type = type;
121125
this.pattern = pattern != null ? pattern.pattern() : null;
122126
this.describeTagPattern = description.describeTagPattern;
127+
this.describeTagMaxDepth = description.describeTagMaxDepth;
123128
this.updatePom = description.updatePom;
124129
this.describeTagFirstParent = description.describeTagFirstParent;
125130
this.version = description.version;

src/main/java/me/qoomon/maven/gitversioning/GitVersioningModelProcessor.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ private void init(Model projectModel) throws IOException {
230230
logger.info("ref configuration: {} - pattern: {}", gitVersionDetails.getRefType().name(), patchDescription.pattern);
231231
if (patchDescription.describeTagPattern != null && !patchDescription.describeTagPattern.equals(".*")) {
232232
logger.info(" describeTagPattern: {}", patchDescription.describeTagPattern);
233-
gitSituation.setDescribeTagPattern(patchDescription.describeTagPattern());
233+
gitSituation.setDescribeTagPattern(patchDescription.describeTagPattern(), patchDescription.describeTagMaxDepth);
234234
}
235235
if (patchDescription.describeTagFirstParent != null) {
236236
logger.info(" describeTagFirstParent: {}", patchDescription.describeTagFirstParent);
@@ -1048,6 +1048,9 @@ private static Configuration readConfig(File configFile) throws IOException {
10481048
if (patchDescription.describeTagFirstParent == null) {
10491049
patchDescription.describeTagFirstParent = config.describeTagFirstParent;
10501050
}
1051+
if (patchDescription.describeTagMaxDepth == null) {
1052+
patchDescription.describeTagMaxDepth = config.describeTagMaxDepth;
1053+
}
10511054
if (patchDescription.updatePom == null) {
10521055
patchDescription.updatePom = config.updatePom;
10531056
}

src/test/java/me/qoomon/gitversioning/commons/GitUtilTest.java

+22-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import java.util.regex.Pattern;
1818

1919
import static org.assertj.core.api.Assertions.assertThat;
20-
import static org.assertj.core.api.SoftAssertions.assertSoftly;
2120
import static org.eclipse.jgit.lib.Constants.HEAD;
2221
import static org.eclipse.jgit.lib.Constants.MASTER;
2322

@@ -189,7 +188,7 @@ void describe() throws Exception {
189188
git.tag().setName(givenTagName).setAnnotated(true).setObjectId(givenCommit).setMessage(".").call();
190189

191190
// when
192-
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true);
191+
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true, -1);
193192

194193
// then
195194
assertThat(description).satisfies(it -> {
@@ -207,11 +206,31 @@ void distanceOrZeroIsZeroWhenNoTagMatches() throws Exception {
207206

208207
final var softly = new SoftAssertions();
209208
for (int i = 0; i < 3; ++i) {
210-
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true);
209+
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true, -1);
210+
softly.assertThat(description.isTagFound()).isFalse();
211211
softly.assertThat(description.getDistanceOrZero()).isZero();
212212
softly.assertThat(description.getDistance()).isEqualTo(i);
213213
git.commit().setMessage("commit " + (i + 1)).setAllowEmpty(true).call();
214214
}
215215
softly.assertAll();
216216
}
217+
218+
@Test
219+
void distanceWithMaxDepth() throws Exception {
220+
// given
221+
final int maxDepth = 4;
222+
Git git = Git.init().setInitialBranch(MASTER).setDirectory(tempDir.toFile()).call();
223+
final RevCommit firstCommit = git.commit().setMessage("initial commit").setAllowEmpty(true).call();
224+
git.tag().setName("v1.0.0").setAnnotated(true).setObjectId(firstCommit).setMessage(".").call();
225+
226+
final SoftAssertions softly = new SoftAssertions();
227+
for (int i = 0; i < 6; ++i) {
228+
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true, maxDepth);
229+
softly.assertThat(description.isTagFound()).as("distanceOrZero " + i).isEqualTo(i < maxDepth);
230+
softly.assertThat(description.getDistanceOrZero()).as("distanceOrZero " + i).isEqualTo(i >= maxDepth ? 0 : i);
231+
softly.assertThat(description.getDistance()).as("distance " + i).isEqualTo(Math.min(i, maxDepth));
232+
git.commit().setMessage("commit " + (i + 1)).setAllowEmpty(true).call();
233+
}
234+
softly.assertAll();
235+
}
217236
}

0 commit comments

Comments
 (0)