diff --git a/CHANGELOG.md b/CHANGELOG.md index 697ad41..5bcc185 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Add versioning extension point [#235](https://github.com/nbbrd/heylogs/issues/235) - Add forge extension point [#236](https://github.com/nbbrd/heylogs/issues/236) - Add basic rule check before scanning and extracting [#243](https://github.com/nbbrd/heylogs/issues/243) +- Add scan for forge [#227](https://github.com/nbbrd/heylogs/issues/227) ### Changed diff --git a/heylogs-api/src/main/java/internal/heylogs/StylishFormat.java b/heylogs-api/src/main/java/internal/heylogs/StylishFormat.java index d3c2023..fadd0c0 100644 --- a/heylogs-api/src/main/java/internal/heylogs/StylishFormat.java +++ b/heylogs-api/src/main/java/internal/heylogs/StylishFormat.java @@ -10,6 +10,7 @@ import nbbrd.service.ServiceProvider; import java.io.IOException; +import java.net.URL; import java.util.*; import java.util.function.Function; @@ -116,6 +117,8 @@ private List getStatusBody(Summary summary) { ? "Not compatible with known versioning" : "Compatible with " + String.join(", ", summary.getCompatibilities())); } + result.add("Forged with " + Optional.ofNullable(summary.getForgeName()).orElse("unknown forge") + + " at " + Optional.ofNullable(summary.getForgeURL()).map(URL::getHost).orElse("unknown host")); result.add(summary.getUnreleasedChanges() > 0 ? ("Has " + summary.getUnreleasedChanges() + " unreleased changes") : "Has no unreleased changes"); } else { result.add("Invalid changelog"); diff --git a/heylogs-api/src/main/java/nbbrd/heylogs/Heylogs.java b/heylogs-api/src/main/java/nbbrd/heylogs/Heylogs.java index 8d4802b..6cd2fb9 100644 --- a/heylogs-api/src/main/java/nbbrd/heylogs/Heylogs.java +++ b/heylogs-api/src/main/java/nbbrd/heylogs/Heylogs.java @@ -1,10 +1,13 @@ package nbbrd.heylogs; import com.vladsch.flexmark.ast.Heading; +import com.vladsch.flexmark.ast.util.ReferenceRepository; +import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Document; import com.vladsch.flexmark.util.ast.Node; import internal.heylogs.ChangelogNodes; import internal.heylogs.GuidingPrinciples; +import internal.heylogs.URLExtractor; import lombok.NonNull; import nbbrd.design.MightBePromoted; import nbbrd.design.StaticFactoryMethod; @@ -14,6 +17,7 @@ import java.io.IOException; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; import static java.util.Arrays.asList; @@ -137,6 +141,9 @@ public void formatResources(@NonNull String formatId, @NonNull Appendable append .map(o -> o.values().stream().mapToLong(List::size).sum()) .orElse(0L); + Optional forgeURL = getLatestVersionURL(document); + Optional forgeName = forgeURL.flatMap(this::getForgeName); + return Summary .builder() .valid(true) @@ -144,9 +151,27 @@ public void formatResources(@NonNull String formatId, @NonNull Appendable append .timeRange(releases.stream().map(Version::getDate).collect(toTimeRange()).orElse(TimeRange.ALL)) .compatibilities(getCompatibilities(releases)) .unreleasedChanges((int) unreleasedChanges) + .forgeName(forgeName.orElse(null)) + .forgeURL(forgeURL.map(URLExtractor::urlOf).map(URLExtractor::baseOf).orElse(null)) .build(); } + private Optional getForgeName(String url) { + return forges.stream().filter(forge -> forge.isCompareLink(url)).map(Forge::getForgeName).findFirst(); + } + + private static Optional getLatestVersionURL(Node document) { + return Nodes.of(Heading.class) + .descendants(document) + .filter(Version::isVersionLevel) + .map(heading -> { + ReferenceRepository repository = Parser.REFERENCES.get(heading.getDocument()); + String normalizeRef = repository.normalizeKey(Version.parse(heading).getRef()); + return Objects.requireNonNull(repository.get(normalizeRef)).getUrl().toString(); + }) + .findFirst(); + } + private List getCompatibilities(List releases) { return versionings.stream() .filter(versioning -> releases.stream().allMatch(release -> versioning.isValidVersion(release.getRef()))) diff --git a/heylogs-api/src/main/java/nbbrd/heylogs/Summary.java b/heylogs-api/src/main/java/nbbrd/heylogs/Summary.java index cc9be28..e36b5a2 100644 --- a/heylogs-api/src/main/java/nbbrd/heylogs/Summary.java +++ b/heylogs-api/src/main/java/nbbrd/heylogs/Summary.java @@ -1,5 +1,6 @@ package nbbrd.heylogs; +import java.net.URL; import java.util.List; @lombok.Value @@ -19,4 +20,10 @@ public class Summary { @lombok.Builder.Default int unreleasedChanges = 0; + + @lombok.Builder.Default + String forgeName = null; + + @lombok.Builder.Default + URL forgeURL = null; } diff --git a/heylogs-api/src/test/java/internal/heylogs/StylishFormatTest.java b/heylogs-api/src/test/java/internal/heylogs/StylishFormatTest.java index f0e9d8c..fb5e7a6 100644 --- a/heylogs-api/src/test/java/internal/heylogs/StylishFormatTest.java +++ b/heylogs-api/src/test/java/internal/heylogs/StylishFormatTest.java @@ -76,11 +76,12 @@ public void testFormatStatus() { assertThat(writing(appendable -> x.formatStatus(appendable, singletonList(SCAN2)))) .isEqualToNormalizingNewlines( "source2\n" - + " Valid changelog \n" - + " Found 3 releases \n" - + " Ranging from 2010-01-01 to 2011-01-01\n" - + " Compatible with Strange Versioning \n" - + " Has 3 unreleased changes \n" + + " Valid changelog \n" + + " Found 3 releases \n" + + " Ranging from 2010-01-01 to 2011-01-01 \n" + + " Compatible with Strange Versioning \n" + + " Forged with unknown forge at unknown host\n" + + " Has 3 unreleased changes \n" ); } diff --git a/heylogs-api/src/test/java/nbbrd/heylogs/HeylogsTest.java b/heylogs-api/src/test/java/nbbrd/heylogs/HeylogsTest.java index ca7007c..6d57cae 100644 --- a/heylogs-api/src/test/java/nbbrd/heylogs/HeylogsTest.java +++ b/heylogs-api/src/test/java/nbbrd/heylogs/HeylogsTest.java @@ -11,6 +11,7 @@ import java.util.List; import static _test.Sample.using; +import static internal.heylogs.URLExtractor.urlOf; import static java.util.Collections.singletonList; import static nbbrd.heylogs.Heylogs.FIRST_FORMAT_AVAILABLE; import static nbbrd.heylogs.spi.RuleSeverity.ERROR; @@ -91,6 +92,8 @@ void testScan() { .timeRange(TimeRange.of(LocalDate.of(2014, 5, 31), LocalDate.of(2019, 2, 15))) .compatibility("Semantic Versioning") .unreleasedChanges(2) + .forgeName("GitHub") + .forgeURL(urlOf("https://github.com")) .build() ); @@ -101,6 +104,8 @@ void testScan() { .releaseCount(2) .timeRange(TimeRange.of(LocalDate.of(2019, 2, 15), LocalDate.of(2019, 2, 15))) .unreleasedChanges(0) + .forgeName("GitHub") + .forgeURL(urlOf("https://github.com")) .build() ); @@ -129,6 +134,8 @@ public void testFormatStatus() throws IOException { .timeRange(TimeRange.of(LocalDate.of(2019, 2, 15), LocalDate.of(2019, 2, 15))) .compatibility("Semantic Versioning") .unreleasedChanges(3) + .forgeName("GitStuff") + .forgeURL(urlOf("https://localhost:8080/hello")) .build()) .build()); @@ -147,6 +154,7 @@ public void testFormatStatus() throws IOException { " Found 1 releases \n" + " Ranging from 2019-02-15 to 2019-02-15\n" + " Compatible with Semantic Versioning \n" + + " Forged with GitStuff at localhost \n" + " Has 3 unreleased changes \n" ); }