use of org.jreleaser.model.Changelog in project jreleaser by jreleaser.
the class ChangelogProvider method resolveChangelog.
private static String resolveChangelog(JReleaserContext context) throws IOException {
Changelog changelog = context.getModel().getRelease().getGitService().getChangelog();
String externalChangelog = changelog.getExternal();
if (isNotBlank(externalChangelog)) {
Path externalChangelogPath = context.getBasedir().resolve(Paths.get(externalChangelog));
File externalChangelogFile = externalChangelogPath.toFile();
if (!externalChangelogFile.exists()) {
throw new IllegalStateException(RB.$("ERROR_changelog_not_exist", context.getBasedir().relativize(externalChangelogPath)));
}
context.getLogger().info(RB.$("changelog.generator.read"), context.getBasedir().relativize(externalChangelogPath));
return new String(Files.readAllBytes(externalChangelogPath));
}
return ChangelogGenerator.generate(context);
}
use of org.jreleaser.model.Changelog in project jreleaser by jreleaser.
the class GitServiceValidator method validateChangelog.
private static void validateChangelog(JReleaserContext context, GitService service, Errors errors) {
Changelog changelog = service.getChangelog();
if (isNotBlank(changelog.getExternal())) {
changelog.setFormatted(Active.NEVER);
}
if (!changelog.resolveFormatted(context.getModel().getProject()))
return;
if (isBlank(changelog.getFormat())) {
changelog.setFormat("- {{commitShortHash}} {{commitTitle}} ({{commitAuthor}})");
}
if (isBlank(changelog.getContent()) && isBlank(changelog.getContentTemplate())) {
if (Files.exists(context.getBasedir().resolve(DEFAULT_CHANGELOG_TPL))) {
changelog.setContentTemplate(DEFAULT_CHANGELOG_TPL);
} else {
changelog.setContent(lineSeparator() + "## Changelog" + lineSeparator() + lineSeparator() + "{{changelogChanges}}" + lineSeparator() + " {{changelogContributors}}");
}
}
if (isNotBlank(changelog.getContentTemplate()) && !Files.exists(context.getBasedir().resolve(changelog.getContentTemplate().trim()))) {
errors.configuration(RB.$("validation_directory_not_exist", "changelog.contentTemplate", changelog.getContentTemplate()));
}
if (isNotBlank(changelog.getPreset())) {
loadPreset(context, changelog, errors);
}
if (changelog.getCategories().isEmpty()) {
changelog.getCategories().add(Changelog.Category.of("feature", RB.$("default.category.feature"), "", "feature", "enhancement"));
changelog.getCategories().add(Changelog.Category.of("fix", RB.$("default.category.bug.fix"), "", "bug", "fix"));
} else {
int i = 0;
for (Changelog.Category category : changelog.getCategories()) {
if (isBlank(category.getTitle())) {
errors.configuration(RB.$("validation_is_missing", service.getServiceName() + ".changelog.categories[" + i + "].title"));
}
if (category.getLabels().isEmpty()) {
errors.configuration(RB.$("validation_are_missing", service.getServiceName() + ".changelog.categories[" + i + "].labels"));
}
i++;
}
// validate category.title is unique
Map<String, List<Changelog.Category>> byTitle = changelog.getCategories().stream().collect(groupingBy(Changelog.Category::getTitle));
byTitle.forEach((title, categories) -> {
if (categories.size() > 1) {
errors.configuration(RB.$("validation_changelog_multiple_categories", service.getServiceName(), title));
}
});
}
if (!changelog.getLabelers().isEmpty()) {
int i = 0;
for (Changelog.Labeler labeler : changelog.getLabelers()) {
if (isBlank(labeler.getLabel())) {
errors.configuration(RB.$("validation_is_missing", service.getServiceName() + ".changelog.labelers[" + i + "].label"));
}
if (isBlank(labeler.getTitle()) && isBlank(labeler.getBody())) {
errors.configuration(RB.$("validation_git_required", service.getServiceName() + ".changelog.labelers[" + i + "] title", "body"));
}
i++;
}
}
if (!changelog.getReplacers().isEmpty()) {
int i = 0;
for (Changelog.Replacer replacer : changelog.getReplacers()) {
if (isBlank(replacer.getSearch())) {
errors.configuration(RB.$("validation_is_missing", service.getServiceName() + ".changelog.replacers[" + i + "].search"));
}
if (null == replacer.getReplace()) {
errors.configuration(RB.$("validation_is_missing", service.getServiceName() + ".changelog.replacers[" + i + "].replace"));
}
i++;
}
}
if (!changelog.getContributors().isEnabledSet()) {
changelog.getContributors().setEnabled(true);
}
}
use of org.jreleaser.model.Changelog in project jreleaser by jreleaser.
the class GitServiceValidator method loadPreset.
private static void loadPreset(JReleaserContext context, Changelog changelog, Errors errors) {
try {
String preset = changelog.getPreset().toLowerCase().trim();
String presetFileName = "META-INF/jreleaser/changelog/preset-" + preset + ".yml";
InputStream inputStream = GitServiceValidator.class.getClassLoader().getResourceAsStream(presetFileName);
if (null != inputStream) {
Changelog loaded = JReleaserConfigLoader.load(Changelog.class, presetFileName, inputStream);
Set<Changelog.Labeler> labelersCopy = new TreeSet<>(Changelog.Labeler.ORDER);
labelersCopy.addAll(changelog.getLabelers());
labelersCopy.addAll(loaded.getLabelers());
changelog.setLabelers(labelersCopy);
List<Changelog.Replacer> replacersCopy = new ArrayList<>(changelog.getReplacers());
replacersCopy.addAll(loaded.getReplacers());
changelog.setReplacers(replacersCopy);
Map<String, List<Changelog.Category>> categoriesByKey = changelog.getCategories().stream().collect(groupingBy(Changelog.Category::getKey));
Map<String, List<Changelog.Category>> loadedCategoriesByKey = loaded.getCategories().stream().collect(groupingBy(Changelog.Category::getKey));
categoriesByKey.forEach((categoryKey, categories) -> {
if (loadedCategoriesByKey.containsKey(categoryKey)) {
Changelog.Category loadedCategory = loadedCategoriesByKey.remove(categoryKey).get(0);
Changelog.Category category = categories.get(0);
category.addLabels(loadedCategory.getLabels());
}
});
loadedCategoriesByKey.values().forEach(list -> changelog.getCategories().add(list.get(0)));
// sort categories once again as order might have changed
changelog.setCategories(Changelog.Category.sort(changelog.getCategories()));
changelog.getHide().addCategories(loaded.getHide().getCategories());
changelog.getHide().addContributors(loaded.getHide().getContributors());
} else {
context.getLogger().warn(RB.$("changelog.preset.not.found"), preset);
}
} catch (IOException e) {
context.getLogger().warn(RB.$("ERROR_classpath_template_resolve"));
}
}
use of org.jreleaser.model.Changelog in project jreleaser by jreleaser.
the class ChangelogGenerator method createChangelog.
private String createChangelog(JReleaserContext context) throws IOException {
GitService gitService = context.getModel().getRelease().getGitService();
Changelog changelog = gitService.getChangelog();
String separator = lineSeparator();
if (Gitlab.NAME.equals(gitService.getServiceName())) {
separator += lineSeparator();
}
String commitSeparator = separator;
try {
Git git = GitSdk.of(context).open();
context.getLogger().debug(RB.$("changelog.generator.resolve.commits"));
Iterable<RevCommit> commits = resolveCommits(git, context);
Comparator<RevCommit> revCommitComparator = Comparator.comparing(RevCommit::getCommitTime).reversed();
if (changelog.getSort() == Changelog.Sort.ASC) {
revCommitComparator = Comparator.comparing(RevCommit::getCommitTime);
}
context.getLogger().debug(RB.$("changelog.generator.sort.commits"), changelog.getSort());
if (changelog.resolveFormatted(context.getModel().getProject())) {
return formatChangelog(context, changelog, commits, revCommitComparator, commitSeparator);
}
String commitsUrl = gitService.getResolvedCommitUrl(context.getModel());
return "## Changelog" + lineSeparator() + lineSeparator() + StreamSupport.stream(commits.spliterator(), false).sorted(revCommitComparator).map(commit -> formatCommit(commit, commitsUrl, changelog, commitSeparator)).collect(Collectors.joining(commitSeparator));
} catch (GitAPIException e) {
throw new IOException(e);
}
}
use of org.jreleaser.model.Changelog in project jreleaser by jreleaser.
the class ChangelogGenerator method formatChangelog.
private String formatChangelog(JReleaserContext context, Changelog changelog, Iterable<RevCommit> commits, Comparator<RevCommit> revCommitComparator, String lineSeparator) {
Set<Contributor> contributors = new LinkedHashSet<>();
Map<String, List<Commit>> categories = new LinkedHashMap<>();
StreamSupport.stream(commits.spliterator(), false).sorted(revCommitComparator).map(Commit::of).peek(c -> {
if (!changelog.getContributors().isEnabled())
return;
if (!changelog.getHide().containsContributor(c.author.name)) {
contributors.add(new Contributor(c.author));
}
c.committers.stream().filter(author -> !changelog.getHide().containsContributor(author.name)).forEach(author -> contributors.add(new Contributor(author)));
}).peek(c -> applyLabels(c, changelog.getLabelers())).filter(c -> checkLabels(c, changelog)).forEach(commit -> categories.computeIfAbsent(categorize(commit, changelog), k -> new ArrayList<>()).add(commit));
GitService gitService = context.getModel().getRelease().getGitService();
String commitsUrl = gitService.getResolvedCommitUrl(context.getModel());
StringBuilder changes = new StringBuilder();
for (Changelog.Category category : changelog.getCategories()) {
String categoryKey = category.getKey();
if (!categories.containsKey(categoryKey) || changelog.getHide().containsCategory(categoryKey))
continue;
changes.append("## ").append(category.getTitle()).append(lineSeparator);
final String categoryFormat = resolveCommitFormat(changelog, category);
changes.append(categories.get(categoryKey).stream().map(c -> resolveTemplate(categoryFormat, c.asContext(changelog.isLinks(), commitsUrl))).collect(Collectors.joining(lineSeparator))).append(lineSeparator).append(lineSeparator());
}
if (!changelog.getHide().isUncategorized() && categories.containsKey(UNCATEGORIZED)) {
if (changes.length() > 0) {
changes.append("---").append(lineSeparator);
}
changes.append(categories.get(UNCATEGORIZED).stream().map(c -> resolveTemplate(changelog.getFormat(), c.asContext(changelog.isLinks(), commitsUrl))).collect(Collectors.joining(lineSeparator))).append(lineSeparator).append(lineSeparator());
}
StringBuilder formattedContributors = new StringBuilder();
if (changelog.getContributors().isEnabled() && !contributors.isEmpty()) {
formattedContributors.append("## Contributors").append(lineSeparator).append("We'd like to thank the following people for their contributions:").append(lineSeparator).append(formatContributors(context, changelog, contributors, lineSeparator)).append(lineSeparator);
}
Map<String, Object> props = context.fullProps();
props.put(KEY_CHANGELOG_CHANGES, passThrough(changes.toString()));
props.put(KEY_CHANGELOG_CONTRIBUTORS, passThrough(formattedContributors.toString()));
return applyReplacers(context, changelog, stripMargin(applyTemplate(changelog.getResolvedContentTemplate(context), props)));
}
Aggregations