diff --git a/CHANGELOG.md b/CHANGELOG.md index c5f37da..96fe644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `tagMessage` allows to create annotated tags when publishing new versions. ([#22](https://github.com/diffplug/spotless-changelog/pull/22)) ## [2.1.2] - 2021-04-10 ### Fixed diff --git a/README.md b/README.md index f65d9c0..3773bd0 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ spotlessChangelog { // all defaults // tag and push tagPrefix 'release/' commitMessage 'Published release/{{version}}' // {{version}} will be replaced + tagMessage null // default is null (creates lightweight tag); {{changes}} and {{version}} will be replaced remote 'origin' branch 'main' // default value is `yes`, but if you set it to `no`, then it will diff --git a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/Changelog.java b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/Changelog.java index 832afc6..c9bda77 100644 --- a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/Changelog.java +++ b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/Changelog.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 DiffPlug + * Copyright (C) 2019-2021 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,6 @@ public class Changelog { private static final String VERSION_BEGIN = "\n## ["; private static final String UNRELEASED = VERSION_BEGIN + "Unreleased]"; private static final String DONT_PARSE_BELOW_HERE = "\n"; - private final boolean windowsNewlines; private final PoolString dontParse, beforeUnreleased; private final List versionsRaw; @@ -166,6 +165,15 @@ public static class VersionEntry { private VersionEntry() {} + private VersionEntry copy() { + VersionEntry copy = new VersionEntry(); + copy.version = version; + copy.date = date; + copy.headerMisc = headerMisc; + copy.changes = changes; + return copy; + } + /** Creates a VersionHeader of the given version and date. */ public static VersionEntry versionDate(String version, String date) { VersionEntry header = new VersionEntry(); @@ -313,7 +321,8 @@ public Changelog releaseUnreleased(String version, String date) { VersionEntry entry = VersionEntry.versionDate(version, date); entry.setChanges(unreleased.changes()); - unreleased.setChanges("\n"); + + list.set(0, unreleased.copy().setChanges("\n")); list.add(1, entry); }); } diff --git a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitActions.java b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitActions.java index 57ba7ae..e03d9c1 100644 --- a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitActions.java +++ b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitActions.java @@ -27,6 +27,7 @@ import java.util.function.Consumer; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PushCommand; +import org.eclipse.jgit.api.TagCommand; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; @@ -57,7 +58,6 @@ public class GitActions implements AutoCloseable { repository = new FileRepositoryBuilder() .findGitDir(changelogFile) .build(); - repository.getWorkTree(); git = new Git(repository); } @@ -87,23 +87,35 @@ public void assertNoTag() throws IOException { /** Adds and commits the changelog. */ public void addAndCommit() throws GitAPIException { - String commitMsg = cfg.commitMessage.replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next()); String path = repository.getWorkTree().toPath().relativize(changelogFile.toPath()).toString(); git.add() .addFilepattern(path) .call(); git.commit() - .setMessage(commitMsg) + .setMessage(formatCommitMessage(cfg.commitMessage)) .call(); } - /** Tags and pushes the tag and the branch. */ + /** Tags and pushes the tag and the branch. */ public void tagBranchPush() throws GitAPIException { - Ref tagRef = git.tag().setName(tagName()).setAnnotated(false).call(); - push(tagRef, RemoteRefUpdate.Status.OK); + TagCommand tagCommand = git.tag().setName(tagName()); + if (cfg.tagMessage != null) { + tagCommand.setAnnotated(true).setMessage(formatTagMessage(cfg.tagMessage)); + } + push(tagCommand.call(), RemoteRefUpdate.Status.OK); push(cfg.branch, RemoteRefUpdate.Status.OK); } + private String formatCommitMessage(final String commitMessage) { + return commitMessage.replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next()); + } + + private String formatTagMessage(final String tagMessage) { + return formatCommitMessage(tagMessage) + .replace(GitCfg.TAG_MESSAGE_CHANGES, model.changelog().unreleasedChanges()) + .replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next()); + } + private String tagName() { return cfg.tagPrefix + model.versions().next(); } diff --git a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitCfg.java b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitCfg.java index f160c46..106d9ae 100644 --- a/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitCfg.java +++ b/spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitCfg.java @@ -22,11 +22,14 @@ /** Configuration for committing, tagging, and pushing the next version. */ public class GitCfg { public static final String COMMIT_MESSAGE_VERSION = "{{version}}"; + public static final String TAG_MESSAGE_CHANGES = "{{changes}}"; /** Prefix used for release tags, default is `release/`. */ public String tagPrefix = "release/"; /** Message used for release commits, default is `Published release/{{version}}`. */ public String commitMessage = "Published release/" + COMMIT_MESSAGE_VERSION; + /** Message used in tag, null means lightweight tag. */ + public String tagMessage = null; public String remote = "origin"; public String branch = "main"; public String sshStrictHostKeyChecking = "yes"; diff --git a/spotless-changelog-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/ChangelogExtension.java b/spotless-changelog-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/ChangelogExtension.java index 15b50f5..912490e 100644 --- a/spotless-changelog-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/ChangelogExtension.java +++ b/spotless-changelog-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/ChangelogExtension.java @@ -194,6 +194,11 @@ public void commitMessage(String commitMessage) { gitCfg.commitMessage = GitCfg.validateCommitMessage(commitMessage); } + /** Default value is null (creates a lightweight tag) - {{changes}} and {{version}} will be replaced. */ + public void tagMessage(String tagMessage) { + gitCfg.tagMessage = tagMessage; + } + /** Default value is 'origin' */ public void remote(String remote) { gitCfg.remote = remote; diff --git a/spotless-changelog-plugin-gradle/src/test/java/com/diffplug/spotless/changelog/gradle/ChangelogPluginPushTest.java b/spotless-changelog-plugin-gradle/src/test/java/com/diffplug/spotless/changelog/gradle/ChangelogPluginPushTest.java new file mode 100644 index 0000000..8998a04 --- /dev/null +++ b/spotless-changelog-plugin-gradle/src/test/java/com/diffplug/spotless/changelog/gradle/ChangelogPluginPushTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2019-2021 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.changelog.gradle; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.revwalk.RevWalk; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +public class ChangelogPluginPushTest extends GradleHarness { + + @Rule + public DeleteOnSuccessTemporaryFolder temporaryFolder = new DeleteOnSuccessTemporaryFolder(new File("build")); + @Rule + public KeepTempFolderOnFailure keepTempFolderOnFailure = new KeepTempFolderOnFailure(temporaryFolder); + + @Test + public void verifyAnnotatedTagMessage() throws IOException, GitAPIException { + + final String testCaseFolder = "1.0.3-annotatedTag"; + File origin = initUpstreamRepo(testCaseFolder); + + final File working = temporaryFolder.newFolder("working"); + Git git = Git.cloneRepository().setURI(origin.getAbsolutePath()) + .setDirectory(working).call(); + + copyResourceFile(working, testCaseFolder, "CHANGELOG.md"); + + gradleRunner().withProjectDir(working)/*.withDebug(true)*/ + .withArguments("changelogPush").build(); + + assertEquals("Version is 1.0.3, here are the changes:" + + "\n\n### Fixed\n" + + "- this should be in tag message\n", + annotatedTagMessage(git, "release/1.0.3")); + } + + private String annotatedTagMessage(Git localGit, final String tagName) throws IOException { + try (RevWalk walk = new RevWalk(localGit.getRepository())) { + return walk.parseTag( + localGit.getRepository().findRef(tagName).getObjectId()) + .getFullMessage(); + } + } + + private File initUpstreamRepo(String testCaseFolder) throws IOException, GitAPIException { + File origin = temporaryFolder.newFolder("origin"); + Git git = Git.init().setDirectory(origin).call(); + copyResourceFile(origin, "settings.gradle"); + copyResourceFile(origin, testCaseFolder, "build.gradle"); + git.add().addFilepattern(".").call(); + git.commit() + .setMessage("Commit all changes including additions") + .call(); + return origin; + } + + private void copyResourceFile(File working, String testCaseFolder, String fileName) throws IOException { + Files.copy(Paths.get("src/test/resources", testCaseFolder, fileName), working.toPath().resolve(fileName)); + } + + private void copyResourceFile(File working, String fileName) throws IOException { + Files.copy(Paths.get("src/test/resources", fileName), working.toPath().resolve(fileName)); + } + + static class KeepTempFolderOnFailure extends TestWatcher { + private final DeleteOnSuccessTemporaryFolder folder; + + KeepTempFolderOnFailure(DeleteOnSuccessTemporaryFolder folder) { + this.folder = folder; + } + + @Override + protected void failed(Throwable e, Description description) { + folder.disableDeletion(); + } + } + + static class DeleteOnSuccessTemporaryFolder extends TemporaryFolder { + + boolean canDelete = true; + + public DeleteOnSuccessTemporaryFolder(File file) { + super(file); + } + + @Override + protected void after() { + if (canDelete) + super.after(); + } + + public void disableDeletion() { + canDelete = false; + } + } +} diff --git a/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/CHANGELOG.md b/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/CHANGELOG.md new file mode 100644 index 0000000..bbf0bf1 --- /dev/null +++ b/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Fixed +- this should be in tag message + +## [1.0.2] - 2021-04-23 + +Initial release. \ No newline at end of file diff --git a/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/build.gradle b/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/build.gradle new file mode 100644 index 0000000..d858ef6 --- /dev/null +++ b/spotless-changelog-plugin-gradle/src/test/resources/1.0.3-annotatedTag/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'com.diffplug.spotless-changelog' +} + +spotlessChangelog { + branch 'master' + tagMessage 'Version is {{version}}, here are the changes:{{changes}}' +} \ No newline at end of file diff --git a/spotless-changelog-plugin-gradle/src/test/resources/settings.gradle b/spotless-changelog-plugin-gradle/src/test/resources/settings.gradle new file mode 100644 index 0000000..e69de29