Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all use of grgit from reckon #196

Merged
merged 8 commits into from
Apr 22, 2023
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
106 changes: 71 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,55 @@ Reckon can alternately use SNAPSHOT versions instead of the stage concept.

**NOTE:** Check the [Release Notes](https://github.com/ajoberstar/reckon/releases) for details on compatibility and changes.

### Gradle
**IMPORTANT:** It is recommended to apply reckon as a Settings plugin (in settings.gradle/settings.gradle.kts) to ensure it is configured before any other plugin tries to use the project version.

#### Apply the plugin
Reckon overrides the `project.version` property in Gradle to provide maximal compatibility with other plugins that need the version.

**IMPORTANT:** It is recommended to apply reckon as a Settings plugin (in settings.gradle/settings.gradle.kts) to ensure it is configured before any other plugin tries to use the project version.
### Recommended Configuration (Kotlin)

```groovy
**settings.gradle.kts**

// if applying in settings.gradle(.kts)
```kotlin
plugins {
id 'org.ajoberstar.reckon.settings' version '<version>'
id("org.ajoberstar.reckon.settings") version "<version>"
}

// if applying in build.gradle(.kts)
extensions.configure<org.ajoberstar.reckon.gradle.ReckonExtension> {
setDefaultInferredScope("patch")
stages("beta", "rc", "final")
setScopeCalc(calcScopeFromProp().or(calcScopeFromCommitMessages()))
setStageCalc(calcStageFromProp())
}
```

### Recommended Configuration (Groovy)

**settings.gradle**

```groovy
plugins {
id 'org.ajoberstar.reckon' version '<version>'
id('org.ajoberstar.reckon.settings') version ''<version>'
}

reckon {
defaultInferredScope = 'patch'
stages 'beta', 'rc', 'final'
scopeCalc = calcScopeFromProp().or(calcScopeFromCommitMessages())
stageCalc = calcStageFromProp()
}
```

### Extension Properties (Groovy)

// in either case
```groovy
reckon {
// START As of 0.16.0
// required as of 0.18.0 (previously defaulted to 'minor')
defaultInferredScope = 'patch'
// omit this to use the default of 'patch'
// if you use branches like maintenance/1.2.x, set this to 'minor'
// if you use branches like maintenance/2.x, set this to 'major'
parallelBranchScope = 'minor'

// what stages are allowed
stages('milestone', 'rc', 'final')
// or use snapshots
Expand All @@ -131,25 +159,7 @@ reckon {
scopeCalc = { inventory -> Optional.of(Scope.MAJOR) }
stageCalc = { inventory, targetNormal -> Optional.of('beta') }

// END As of 0.16.0

// START LEGACY
scopeFromProp()
stageFromProp('milestone', 'rc', 'final')

// alternative to stageFromProp
// snapshotFromProp()
// END LEGACY

// omit this to use the default of 'minor'
defaultInferredScope = 'patch'

// omit this to use the deafult of 'patch'
// if you use branches like maintenance/1.2.x, set this to 'minor'
// if you use branches like maintenance/2.x, set this to 'major'
parallelBranchScope = 'minor'

// omit to use default remote
// omit to use 'origin'
remote = 'other-remote'

// omit this to use the default of parsing tag names of the form 1.2.3 or v1.2.3
Expand All @@ -169,9 +179,35 @@ reckon {
}
```

**NOTE:** Reckon overrides the `project.version` property in Gradle
### Legacy Project Plugin

This version of the plugin will be retired before 1.0.0 (if that ever comes), due to ordering issues that can occur with other plugins reading the version.

**build.gradle.kts**

```kotlin
plugins {
id("org.ajoberstar.reckon") version "<version>"
}

reckon {
// configure as above
}
```

**build.gradle**

```groovy
plugins {
id 'org.ajoberstar.reckon' version '<version>'
}

reckon {
// configure as above
}
```

#### Passing scope/stage as props
### Passing scope/stage as props

- `reckon.scope` (allowed if `scopeCalc` includes `calcStageFromProp()` or if you called `scopeFromProp()`)
Valid values: `major`, `minor`, `patch` (if not set the scope is inferred by other means)
Expand All @@ -188,9 +224,9 @@ When Gradle executes, the version will be inferred as soon as something tries to
Reckoned version 1.3.0-milestone.1
```

#### Reading scope from commit messages
### Reading scope from commit messages

If you want the scope to inferred in a more automated way, consider making use of a commit message convention. This sections describes the out-of-the-box convention supported by Reckon. Others are possible by customizing the `scopeCalc` further.
If you want the scope to infer in a more automated way, consider making use of a commit message convention. This sections describes the out-of-the-box convention supported by Reckon. Others are possible by customizing the `scopeCalc` further.

If your `scopeCalc` includes `calcScopeFromCommitMessages()`, the commit messages between your "base normal" (previous final release) and the current `HEAD` are parsed for SemVer indicators.

Expand Down Expand Up @@ -236,13 +272,13 @@ pqr1234 (HEAD -> main) major: Removed deprecated setNormal method

In this case we'd be looking at all commits since the last tagged final version, `1.2.3`. We'd only care about messages that follow our convention of prefixing the message with a scope. Since there's a mix of commits using all 3 scopes, we pick the most severe of the ones we found `major`.

##### Special Case for pre-1.0.0
#### Special Case for pre-1.0.0

Before 1.0.0, SemVer doesn't really guarantee anything, but a good practice seems to be a `PATCH` increment is for bug fixes, while a `MINOR` increase can be new features or breaking changes.

In order to promote the convention of using `major: My message` for breaking changes, before 1.0.0 a `major` in a commit message will be read as `minor`. The goal is to promote you explicitly documenting breaking changes in your commit logs, while requiring the actual 1.0.0 version bump to come via an override with `-Preckon.scope=major`.

##### DISCLAIMER this is not Convention Commits compliant
#### DISCLAIMER this is not Convention Commits compliant

While this approach is similar to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), it does not follow their spec, sticking to something more directly applicable to Reckon's scopes. User's can use the `calcScopeFromCommitMessages(Function<String, Optional<Scope>>)` form if they want to implement Conventional Commits, or any other scheme themselves.

Expand Down
10 changes: 0 additions & 10 deletions build.gradle.kts

This file was deleted.

1 change: 0 additions & 1 deletion reckon-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ testing {
dependencies {
implementation("org.junit.jupiter:junit-jupiter-params")
implementation("org.mockito:mockito-core:latest.release")
implementation("org.ajoberstar.grgit:grgit-core:[5.0,6.0[")
runtimeOnly("org.slf4j:slf4j-simple:[2.0,3.0[")
}
}
Expand Down
4 changes: 1 addition & 3 deletions reckon-core/gradle.lockfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ com.github.zafarkhaja:java-semver:0.9.0=compileClasspath,runtimeClasspath,testCo
com.googlecode.javaewah:JavaEWAH:1.1.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
net.bytebuddy:byte-buddy-agent:1.14.4=testCompileClasspath,testRuntimeClasspath
net.bytebuddy:byte-buddy:1.14.4=testCompileClasspath,testRuntimeClasspath
org.ajoberstar.grgit:grgit-core:5.2.0=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.12.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
org.codehaus.groovy:groovy:3.0.17=testCompileClasspath,testRuntimeClasspath
org.eclipse.jgit:org.eclipse.jgit:6.5.0.202303070854-r=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.9.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.9.2=testRuntimeClasspath
Expand All @@ -23,4 +21,4 @@ org.objenesis:objenesis:3.3=testRuntimeClasspath
org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testRuntimeClasspath
org.slf4j:slf4j-api:2.0.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.slf4j:slf4j-simple:2.0.7=testRuntimeClasspath
empty=
empty=annotationProcessor,signatures,testAnnotationProcessor
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -19,9 +13,6 @@
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
Expand All @@ -32,7 +23,7 @@

/**
* Supplies an inventory of a Git repository.
*
* <p>
* This is intentionally package private.
*/
final class GitInventorySupplier implements VcsInventorySupplier {
Expand Down Expand Up @@ -105,7 +96,17 @@ public VcsInventory getInventory() {

private boolean isClean() {
try {
return new Git(repo).status().call().isClean();
var status = new Git(repo).status().call();
if (!status.isClean()) {
logger.info("Git repository is not clean: added={}, changed={}, removed={}, untracked={}, modified={}, missing={}",
status.getAdded(),
status.getChanged(),
status.getRemoved(),
status.getUntracked(),
status.getModified(),
status.getMissing());
}
return status.isClean();
} catch (GitAPIException e) {
logger.error("Failed to determine status of repository. Assuming not clean.", e);
// TODO should this throw up?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -60,7 +57,7 @@ public Version reckon() {
var reckoned = reckonTargetVersion(inventory, targetNormal);

if (reckoned.isSignificant() && !inventory.isClean()) {
throw new IllegalStateException("Cannot release a final or significant stage without a clean repo.");
throw new IllegalStateException("Cannot release a final or significant stage without a clean repo. Review INFO logs for more details.");
}

if (inventory.getClaimedVersions().contains(reckoned) && !inventory.getCurrentVersion().map(reckoned::equals).orElse(false)) {
Expand Down Expand Up @@ -160,7 +157,7 @@ public static final class Builder {
private VcsInventorySupplier inventorySupplier;
private ScopeCalculator scopeCalc;
private StageCalculator stageCalc;
private Scope defaultInferredScope = Scope.MINOR;
private Scope defaultInferredScope;
private Scope parallelBranchScope = Scope.PATCH;
private Set<String> stages;
private String defaultStage;
Expand Down
Loading