mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-04 20:45:52 +01:00
rename trailer to contributor
This commit is contained in:
@@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
- Show commit trailers in table on changeset details view ([#1169](https://github.com/scm-manager/scm-manager/pull/1169))
|
||||
- Show commit contributors in table on changeset details view ([#1169](https://github.com/scm-manager/scm-manager/pull/1169))
|
||||
### Fixed
|
||||
- Fixes configuration of jetty listener address with system property `jetty.host` ([#1173](https://github.com/scm-manager/scm-manager/pull/1173), [#1174](https://github.com/scm-manager/scm-manager/pull/1174))
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ChangesetDto extends HalRepresentation {
|
||||
*/
|
||||
private String description;
|
||||
|
||||
private List<TrailerDto> trailers;
|
||||
private List<ContributorDto> contributors;
|
||||
|
||||
public ChangesetDto(Links links, Embedded embedded) {
|
||||
super(links, embedded);
|
||||
|
||||
@@ -31,7 +31,7 @@ import lombok.Setter;
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class TrailerDto {
|
||||
private String trailerType;
|
||||
public class ContributorDto {
|
||||
private String type;
|
||||
private PersonDto person;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public class Changeset extends BasicPropertiesAware implements ModelObject {
|
||||
/**
|
||||
* Trailers for this changeset like reviewers or co-authors
|
||||
*/
|
||||
private Collection<Trailer> trailers;
|
||||
private Collection<Contributor> contributors;
|
||||
|
||||
public Changeset() {}
|
||||
|
||||
@@ -231,8 +231,13 @@ public class Changeset extends BasicPropertiesAware implements ModelObject {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public Collection<Trailer> getTrailers() {
|
||||
return trailers;
|
||||
/**
|
||||
* Returns collection of contributors for this changeset.
|
||||
* @return collection of contributors
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public Collection<Contributor> getContributors() {
|
||||
return contributors;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,22 +315,37 @@ public class Changeset extends BasicPropertiesAware implements ModelObject {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public void setTrailers(Collection<Trailer> trailers) {
|
||||
this.trailers = new ArrayList<>(trailers);
|
||||
/**
|
||||
* Sets the collection of contributors.
|
||||
* @param contributors collection of contributors
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public void setContributors(Collection<Contributor> contributors) {
|
||||
this.contributors = new ArrayList<>(contributors);
|
||||
}
|
||||
|
||||
public void addTrailer(Trailer trailer) {
|
||||
if (trailers == null) {
|
||||
trailers = new ArrayList<>();
|
||||
/**
|
||||
* Adds a contributor to the list of contributors.
|
||||
* @param contributor contributor to add
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public void addContributor(Contributor contributor) {
|
||||
if (contributors == null) {
|
||||
contributors = new ArrayList<>();
|
||||
}
|
||||
trailers.add(trailer);
|
||||
contributors.add(contributor);
|
||||
}
|
||||
|
||||
public void addTrailers(Collection<Trailer> trailers) {
|
||||
if (this.trailers == null) {
|
||||
this.trailers = new ArrayList<>(trailers);
|
||||
/**
|
||||
* Adds all contributors from the given collection to the list of contributors.
|
||||
* @param contributors collection of contributor
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public void addContributors(Collection<Contributor> contributors) {
|
||||
if (this.contributors == null) {
|
||||
this.contributors = new ArrayList<>(contributors);
|
||||
} else {
|
||||
this.trailers.addAll(trailers);
|
||||
this.contributors.addAll(contributors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import lombok.Value;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Value
|
||||
public class Trailer implements Serializable {
|
||||
private String trailerType;
|
||||
public class Contributor implements Serializable {
|
||||
private String type;
|
||||
private Person person;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public class GitChangesetConverter implements Closeable
|
||||
|
||||
Changeset changeset = new Changeset(id, date, author, message);
|
||||
if (!committerIdent.equals(authorIndent)) {
|
||||
changeset.addTrailer(new Trailer("Committed-by", createPersonFor(committerIdent)));
|
||||
changeset.addContributor(new Contributor("Committed-by", createPersonFor(committerIdent)));
|
||||
}
|
||||
|
||||
if (parentList != null)
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -273,7 +272,7 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAppendCommitterAsTrailer() {
|
||||
public void shouldAppendCommitterAsContributor() {
|
||||
LogCommandRequest request = new LogCommandRequest();
|
||||
request.setStartChangeset("fcd0ef1831e4002ac43ea539f4094334c79ea9ec");
|
||||
request.setEndChangeset("fcd0ef1831e4002ac43ea539f4094334c79ea9ec");
|
||||
@@ -281,8 +280,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
||||
ChangesetPagingResult changesets = createCommand().getChangesets(request);
|
||||
Changeset changeset = changesets.getChangesets().get(0);
|
||||
|
||||
assertThat(changeset.getTrailers()).hasSize(1);
|
||||
assertThat(changeset.getTrailers().iterator().next().getPerson())
|
||||
assertThat(changeset.getContributors()).hasSize(1);
|
||||
assertThat(changeset.getContributors().iterator().next().getPerson())
|
||||
.isEqualTo(new Person("Sebastian Sdorra", "s.sdorra@ostfalia.de"));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ const one: Changeset = {
|
||||
date: new Date("2020-06-09T06:34:47Z"),
|
||||
description:
|
||||
"The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive. The craft was stolen by then-President Zaphod Beeblebrox at the official launch of the ship, as he was supposed to be officiating the launch. Later, during the use of the Infinite Improbability Drive, the ship picked up Arthur Dent and Ford Prefect, who were floating unprotected in deep space in the same star sector, having just escaped the destruction of the same planet.\n\n",
|
||||
trailers: [
|
||||
contributors: [
|
||||
{
|
||||
trailerType: "Committed-by",
|
||||
type: "Committed-by",
|
||||
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" }
|
||||
},
|
||||
{ trailerType: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } }
|
||||
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } }
|
||||
],
|
||||
_links: {
|
||||
self: {
|
||||
@@ -85,9 +85,9 @@ const two: Changeset = {
|
||||
author: { mail: "scm-admin@scm-manager.org", name: "SCM Administrator" },
|
||||
date: new Date("2020-06-09T05:39:50Z"),
|
||||
description: 'Change heading to "Heart Of Gold"\n\n',
|
||||
trailers: [
|
||||
contributors: [
|
||||
{
|
||||
trailerType: "Committed-by",
|
||||
type: "Committed-by",
|
||||
person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" }
|
||||
}
|
||||
],
|
||||
@@ -139,7 +139,7 @@ const three: Changeset = {
|
||||
author: { mail: "scm-admin@scm-manager.org", name: "SCM Administrator" },
|
||||
date: new Date("2020-06-09T05:25:16Z"),
|
||||
description: "initialize repository",
|
||||
trailers: [],
|
||||
contributors: [],
|
||||
_links: {
|
||||
self: {
|
||||
href:
|
||||
@@ -170,10 +170,10 @@ const four: Changeset = {
|
||||
author: { mail: "scm-admin@scm-manager.org", name: "SCM Administrator" },
|
||||
date: new Date("2020-06-09T09:23:49Z"),
|
||||
description: "Added design docs\n\n",
|
||||
trailers: [
|
||||
{ trailerType: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } },
|
||||
{ trailerType: "Co-authored-by", person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" } },
|
||||
{ trailerType: "Co-authored-by", person: { mail: "trillian@hitchhiker.cm", name: "Tricia Marie McMillan" } }
|
||||
contributors: [
|
||||
{ type: "Co-authored-by", person: { mail: "ford.prefect@hitchhiker.com", name: "Ford Prefect" } },
|
||||
{ type: "Co-authored-by", person: { mail: "zaphod.beeblebrox@hitchhiker.cm", name: "Zaphod Beeblebrox" } },
|
||||
{ type: "Co-authored-by", person: { mail: "trillian@hitchhiker.cm", name: "Tricia Marie McMillan" } }
|
||||
],
|
||||
_links: {
|
||||
self: {
|
||||
|
||||
@@ -58,28 +58,27 @@ type PersonAvatarProps = {
|
||||
avatar: string;
|
||||
};
|
||||
|
||||
const PersonAvatar: FC<PersonAvatarProps> = ({ person, avatar }) => {
|
||||
const ContributorWithAvatar: FC<PersonAvatarProps> = ({ person, avatar }) => {
|
||||
const [t] = useTranslation("repos");
|
||||
const img = <ContributorAvatar src={avatar} alt={person.name} title={person.name} />;
|
||||
if (person.mail) {
|
||||
return (
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.author.mailto") + " " + person.mail}>
|
||||
{img}
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.contributors.mailto") + " " + person.mail}>
|
||||
<ContributorAvatar src={avatar} alt={person.name} />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return img;
|
||||
return <ContributorAvatar src={avatar} alt={person.name} title={person.name} />;
|
||||
};
|
||||
|
||||
const SinglePerson: FC<PersonProps> = ({ person, displayTextOnly }) => {
|
||||
const SingleContributor: FC<PersonProps> = ({ person, displayTextOnly }) => {
|
||||
const [t] = useTranslation("repos");
|
||||
const avatar = useAvatar(person);
|
||||
if (!displayTextOnly && avatar) {
|
||||
return <PersonAvatar person={person} avatar={avatar} />;
|
||||
return <ContributorWithAvatar person={person} avatar={avatar} />;
|
||||
}
|
||||
if (person.mail) {
|
||||
return (
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.author.mailto") + " " + person.mail}>
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.contributors.mailto") + " " + person.mail}>
|
||||
{person.name}
|
||||
</a>
|
||||
);
|
||||
@@ -93,14 +92,14 @@ type PersonsProps = {
|
||||
displayTextOnly?: boolean;
|
||||
};
|
||||
|
||||
const Persons: FC<PersonsProps> = ({ persons, label, displayTextOnly }) => {
|
||||
const Contributors: FC<PersonsProps> = ({ persons, label, displayTextOnly }) => {
|
||||
const binder = useBinder();
|
||||
|
||||
const [t] = useTranslation("repos");
|
||||
if (persons.length === 1) {
|
||||
return (
|
||||
<>
|
||||
{t(label)} <SinglePerson person={persons[0]} displayTextOnly={displayTextOnly} />
|
||||
{t(label)} <SingleContributor person={persons[0]} displayTextOnly={displayTextOnly} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -112,7 +111,7 @@ const Persons: FC<PersonsProps> = ({ persons, label, displayTextOnly }) => {
|
||||
{t(label)}{" "}
|
||||
<AvatarList>
|
||||
{persons.map(p => (
|
||||
<PersonAvatar key={p.name} person={p} avatar={avatarFactory(p)} />
|
||||
<ContributorWithAvatar key={p.name} person={p} avatar={avatarFactory(p)} />
|
||||
))}
|
||||
</AvatarList>
|
||||
</>
|
||||
@@ -122,7 +121,7 @@ const Persons: FC<PersonsProps> = ({ persons, label, displayTextOnly }) => {
|
||||
<>
|
||||
{t(label)}{" "}
|
||||
<a title={persons.map(person => "- " + person.name).join("\n")}>
|
||||
{t("changesets.authors.more", { count: persons.length })}
|
||||
{t("changeset.contributors.more", { count: persons.length })}
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
@@ -133,32 +132,32 @@ const ChangesetAuthor: FC<Props> = ({ changeset }) => {
|
||||
const binder = useBinder();
|
||||
|
||||
const getCoAuthors = () => {
|
||||
return filterTrailersByType("Co-authored-by");
|
||||
return filterContributorsByType("Co-authored-by");
|
||||
};
|
||||
|
||||
const getCommitters = () => {
|
||||
return filterTrailersByType("Committed-by");
|
||||
return filterContributorsByType("Committed-by");
|
||||
};
|
||||
|
||||
const filterTrailersByType = (trailerType: string) => {
|
||||
return changeset.trailers.filter(p => p.trailerType === trailerType).map(trailer => trailer.person);
|
||||
const filterContributorsByType = (type: string) => {
|
||||
return changeset.contributors.filter(p => p.type === type).map(contributor => contributor.person);
|
||||
};
|
||||
|
||||
const authorLine = [];
|
||||
if (changeset.author) {
|
||||
authorLine.push(
|
||||
<Persons persons={[changeset.author]} label={"changesets.authors.authoredBy"} displayTextOnly={true} />
|
||||
<Contributors persons={[changeset.author]} label={"changeset.contributors.authoredBy"} displayTextOnly={true} />
|
||||
);
|
||||
}
|
||||
|
||||
const commiters = getCommitters();
|
||||
if (commiters.length > 0) {
|
||||
authorLine.push(<Persons persons={commiters} label={"changesets.authors.committedBy"} />);
|
||||
authorLine.push(<Contributors persons={commiters} label={"changeset.contributors.committedBy"} />);
|
||||
}
|
||||
|
||||
const coAuthors = getCoAuthors();
|
||||
if (coAuthors.length > 0) {
|
||||
authorLine.push(<Persons persons={coAuthors} label={"changesets.authors.coAuthoredBy"} />);
|
||||
authorLine.push(<Contributors persons={coAuthors} label={"changeset.contributors.coAuthoredBy"} />);
|
||||
}
|
||||
|
||||
// extensions
|
||||
|
||||
@@ -36,7 +36,7 @@ export type Changeset = Collection & {
|
||||
date: Date;
|
||||
author: Person;
|
||||
description: string;
|
||||
trailers: Trailer[];
|
||||
contributors: Contributor[];
|
||||
_links: Links;
|
||||
_embedded: {
|
||||
tags?: Tag[];
|
||||
@@ -45,9 +45,9 @@ export type Changeset = Collection & {
|
||||
};
|
||||
};
|
||||
|
||||
export type Trailer = {
|
||||
export type Contributor = {
|
||||
person: Person;
|
||||
trailerType: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type ParentChangeset = {
|
||||
|
||||
@@ -34,7 +34,7 @@ export { RepositoryType, RepositoryTypeCollection } from "./RepositoryTypes";
|
||||
|
||||
export { Branch, BranchRequest } from "./Branches";
|
||||
|
||||
export { Changeset, Person, Trailer, ParentChangeset } from "./Changesets";
|
||||
export { Changeset, Person, Contributor, ParentChangeset } from "./Changesets";
|
||||
|
||||
export { Tag } from "./Tags";
|
||||
|
||||
|
||||
@@ -79,8 +79,7 @@
|
||||
"errorSubtitle": "Changesets konnten nicht abgerufen werden",
|
||||
"noChangesets": "Keine Changesets in diesem Branch gefunden. Die Commits könnten gelöscht worden sein.",
|
||||
"branchSelectorLabel": "Branches",
|
||||
"collapseDiffs": "Auf-/Zuklappen",
|
||||
"contributors": "Liste der Mitwirkenden"
|
||||
"collapseDiffs": "Auf-/Zuklappen"
|
||||
},
|
||||
"changeset": {
|
||||
"description": "Beschreibung",
|
||||
@@ -88,15 +87,14 @@
|
||||
"shortSummary": "Committet <0/> <1/>",
|
||||
"tags": "Tags",
|
||||
"diffNotSupported": "Diff des Changesets wird von diesem Repositorytyp nicht unterstützt",
|
||||
"author": {
|
||||
"prefix": "Verfasst von",
|
||||
"contributors": {
|
||||
"mailto": "Mail senden an",
|
||||
"label": "Autor"
|
||||
},
|
||||
"coAuthor": {
|
||||
"prefix": "und",
|
||||
"label": "Co-Autor",
|
||||
"label_plural": "Co-Autoren"
|
||||
"list": "Liste der Mitwirkenden",
|
||||
"authoredBy": "Verfasst von",
|
||||
"committedBy": "Committed von",
|
||||
"coAuthoredBy": "Co-Autoren",
|
||||
"more": "{{count}} mehr",
|
||||
"count": "5 Mitwirkende"
|
||||
},
|
||||
"buttons": {
|
||||
"details": "Details",
|
||||
|
||||
@@ -79,15 +79,7 @@
|
||||
"errorSubtitle": "Could not fetch changesets",
|
||||
"noChangesets": "No changesets found for this branch. The commits could have been removed.",
|
||||
"branchSelectorLabel": "Branches",
|
||||
"collapseDiffs": "Collapse",
|
||||
"contributors": "List of contributors",
|
||||
"authors": {
|
||||
"and": "and",
|
||||
"authoredBy": "Authored by",
|
||||
"committedBy": "committed by",
|
||||
"coAuthoredBy": "co authored by",
|
||||
"more": "{{count}} more"
|
||||
}
|
||||
"collapseDiffs": "Collapse"
|
||||
},
|
||||
"changeset": {
|
||||
"description": "Description",
|
||||
@@ -95,19 +87,18 @@
|
||||
"shortSummary": "Committed <0/> <1/>",
|
||||
"tags": "Tags",
|
||||
"diffNotSupported": "Diff of changesets is not supported by the type of repository",
|
||||
"author": {
|
||||
"prefix": "Authored by",
|
||||
"mailto": "Send mail to",
|
||||
"label": "Author"
|
||||
},
|
||||
"coAuthor": {
|
||||
"prefix": "and",
|
||||
"label": "Co-author",
|
||||
"label_plural": "Co-authors"
|
||||
},
|
||||
"buttons": {
|
||||
"details": "Details",
|
||||
"sources": "Sources"
|
||||
},
|
||||
"contributors": {
|
||||
"mailto": "Send mail to",
|
||||
"list": "List of contributors",
|
||||
"authoredBy": "Authored by",
|
||||
"committedBy": "committed by",
|
||||
"coAuthoredBy": "co authored by",
|
||||
"more": "{{count}} more",
|
||||
"count": "5 Contributors"
|
||||
}
|
||||
},
|
||||
"repositoryForm": {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React, { FC, useState } from "react";
|
||||
import {Trans, useTranslation, WithTranslation, withTranslation} from "react-i18next";
|
||||
import { Trans, useTranslation, WithTranslation, withTranslation } from "react-i18next";
|
||||
import classNames from "classnames";
|
||||
import styled from "styled-components";
|
||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||
@@ -66,7 +66,7 @@ const BottomMarginLevel = styled(Level)`
|
||||
`;
|
||||
|
||||
const countContributors = (changeset: Changeset) => {
|
||||
return changeset.trailers.length + 1;
|
||||
return changeset.contributors.length + 1;
|
||||
};
|
||||
|
||||
const ContributorLine = styled.div`
|
||||
@@ -101,12 +101,12 @@ const ContributorToggleLine = styled.p`
|
||||
|
||||
const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => {
|
||||
const [t] = useTranslation("repos");
|
||||
const [open, setOpen] = useState(true);
|
||||
const [open, setOpen] = useState(false);
|
||||
if (open) {
|
||||
return (
|
||||
<ContributorDetails>
|
||||
<ContributorToggleLine onClick={e => setOpen(!open)}>
|
||||
<Icon name="angle-down" /> {t("changesets.contributors")}
|
||||
<Icon name="angle-down" /> {t("changeset.contributors.list")}
|
||||
</ContributorToggleLine>
|
||||
<ContributorTable changeset={changeset} />
|
||||
</ContributorDetails>
|
||||
@@ -119,7 +119,11 @@ const Contributors: FC<{ changeset: Changeset }> = ({ changeset }) => {
|
||||
<Icon name="angle-right" /> <ChangesetAuthor changeset={changeset} />
|
||||
</ContributorColumn>
|
||||
<CountColumn>
|
||||
(<span className="has-text-link">{countContributors(changeset)} Contributors</span>)
|
||||
(
|
||||
<span className="has-text-link">
|
||||
{t("changeset.contributors.count", { count: countContributors(changeset) })}
|
||||
</span>
|
||||
)
|
||||
</CountColumn>
|
||||
</ContributorLine>
|
||||
</>
|
||||
|
||||
@@ -53,7 +53,7 @@ const Contributor: FC<{ person: Person }> = ({ person }) => {
|
||||
}
|
||||
if (person.mail) {
|
||||
return (
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.author.mailto") + " " + person.mail}>
|
||||
<a href={"mailto:" + person.mail} title={t("changeset.contributors.mailto") + " " + person.mail}>
|
||||
{prefix}
|
||||
{person.name}
|
||||
</a>
|
||||
@@ -65,39 +65,39 @@ const Contributor: FC<{ person: Person }> = ({ person }) => {
|
||||
const ContributorTable: FC<Props> = ({ changeset }) => {
|
||||
const [t] = useTranslation("plugins");
|
||||
|
||||
const collectAvailableTrailerTypes = () => {
|
||||
const collectAvailableContributorTypes = () => {
|
||||
// @ts-ignore
|
||||
return [...new Set(changeset.trailers.map(trailer => trailer.trailerType))];
|
||||
return [...new Set(changeset.contributors.map(contributor => contributor.type))];
|
||||
};
|
||||
|
||||
const getPersonsByTrailersType = (type: string) => {
|
||||
return changeset.trailers?.filter(trailer => trailer.trailerType === type).map(t => t.person);
|
||||
const getPersonsByContributorType = (type: string) => {
|
||||
return changeset.contributors?.filter(contributor => contributor.type === type).map(t => t.person);
|
||||
};
|
||||
|
||||
const getTrailersByType = () => {
|
||||
const availableTrailerTypes: string[] = collectAvailableTrailerTypes();
|
||||
const getContributorsByType = () => {
|
||||
const availableContributorTypes: string[] = collectAvailableContributorTypes();
|
||||
|
||||
const personsByTrailerType = [];
|
||||
for (const type of availableTrailerTypes) {
|
||||
personsByTrailerType.push({ type, persons: getPersonsByTrailersType(type) });
|
||||
const personsByContributorType = [];
|
||||
for (const type of availableContributorTypes) {
|
||||
personsByContributorType.push({ type, persons: getPersonsByContributorType(type) });
|
||||
}
|
||||
return personsByTrailerType;
|
||||
return personsByContributorType;
|
||||
};
|
||||
|
||||
return (
|
||||
<table>
|
||||
<tr>
|
||||
<SizedTd>{t("changeset.trailer.type.author") + ":"}</SizedTd>
|
||||
<SizedTd>{t("changeset.contributor.type.author") + ":"}</SizedTd>
|
||||
<td>
|
||||
<Contributor person={changeset.author} />
|
||||
</td>
|
||||
</tr>
|
||||
{getTrailersByType().map(trailer => (
|
||||
<tr key={trailer.type}>
|
||||
<SizedTd>{t("changeset.trailer.type." + trailer.type) + ":"}</SizedTd>
|
||||
{getContributorsByType().map(contributor => (
|
||||
<tr key={contributor.type}>
|
||||
<SizedTd>{t("changeset.contributor.type." + contributor.type) + ":"}</SizedTd>
|
||||
<td className="is-ellipsis-overflow is-marginless">
|
||||
<CommaSeparatedList>
|
||||
{trailer.persons.map(person => (
|
||||
{contributor.persons.map(person => (
|
||||
<Contributor key={person.name} person={person} />
|
||||
))}
|
||||
</CommaSeparatedList>
|
||||
|
||||
@@ -26,17 +26,15 @@ package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.Embedded;
|
||||
import de.otto.edison.hal.Links;
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.ObjectFactory;
|
||||
import sonia.scm.repository.Branch;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.Person;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.Tag;
|
||||
import sonia.scm.repository.Trailer;
|
||||
import sonia.scm.repository.Contributor;
|
||||
import sonia.scm.repository.api.Command;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
@@ -44,7 +42,6 @@ import sonia.scm.web.EdisonHalAppender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -70,7 +67,7 @@ public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMa
|
||||
@Inject
|
||||
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
|
||||
|
||||
abstract TrailerDto map(Trailer trailer);
|
||||
abstract ContributorDto map(Contributor contributor);
|
||||
|
||||
abstract PersonDto map(Person person);
|
||||
|
||||
|
||||
@@ -33,17 +33,17 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Extension
|
||||
public class ChangesetDescriptionTrailerProvider implements ChangesetPreProcessorFactory {
|
||||
public class ChangesetDescriptionContributorProvider implements ChangesetPreProcessorFactory {
|
||||
|
||||
private static final Collection<String> SUPPORTED_TRAILER_TYPES = ImmutableSet.of("Co-authored-by", "Reviewed-by", "Signed-off-by", "Committed-by");
|
||||
private static final Pattern TRAILER_PATTERN = Pattern.compile("^([\\w-]*):\\W*(.*)\\W+<(.*)>\\W*$");
|
||||
private static final Collection<String> 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 TrailerChangesetPreProcessor();
|
||||
return new ContributorChangesetPreProcessor();
|
||||
}
|
||||
|
||||
private static class TrailerChangesetPreProcessor implements ChangesetPreProcessor {
|
||||
private static class ContributorChangesetPreProcessor implements ChangesetPreProcessor {
|
||||
@Override
|
||||
public void process(Changeset changeset) {
|
||||
new Worker(changeset).process();
|
||||
@@ -75,20 +75,20 @@ public class ChangesetDescriptionTrailerProvider implements ChangesetPreProcesso
|
||||
return;
|
||||
}
|
||||
|
||||
if (foundEmptyLine && checkForTrailer(line)) {
|
||||
if (foundEmptyLine && checkForContributor(line)) {
|
||||
return;
|
||||
}
|
||||
appendLine(scanner, line);
|
||||
}
|
||||
|
||||
private boolean checkForTrailer(String line) {
|
||||
Matcher matcher = TRAILER_PATTERN.matcher(line);
|
||||
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_TRAILER_TYPES.contains(type)) {
|
||||
createTrailer(type, name, mail);
|
||||
if (SUPPORTED_CONTRIBUTOR_TYPES.contains(type)) {
|
||||
createContributor(type, name, mail);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -107,8 +107,8 @@ public class ChangesetDescriptionTrailerProvider implements ChangesetPreProcesso
|
||||
}
|
||||
}
|
||||
|
||||
private void createTrailer(String type, String name, String mail) {
|
||||
changeset.addTrailer(new Trailer(type, new Person(name, mail)));
|
||||
private void createContributor(String type, String name, String mail) {
|
||||
changeset.addContributor(new Contributor(type, new Person(name, mail)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"changeset": {
|
||||
"trailer": {
|
||||
"contributor": {
|
||||
"type": {
|
||||
"author": "Autor",
|
||||
"Reviewed-by": "Reviewer",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"changeset": {
|
||||
"trailer": {
|
||||
"contributor": {
|
||||
"type": {
|
||||
"author": "Author",
|
||||
"Reviewed-by": "Reviewers",
|
||||
|
||||
@@ -34,20 +34,20 @@ import java.util.Iterator;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ChangesetDescriptionTrailerProviderTest {
|
||||
class ChangesetDescriptionContributorProviderTest {
|
||||
|
||||
private static final Repository REPOSITORY = RepositoryTestData.createHeartOfGold();
|
||||
|
||||
private final ChangesetDescriptionTrailerProvider changesetDescriptionTrailers = new ChangesetDescriptionTrailerProvider();
|
||||
private final ChangesetDescriptionContributorProvider changesetDescriptionContributors = new ChangesetDescriptionContributorProvider();
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyList() {
|
||||
Changeset changeset = createChangeset("zaphod beeblebrox");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
assertThat(trailers).isNullOrEmpty();
|
||||
assertThat(contributors).isNullOrEmpty();
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox");
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
Person person = createPerson("Arthur Dent", "dent@hitchhiker.org");
|
||||
Changeset changeset = createChangeset("zaphod beeblebrox\n\nCo-authored-by: Arthur Dent <dent@hitchhiker.org>");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
Trailer trailer = trailers.iterator().next();
|
||||
assertThat(trailer.getTrailerType()).isEqualTo("Co-authored-by");
|
||||
assertThat(trailer.getPerson()).isEqualTo(person);
|
||||
Contributor contributor = contributors.iterator().next();
|
||||
assertThat(contributor.getType()).isEqualTo("Co-authored-by");
|
||||
assertThat(contributor.getPerson()).isEqualTo(person);
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox\n\n");
|
||||
}
|
||||
|
||||
@@ -70,13 +70,13 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
Person person = createPerson("Tricia McMillan", "trillian@hitchhiker.org");
|
||||
Changeset changeset = createChangeset("zaphod beeblebrox\n\nReviewed-by: Tricia McMillan <trillian@hitchhiker.org>");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
Trailer trailer = trailers.iterator().next();
|
||||
Contributor contributor = contributors.iterator().next();
|
||||
|
||||
assertThat(trailer.getTrailerType()).isEqualTo("Reviewed-by");
|
||||
assertThat(trailer.getPerson()).isEqualTo(person);
|
||||
assertThat(contributor.getType()).isEqualTo("Reviewed-by");
|
||||
assertThat(contributor.getPerson()).isEqualTo(person);
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox\n\n");
|
||||
}
|
||||
|
||||
@@ -85,13 +85,13 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
Person person = createPerson("Tricia McMillan", "trillian@hitchhiker.org");
|
||||
Changeset changeset = createChangeset("zaphod beeblebrox\n\n\nSigned-off-by: Tricia McMillan <trillian@hitchhiker.org>");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
Trailer trailer = trailers.iterator().next();
|
||||
Contributor contributor = contributors.iterator().next();
|
||||
|
||||
assertThat(trailer.getTrailerType()).isEqualTo("Signed-off-by");
|
||||
assertThat(trailer.getPerson()).isEqualTo(person);
|
||||
assertThat(contributor.getType()).isEqualTo("Signed-off-by");
|
||||
assertThat(contributor.getPerson()).isEqualTo(person);
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox\n\n\n");
|
||||
}
|
||||
|
||||
@@ -100,13 +100,13 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
Person person = createPerson("Tricia McMillan", "trillian@hitchhiker.org");
|
||||
Changeset changeset = createChangeset("zaphod beeblebrox\n\nCommitted-by: Tricia McMillan <trillian@hitchhiker.org>");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
Trailer trailer = trailers.iterator().next();
|
||||
Contributor contributor = contributors.iterator().next();
|
||||
|
||||
assertThat(trailer.getTrailerType()).isEqualTo("Committed-by");
|
||||
assertThat(trailer.getPerson()).isEqualTo(person);
|
||||
assertThat(contributor.getType()).isEqualTo("Committed-by");
|
||||
assertThat(contributor.getPerson()).isEqualTo(person);
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox\n\n");
|
||||
}
|
||||
|
||||
@@ -116,19 +116,19 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
"Committed-by: Tricia McMillan <trillian@hitchhiker.org>\n" +
|
||||
"Signed-off-by: Artur Dent <dent@hitchhiker.org>");
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
Iterator<Trailer> trailerIterator = trailers.iterator();
|
||||
Trailer firstTrailer = trailerIterator.next();
|
||||
Trailer secondTrailer = trailerIterator.next();
|
||||
Iterator<Contributor> contributorIterator = contributors.iterator();
|
||||
Contributor firstContributor = contributorIterator.next();
|
||||
Contributor secondContributor = contributorIterator.next();
|
||||
|
||||
assertThat(firstTrailer.getTrailerType()).isEqualTo("Committed-by");
|
||||
assertThat(firstTrailer.getPerson())
|
||||
assertThat(firstContributor.getType()).isEqualTo("Committed-by");
|
||||
assertThat(firstContributor.getPerson())
|
||||
.isEqualTo(createPerson("Tricia McMillan", "trillian@hitchhiker.org"));
|
||||
|
||||
assertThat(secondTrailer.getTrailerType()).isEqualTo("Signed-off-by");
|
||||
assertThat(secondTrailer.getPerson())
|
||||
assertThat(secondContributor.getType()).isEqualTo("Signed-off-by");
|
||||
assertThat(secondContributor.getPerson())
|
||||
.isEqualTo(createPerson("Artur Dent", "dent@hitchhiker.org"));
|
||||
|
||||
assertThat(changeset.getDescription()).isEqualTo("zaphod beeblebrox\n\n");
|
||||
@@ -140,10 +140,10 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
"Some-strange-tag: Tricia McMillan <trillian@hitchhiker.org>";
|
||||
Changeset changeset = createChangeset(originalCommitMessage);
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
assertThat(trailers).isNullOrEmpty();
|
||||
assertThat(contributors).isNullOrEmpty();
|
||||
assertThat(changeset.getDescription()).isEqualTo(originalCommitMessage);
|
||||
}
|
||||
|
||||
@@ -153,10 +153,10 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
"Committed-by: Tricia McMillan";
|
||||
Changeset changeset = createChangeset(originalCommitMessage);
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
assertThat(trailers).isNullOrEmpty();
|
||||
assertThat(contributors).isNullOrEmpty();
|
||||
assertThat(changeset.getDescription()).isEqualTo(originalCommitMessage);
|
||||
}
|
||||
|
||||
@@ -166,10 +166,10 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
"Committed-by: Tricia McMillan <trillian@hitchhiker.org>";
|
||||
Changeset changeset = createChangeset(originalCommitMessage);
|
||||
|
||||
changesetDescriptionTrailers.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Trailer> trailers = changeset.getTrailers();
|
||||
changesetDescriptionContributors.createPreProcessor(REPOSITORY).process(changeset);
|
||||
Collection<Contributor> contributors = changeset.getContributors();
|
||||
|
||||
assertThat(trailers).isNotEmpty();
|
||||
assertThat(contributors).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,15 +178,15 @@ class ChangesetDescriptionTrailerProviderTest {
|
||||
"Committed-by: Tricia McMillan <trillian@hitchhiker.org>");
|
||||
Changeset changeset2 = createChangeset("message two");
|
||||
|
||||
ChangesetPreProcessor preProcessor = changesetDescriptionTrailers.createPreProcessor(REPOSITORY);
|
||||
ChangesetPreProcessor preProcessor = changesetDescriptionContributors.createPreProcessor(REPOSITORY);
|
||||
preProcessor.process(changeset1);
|
||||
preProcessor.process(changeset2);
|
||||
|
||||
assertThat(changeset1.getDescription()).isEqualTo("message one\n\n");
|
||||
assertThat(changeset1.getTrailers()).isNotEmpty();
|
||||
assertThat(changeset1.getContributors()).isNotEmpty();
|
||||
|
||||
assertThat(changeset2.getDescription()).isEqualTo("message two");
|
||||
assertThat(changeset2.getTrailers()).isNullOrEmpty();
|
||||
assertThat(changeset2.getContributors()).isNullOrEmpty();
|
||||
}
|
||||
|
||||
private Changeset createChangeset(String commitMessage) {
|
||||
Reference in New Issue
Block a user