diff --git a/gradle/changelog/contributor.yaml b/gradle/changelog/contributor.yaml new file mode 100644 index 0000000000..575b50c448 --- /dev/null +++ b/gradle/changelog/contributor.yaml @@ -0,0 +1,2 @@ +- type: added + description: Enhanced contributor api ([#1966](https://github.com/scm-manager/scm-manager/pull/1966)) diff --git a/scm-core/src/main/java/sonia/scm/repository/Contributor.java b/scm-core/src/main/java/sonia/scm/repository/Contributor.java index 9616695638..f1e888f5f7 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Contributor.java +++ b/scm-core/src/main/java/sonia/scm/repository/Contributor.java @@ -24,12 +24,46 @@ package sonia.scm.repository; +import com.google.common.collect.ImmutableSet; import lombok.Value; import java.io.Serializable; +import java.util.Collection; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.Optional.empty; +import static java.util.Optional.of; @Value public class Contributor implements Serializable { + + public static final String CO_AUTHORED_BY = "Co-authored-by"; + public static final String COMMITTED_BY = "Committed-by"; + public static final String REVIEWED_BY = "Reviewed-by"; + public static final String SIGNED_OFF_BY = "Signed-off-by"; + + private static final Collection SUPPORTED_CONTRIBUTOR_TYPES = ImmutableSet.of(CO_AUTHORED_BY, REVIEWED_BY, SIGNED_OFF_BY, COMMITTED_BY); + private static final Pattern CONTRIBUTOR_PATTERN = Pattern.compile("^([\\w-]*):\\W*(.*)\\W+<(.*)>\\W*$"); + private String type; private Person person; + + static Optional fromCommitLine(String line) { + Matcher matcher = CONTRIBUTOR_PATTERN.matcher(line); + if (matcher.matches()) { + String type = matcher.group(1); + String name = matcher.group(2); + String mail = matcher.group(3); + if (SUPPORTED_CONTRIBUTOR_TYPES.contains(type)) { + return of(new Contributor(type, new Person(name, mail))); + } + } + return empty(); + } + + public String toCommitLine() { + return String.format("%s: %s <%s>", type, person.getName(), person.getMail()); + } } diff --git a/scm-core/src/test/java/sonia/scm/repository/ContributorTest.java b/scm-core/src/test/java/sonia/scm/repository/ContributorTest.java new file mode 100644 index 0000000000..48e17aa872 --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/repository/ContributorTest.java @@ -0,0 +1,69 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.repository; + +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +class ContributorTest { + + @Test + void shouldParseCoAuthoredBy() { + Optional contributor = Contributor.fromCommitLine("Co-authored-by: Arthur Dent "); + + assertThat(contributor).get().isEqualTo(new Contributor(Contributor.CO_AUTHORED_BY, new Person("Arthur Dent", "dent@hitchhiker.org"))); + } + + @Test + void shouldParseCommittedBy() { + Optional contributor = Contributor.fromCommitLine("Committed-by: Arthur Dent "); + + assertThat(contributor).get().isEqualTo(new Contributor(Contributor.COMMITTED_BY, new Person("Arthur Dent", "dent@hitchhiker.org"))); + } + + @Test + void shouldParseReviewedBy() { + Optional contributor = Contributor.fromCommitLine("Reviewed-by: Arthur Dent "); + + assertThat(contributor).get().isEqualTo(new Contributor(Contributor.REVIEWED_BY, new Person("Arthur Dent", "dent@hitchhiker.org"))); + } + + @Test + void shouldParseSignedOffBy() { + Optional contributor = Contributor.fromCommitLine("Signed-off-by: Arthur Dent "); + + assertThat(contributor).get().isEqualTo(new Contributor(Contributor.SIGNED_OFF_BY, new Person("Arthur Dent", "dent@hitchhiker.org"))); + } + + @Test + void shouldRenderCommitLine() { + String commitLine = new Contributor(Contributor.CO_AUTHORED_BY, new Person("Arthur Dent", "dent@hitchhiker.org")).toCommitLine(); + + assertThat(commitLine).isEqualTo("Co-authored-by: Arthur Dent "); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/repository/ChangesetDescriptionContributorProvider.java b/scm-webapp/src/main/java/sonia/scm/repository/ChangesetDescriptionContributorProvider.java index c1d0a16c22..bf34ba0233 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/ChangesetDescriptionContributorProvider.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/ChangesetDescriptionContributorProvider.java @@ -24,20 +24,14 @@ package sonia.scm.repository; -import com.google.common.collect.ImmutableSet; import sonia.scm.plugin.Extension; -import java.util.Collection; +import java.util.Optional; import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Extension public class ChangesetDescriptionContributorProvider implements ChangesetPreProcessorFactory { - private static final Collection SUPPORTED_CONTRIBUTOR_TYPES = ImmutableSet.of("Co-authored-by", "Reviewed-by", "Signed-off-by", "Committed-by"); - private static final Pattern CONTRIBUTOR_PATTERN = Pattern.compile("^([\\w-]*):\\W*(.*)\\W+<(.*)>\\W*$"); - @Override public ChangesetPreProcessor createPreProcessor(Repository repository) { return new ContributorChangesetPreProcessor(); @@ -82,17 +76,13 @@ public class ChangesetDescriptionContributorProvider implements ChangesetPreProc } private boolean checkForContributor(String line) { - Matcher matcher = CONTRIBUTOR_PATTERN.matcher(line); - if (matcher.matches()) { - String type = matcher.group(1); - String name = matcher.group(2); - String mail = matcher.group(3); - if (SUPPORTED_CONTRIBUTOR_TYPES.contains(type)) { - createContributor(type, name, mail); - return true; - } + Optional contributor = Contributor.fromCommitLine(line); + if (contributor.isPresent()) { + changeset.addContributor(contributor.get()); + return true; + } else{ + return false; } - return false; } private void handleEmptyLine(Scanner scanner, String line) { @@ -106,9 +96,5 @@ public class ChangesetDescriptionContributorProvider implements ChangesetPreProc newDescription.append('\n'); } } - - private void createContributor(String type, String name, String mail) { - changeset.addContributor(new Contributor(type, new Person(name, mail))); - } } }