Skip to content

Commit

Permalink
Add forge extension point
Browse files Browse the repository at this point in the history
  • Loading branch information
charphi committed Apr 5, 2024
1 parent ea55fc5 commit 7587e5b
Show file tree
Hide file tree
Showing 18 changed files with 249 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Add error severity to failures [#17](https://github.com/nbbrd/heylogs/issues/17)
- Add json formatting [#118](https://github.com/nbbrd/heylogs/issues/118)
- Add versioning extension point [#235](https://github.com/nbbrd/heylogs/issues/235)
- Add forge extension point [#236](https://github.com/nbbrd/heylogs/issues/236)

### Changed

Expand Down
8 changes: 0 additions & 8 deletions heylogs-api/src/main/java/internal/heylogs/GitHostRef.java

This file was deleted.

27 changes: 27 additions & 0 deletions heylogs-api/src/main/java/internal/heylogs/github/GitHub.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package internal.heylogs.github;

import lombok.NonNull;
import nbbrd.design.DirectImpl;
import nbbrd.heylogs.spi.Forge;
import nbbrd.io.text.Parser;
import nbbrd.service.ServiceProvider;

@DirectImpl
@ServiceProvider
public final class GitHub implements Forge {

@Override
public @NonNull String getForgeId() {
return "github";
}

@Override
public @NonNull String getForgeName() {
return "GitHub";
}

@Override
public boolean isCompareLink(@NonNull CharSequence text) {
return Parser.of(GitHubCompareLink::parse).parseValue(text).isPresent();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostLink;
import nbbrd.heylogs.spi.ForgeLink;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -16,7 +16,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubCommitSHALink implements GitHostLink {
class GitHubCommitSHALink implements ForgeLink {

@StaticFactoryMethod
public static @NonNull GitHubCommitSHALink parse(@NonNull CharSequence text) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostRef;
import nbbrd.heylogs.spi.ForgeRef;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -13,7 +13,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubCommitSHARef implements GitHostRef<GitHubCommitSHALink> {
class GitHubCommitSHARef implements ForgeRef<GitHubCommitSHALink> {

public enum Type {HASH, OWNER_HASH, OWNER_REPO_HASH}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package internal.heylogs.github;

import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
import nbbrd.design.StaticFactoryMethod;
import nbbrd.heylogs.spi.ForgeLink;
import nbbrd.io.http.URLQueryBuilder;

import java.net.URL;
import java.util.regex.Pattern;

import static internal.heylogs.URLExtractor.*;

// https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-comparing-branches-in-pull-requests#three-dot-and-two-dot-git-diff-comparisons
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubCompareLink implements ForgeLink {

@StaticFactoryMethod
public static @NonNull GitHubCompareLink parse(@NonNull CharSequence text) {
return parseURL(urlOf(text));
}

private static @NonNull GitHubCompareLink parseURL(@NonNull URL url) {
String[] pathArray = getPathArray(url);

checkPathLength(pathArray, 4);
checkPathItem(pathArray, 0, OWNER);
checkPathItem(pathArray, 1, REPO);
checkPathItem(pathArray, 2, "compare");
checkPathItem(pathArray, 3, OID);

return new GitHubCompareLink(baseOf(url), pathArray[0], pathArray[1], pathArray[2], pathArray[3]);
}

@NonNull URL base;
@NonNull String owner;
@NonNull String repo;
@NonNull String type;
@NonNull String oid;

@Override
public String toString() {
return URLQueryBuilder.of(base).path(owner).path(repo).path(type).path(oid).toString();
}

private static final Pattern OWNER = Pattern.compile("[a-z\\d](?:[a-z\\d]|-(?=[a-z\\d])){0,38}");
private static final Pattern REPO = Pattern.compile("[a-z\\d._-]{1,100}");
private static final Pattern OID = Pattern.compile(".+\\.{3}.+");
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostLink;
import nbbrd.heylogs.spi.ForgeLink;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -17,7 +17,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubIssueLink implements GitHostLink {
class GitHubIssueLink implements ForgeLink {

public static final String ISSUES_TYPE = "issues";
public static final String PULL_REQUEST_TYPE = "pull";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostRef;
import nbbrd.heylogs.spi.ForgeRef;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -15,7 +15,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubIssueRef implements GitHostRef<GitHubIssueLink> {
class GitHubIssueRef implements ForgeRef<GitHubIssueLink> {

public enum Type {NUMBER, OWNER_REPO_NUMBER}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostLink;
import nbbrd.heylogs.spi.ForgeLink;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -17,7 +17,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubMentionLink implements GitHostLink {
class GitHubMentionLink implements ForgeLink {

@StaticFactoryMethod
public static @NonNull GitHubMentionLink parse(@NonNull CharSequence text) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package internal.heylogs.github;

import internal.heylogs.GitHostRef;
import nbbrd.heylogs.spi.ForgeRef;
import lombok.AccessLevel;
import lombok.NonNull;
import nbbrd.design.RepresentableAsString;
Expand All @@ -14,7 +14,7 @@
@RepresentableAsString
@lombok.Value
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
class GitHubMentionRef implements GitHostRef<GitHubMentionLink> {
class GitHubMentionRef implements ForgeRef<GitHubMentionLink> {

public enum Type {USER, TEAM}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package internal.heylogs.github;

import internal.heylogs.GitHostLink;
import internal.heylogs.GitHostRef;
import internal.heylogs.GitHostRefRuleSupport;
import nbbrd.heylogs.spi.ForgeLink;
import nbbrd.heylogs.spi.ForgeRef;
import nbbrd.heylogs.spi.ForgeRefRuleSupport;
import lombok.NonNull;
import nbbrd.design.DirectImpl;
import nbbrd.design.VisibleForTesting;
Expand All @@ -22,7 +22,7 @@ public final class GitHubRules implements RuleBatch {
}

@VisibleForTesting
static final Rule GITHUB_ISSUE_REF = GitHostRefRuleSupport
static final Rule GITHUB_ISSUE_REF = ForgeRefRuleSupport
.builder(GitHubIssueLink::parse, GitHubIssueRef::parse)
.id("github-issue-ref")
.name("GitHub issue ref")
Expand All @@ -32,7 +32,7 @@ public final class GitHubRules implements RuleBatch {
.build();

@VisibleForTesting
static final Rule GITHUB_PULL_REQUEST_REF = GitHostRefRuleSupport
static final Rule GITHUB_PULL_REQUEST_REF = ForgeRefRuleSupport
.builder(GitHubIssueLink::parse, GitHubIssueRef::parse)
.id("github-pull-request-ref")
.name("GitHub pull request ref")
Expand All @@ -42,7 +42,7 @@ public final class GitHubRules implements RuleBatch {
.build();

@VisibleForTesting
static final Rule GITHUB_MENTION_REF = GitHostRefRuleSupport
static final Rule GITHUB_MENTION_REF = ForgeRefRuleSupport
.builder(GitHubMentionLink::parse, GitHubMentionRef::parse)
.id("github-mention-ref")
.name("GitHub mention ref")
Expand All @@ -52,7 +52,7 @@ public final class GitHubRules implements RuleBatch {
.build();

@VisibleForTesting
static final Rule GITHUB_COMMIT_SHA_REF = GitHostRefRuleSupport
static final Rule GITHUB_COMMIT_SHA_REF = ForgeRefRuleSupport
.builder(GitHubCommitSHALink::parse, GitHubCommitSHARef::parse)
.id("github-commit-sha-ref")
.name("GitHub commit SHA ref")
Expand All @@ -61,7 +61,7 @@ public final class GitHubRules implements RuleBatch {
.message((expected, found) -> messageOf("GitHub commit SHA ref", GitHubCommitSHARef.of(expected, found.getType()), found))
.build();

private static boolean isGitHubHost(GitHostLink expected) {
private static boolean isGitHubHost(ForgeLink expected) {
return expected.getBase().getHost().equals("github.com");
}

Expand All @@ -73,7 +73,7 @@ private static boolean isPullRequest(GitHubIssueLink expected) {
return expected.getType().equals(GitHubIssueLink.PULL_REQUEST_TYPE);
}

private static String messageOf(String name, GitHostRef<?> expected, GitHostRef<?> found) {
private static String messageOf(String name, ForgeRef<?> expected, ForgeRef<?> found) {
return "Expecting " + name + " " + expected + ", found " + found;
}
}
18 changes: 17 additions & 1 deletion heylogs-api/src/main/java/nbbrd/heylogs/Heylogs.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class Heylogs {
.rules(RuleLoader.load())
.formats(FormatLoader.load())
.versionings(VersioningLoader.load())
.forges(ForgeLoader.load())
.build();
}

Expand All @@ -46,6 +47,10 @@ public class Heylogs {
@lombok.Singular
List<Versioning> versionings;

@NonNull
@lombok.Singular
List<Forge> forges;

public @NonNull List<Problem> validate(@NonNull Document doc) {
return concat(Stream.of(doc), Nodes.of(Node.class).descendants(doc))
.flatMap(node -> rules.stream().map(rule -> getProblemOrNull(node, rule)).filter(Objects::nonNull))
Expand All @@ -56,7 +61,8 @@ public class Heylogs {
return concat(
rules.stream().map(Heylogs::asResource),
formats.stream().map(Heylogs::asResource),
versionings.stream().map(Heylogs::asResource)
versionings.stream().map(Heylogs::asResource),
forges.stream().map(Heylogs::asResource)
)
.sorted(comparing(Resource::getType).thenComparing(Resource::getCategory).thenComparing(Resource::getId))
.collect(toList());
Expand Down Expand Up @@ -92,6 +98,16 @@ private static Resource asResource(Versioning versioning) {
.build();
}

private static Resource asResource(Forge forge) {
return Resource
.builder()
.type("forge")
.category("main")
.id(forge.getForgeId())
.name(forge.getForgeName())
.build();
}

private static Problem getProblemOrNull(Node node, Rule rule) {
RuleIssue ruleIssueOrNull = rule.getRuleIssueOrNull(node);
return ruleIssueOrNull != null ? Problem.builder().rule(rule).issue(ruleIssueOrNull).build() : null;
Expand Down
19 changes: 19 additions & 0 deletions heylogs-api/src/main/java/nbbrd/heylogs/spi/Forge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package nbbrd.heylogs.spi;

import lombok.NonNull;
import nbbrd.service.Quantifier;
import nbbrd.service.ServiceDefinition;
import nbbrd.service.ServiceId;

@ServiceDefinition(
quantifier = Quantifier.MULTIPLE
)
public interface Forge {

@ServiceId(pattern = ServiceId.KEBAB_CASE)
@NonNull String getForgeId();

@NonNull String getForgeName();

boolean isCompareLink(@NonNull CharSequence text);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package internal.heylogs;
package nbbrd.heylogs.spi;

import lombok.NonNull;

import java.net.URL;

public interface GitHostLink {
public interface ForgeLink {

@NonNull URL getBase();
}
8 changes: 8 additions & 0 deletions heylogs-api/src/main/java/nbbrd/heylogs/spi/ForgeRef.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package nbbrd.heylogs.spi;

import lombok.NonNull;

public interface ForgeRef<T extends ForgeLink> {

boolean isCompatibleWith(@NonNull T link);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package internal.heylogs;
package nbbrd.heylogs.spi;

import com.vladsch.flexmark.ast.Link;
import com.vladsch.flexmark.util.ast.Node;
import lombok.NonNull;
import nbbrd.heylogs.spi.Rule;
import nbbrd.heylogs.spi.RuleIssue;
import nbbrd.heylogs.spi.RuleSeverity;
import nbbrd.io.text.Parser;
import org.checkerframework.checker.nullness.qual.Nullable;

Expand All @@ -15,7 +12,7 @@
import java.util.function.Predicate;

@lombok.Builder(toBuilder = true)
public final class GitHostRefRuleSupport<L extends GitHostLink, R extends GitHostRef<L>> implements Rule {
public final class ForgeRefRuleSupport<L extends ForgeLink, R extends ForgeRef<L>> implements Rule {

private final @NonNull String id;

Expand Down Expand Up @@ -83,11 +80,11 @@ public boolean isRuleAvailable() {
return NO_RULE_ISSUE;
}

private static <T extends GitHostLink> boolean isNotCompatibleRef(GitHostRef<T> found, T expected) {
private static <T extends ForgeLink> boolean isNotCompatibleRef(ForgeRef<T> found, T expected) {
return found != null && !found.isCompatibleWith(expected);
}

public static <L extends GitHostLink, R extends GitHostRef<L>> @NonNull Builder<L, R> builder(
public static <L extends ForgeLink, R extends ForgeRef<L>> @NonNull Builder<L, R> builder(
Function<? super CharSequence, L> linkParser,
Function<? super CharSequence, R> refParser
) {
Expand Down
Loading

0 comments on commit 7587e5b

Please sign in to comment.