Skip to content

Commit

Permalink
Add describeTagMaxDepth config to limit the repository scan
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Marc ROZANC committed Sep 22, 2024
1 parent b094b98 commit b9bd821
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 33 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ You can configure the version and properties adjustments for specific branches a
```xml
<configuration xmlns="https://github.com/qoomon/maven-git-versioning-extension"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-9.4.0.xsd">
xsi:schemaLocation="https://github.com/qoomon/maven-git-versioning-extension https://qoomon.github.io/maven-git-versioning-extension/configuration-9.8.2.xsd">

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

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

- `<version>` The new version format, see [Format Placeholders](#format-placeholders)
Expand Down
95 changes: 95 additions & 0 deletions docs/configuration-9.8.2.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns="https://github.com/qoomon/maven-git-versioning-extension"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://github.com/qoomon/maven-git-versioning-extension"
elementFormDefault="qualified">

<xs:element name="configuration">
<xs:complexType>
<xs:all>
<xs:element name="disable" type="xs:boolean" minOccurs="0"/>

<xs:element name="projectVersionPattern" type="xs:string" minOccurs="0"/>

<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
<xs:element name="describeTagMaxDepth" type="xs:int" minOccurs="0"/>
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>

<xs:element name="refs" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="ref" type="RefPatchDescription" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>

<xs:attribute name="considerTagsOnBranches" type="xs:boolean"/>
</xs:complexType>
</xs:element>

<xs:element name="rev" type="PatchDescription" minOccurs="0"/>

<xs:element name="relatedProjects" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="project" type="RelatedProject" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>

<xs:complexType name="PatchDescription">
<xs:all>
<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>

<xs:element name="version" type="xs:string" minOccurs="0"/>
<xs:element name="properties" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>

<xs:complexType name="RefPatchDescription">
<xs:all>
<xs:element name="pattern" type="xs:string" minOccurs="0"/>
<xs:element name="describeTagPattern" type="xs:string" minOccurs="0"/>
<xs:element name="describeTagMaxDepth" type="xs:int" minOccurs="0"/>
<xs:element name="describeTagFirstParent" type="xs:boolean" minOccurs="0"/>
<xs:element name="updatePom" type="xs:boolean" minOccurs="0"/>

<xs:element name="version" type="xs:string" minOccurs="0"/>
<xs:element name="properties" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>

<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="tag"/>
<xs:enumeration value="branch"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>

<xs:complexType name="RelatedProject">
<xs:all>
<xs:element name="groupId" type="xs:string"/>
<xs:element name="artifactId" type="xs:string"/>
</xs:all>
</xs:complexType>

</xs:schema>
39 changes: 18 additions & 21 deletions docs/example-configuration.xml
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>

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

<disable>false</disable>
<updatePom>false</updatePom>
<preferTags>false</preferTags>
<describeTagMaxDepth>100</describeTagMaxDepth>

<branch>
<pattern>.*</pattern>
<versionFormat>${branch}-SNAPSHOT</versionFormat>
<property>
<name>name</name>
<valueFormat>value</valueFormat>
</property>
<property>
<name>name</name>
<valueFormat>value</valueFormat>
</property>
</branch>
<refs considerTagsOnBranches="true">
<ref type="tag">
<pattern>v(.*)</pattern>
<version>${ref.1}</version>
</ref>

<tag>
<pattern>v(.*)</pattern>
<versionFormat>${1}</versionFormat>
</tag>
<ref type="branch">
<pattern>.*</pattern>
<version>${ref}</version>
<properties>
<name>value</name>
</properties>
</ref>
</refs>

<commit>
<versionFormat>${commit}</versionFormat>
</commit>
<rev>
<version>${commit}</version>
</rev>

</configuration>
10 changes: 5 additions & 5 deletions src/main/java/me/qoomon/gitversioning/commons/GitSituation.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class GitSituation {

private boolean firstParent = true;

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

public GitSituation(Repository repository) throws IOException {
this.repository = repository;
Expand Down Expand Up @@ -121,9 +121,9 @@ public boolean isClean() {
return clean.get();
}

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

public Pattern getDescribeTagPattern() {
Expand Down Expand Up @@ -162,7 +162,7 @@ private boolean clean() throws GitAPIException {
return GitUtil.status(repository).isClean();
}

private GitDescription describe() throws IOException {
return GitUtil.describe(head, describeTagPattern, repository, firstParent);
private GitDescription describe(Integer maxDepth) throws IOException {
return GitUtil.describe(head, describeTagPattern, repository, firstParent, maxDepth);
}
}
5 changes: 3 additions & 2 deletions src/main/java/me/qoomon/gitversioning/commons/GitUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static List<String> tagsPointAt(ObjectId revObjectId, Repository reposito
return reverseTagRefMap(repository).getOrDefault(revObjectId, emptyList());
}

public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern, Repository repository, boolean firstParent) throws IOException {
public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern, Repository repository, boolean firstParent, Integer maxDepth) throws IOException {
Repository commonRepository = worktreesFix_getCommonRepository(repository);
if (revObjectId == null) {
return new GitDescription(NO_COMMIT, "root", 0, false);
Expand All @@ -64,8 +64,9 @@ public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern,
walk.setFirstParent(firstParent);
walk.markStart(walk.parseCommit(revObjectId));
Iterator<RevCommit> walkIterator = walk.iterator();
final int positiveMaxDepth = maxDepth == null || maxDepth < 0 ? Integer.MAX_VALUE : maxDepth;
int depth = 0;
while (walkIterator.hasNext()) {
while (walkIterator.hasNext() && depth < positiveMaxDepth) {
RevCommit rev = walkIterator.next();
Optional<String> matchingTag = objectIdListMap.getOrDefault(rev, emptyList()).stream()
.filter(tag -> tagPattern.matcher(tag).matches())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public Pattern describeTagPattern() {
return Pattern.compile(describeTagPattern);
}

public Integer describeTagMaxDepth = Integer.MAX_VALUE;

public Boolean updatePom = false;

public RefPatchDescriptionList refs = new RefPatchDescriptionList();
Expand All @@ -79,6 +81,8 @@ public Pattern describeTagPattern() {
return Pattern.compile(describeTagPattern);
}

public Integer describeTagMaxDepth;

@JsonDeserialize(using = IgnoreWhitespaceDeserializer.class)
public String version;

Expand Down Expand Up @@ -120,6 +124,7 @@ public RefPatchDescription(GitRefType type, Pattern pattern, PatchDescription de
this.type = type;
this.pattern = pattern != null ? pattern.pattern() : null;
this.describeTagPattern = description.describeTagPattern;
this.describeTagMaxDepth = description.describeTagMaxDepth;
this.updatePom = description.updatePom;
this.describeTagFirstParent = description.describeTagFirstParent;
this.version = description.version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private void init(Model projectModel) throws IOException {
logger.info("ref configuration: {} - pattern: {}", gitVersionDetails.getRefType().name(), patchDescription.pattern);
if (patchDescription.describeTagPattern != null && !patchDescription.describeTagPattern.equals(".*")) {
logger.info(" describeTagPattern: {}", patchDescription.describeTagPattern);
gitSituation.setDescribeTagPattern(patchDescription.describeTagPattern());
gitSituation.setDescribeTagPattern(patchDescription.describeTagPattern(), patchDescription.describeTagMaxDepth);
}
if (patchDescription.describeTagFirstParent != null) {
logger.info(" describeTagFirstParent: {}", patchDescription.describeTagFirstParent);
Expand Down Expand Up @@ -1048,6 +1048,9 @@ private static Configuration readConfig(File configFile) throws IOException {
if (patchDescription.describeTagFirstParent == null) {
patchDescription.describeTagFirstParent = config.describeTagFirstParent;
}
if (patchDescription.describeTagMaxDepth == null) {
patchDescription.describeTagMaxDepth = config.describeTagMaxDepth;
}
if (patchDescription.updatePom == null) {
patchDescription.updatePom = config.updatePom;
}
Expand Down
25 changes: 22 additions & 3 deletions src/test/java/me/qoomon/gitversioning/commons/GitUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.regex.Pattern;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.lib.Constants.MASTER;

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

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

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

final var softly = new SoftAssertions();
for (int i = 0; i < 3; ++i) {
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true);
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true, -1);
softly.assertThat(description.isTagFound()).isFalse();
softly.assertThat(description.getDistanceOrZero()).isZero();
softly.assertThat(description.getDistance()).isEqualTo(i);
git.commit().setMessage("commit " + (i + 1)).setAllowEmpty(true).call();
}
softly.assertAll();
}

@Test
void distanceWithMaxDepth() throws Exception {
// given
final int maxDepth = 4;
Git git = Git.init().setInitialBranch(MASTER).setDirectory(tempDir.toFile()).call();
final RevCommit firstCommit = git.commit().setMessage("initial commit").setAllowEmpty(true).call();
git.tag().setName("v1.0.0").setAnnotated(true).setObjectId(firstCommit).setMessage(".").call();

final SoftAssertions softly = new SoftAssertions();
for (int i = 0; i < 6; ++i) {
GitDescription description = GitUtil.describe(head(git), Pattern.compile("v.+"), git.getRepository(), true, maxDepth);
softly.assertThat(description.isTagFound()).as("distanceOrZero " + i).isEqualTo(i < maxDepth);
softly.assertThat(description.getDistanceOrZero()).as("distanceOrZero " + i).isEqualTo(i >= maxDepth ? 0 : i);
softly.assertThat(description.getDistance()).as("distance " + i).isEqualTo(Math.min(i, maxDepth));
git.commit().setMessage("commit " + (i + 1)).setAllowEmpty(true).call();
}
softly.assertAll();
}
}

0 comments on commit b9bd821

Please sign in to comment.