Skip to content

Commit

Permalink
Only show relevant information for repository on repository informati…
Browse files Browse the repository at this point in the history
…on page. The initialization block is only shown if the repository is still empty.
  • Loading branch information
eheimbuch committed Apr 27, 2021
1 parent 9782fd2 commit f028d3b
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 111 deletions.
118 changes: 71 additions & 47 deletions scm-plugins/scm-git-plugin/src/main/js/CloneInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,57 +21,81 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from "react";
import { WithTranslation, withTranslation } from "react-i18next";
import { Repository } from "@scm-manager/ui-types";
import React, { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Branch, Link, Repository } from "@scm-manager/ui-types";
import { apiClient } from "@scm-manager/ui-components";

type Props = WithTranslation & {
type Props = {
url: string;
repository: Repository;
};

class CloneInformation extends React.Component<Props> {
render() {
const { url, repository, t } = this.props;
const CloneInformation: FC<Props> = ({ url, repository }) => {
const [t] = useTranslation("plugins");
const [defaultBranch, setDefaultBranch] = useState<Branch>({ name: "", revision: "", _links: {} });
const [emptyRepository, setEmptyRepository] = useState<boolean>();

return (
<div>
<h4>{t("scm-git-plugin.information.clone")}</h4>
<pre>
<code>git clone {url}</code>
</pre>
<h4>{t("scm-git-plugin.information.create")}</h4>
<pre>
<code>
git init {repository.name}
<br />
cd {repository.name}
<br />
echo "# {repository.name}
" &gt; README.md
<br />
git add README.md
<br />
git commit -m "Add readme"
<br />
git remote add origin {url}
<br />
git push -u origin master
<br />
</code>
</pre>
<h4>{t("scm-git-plugin.information.replace")}</h4>
<pre>
<code>
git remote add origin {url}
<br />
git push -u origin master
<br />
</code>
</pre>
</div>
);
}
}
useEffect(() => {
if (repository) {
apiClient
.get((repository._links.changesets as Link).href)
.then(r => r.json())
.then(result => {
const empty = result._embedded.changesets.length === 0;
setEmptyRepository(empty);

export default withTranslation("plugins")(CloneInformation);
if (!empty) {
apiClient
.get((repository._links.defaultBranch as Link).href)
.then(r => r.json())
.then(setDefaultBranch);
}
});
}
}, [repository]);

return (
<div>
<h4>{t("scm-git-plugin.information.clone")}</h4>
<pre>
<code>git clone {url}</code>
</pre>
{emptyRepository && (
<>
<h4>{t("scm-git-plugin.information.create")}</h4>
<pre>
<code>
git init {repository.name}
<br />
cd {repository.name}
<br />
echo "# {repository.name}
" &gt; README.md
<br />
git add README.md
<br />
git commit -m "Add readme"
<br />
git remote add origin {url}
<br />
git push -u origin {defaultBranch?.name || "master"}
<br />
</code>
</pre>
</>
)}
<h4>{t("scm-git-plugin.information.replace")}</h4>
<pre>
<code>
git remote add origin {url}
<br />
git push -u origin {defaultBranch?.name || "master"}
<br />
</code>
</pre>
</div>
);
};

export default CloneInformation;
1 change: 0 additions & 1 deletion scm-plugins/scm-git-plugin/src/main/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* SOFTWARE.
*/

import React from "react";
import { binder } from "@scm-manager/ui-extensions";
import ProtocolInformation from "./ProtocolInformation";
import GitAvatar from "./GitAvatar";
Expand Down
131 changes: 74 additions & 57 deletions scm-plugins/scm-hg-plugin/src/main/js/ProtocolInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,67 +21,84 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from "react";
import { WithTranslation, withTranslation } from "react-i18next";
import { Repository } from "@scm-manager/ui-types";
import { repositories } from "@scm-manager/ui-components";
import React, { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, Repository } from "@scm-manager/ui-types";
import { apiClient, repositories } from "@scm-manager/ui-components";

type Props = WithTranslation & {
type Props = {
repository: Repository;
};

class ProtocolInformation extends React.Component<Props> {
render() {
const { repository, t } = this.props;
const href = repositories.getProtocolLinkByType(repository, "http");
if (!href) {
return null;
const ProtocolInformation: FC<Props> = ({ repository }) => {
const [t] = useTranslation("plugins");
const [emptyRepository, setEmptyRepository] = useState<boolean>();

const href = repositories.getProtocolLinkByType(repository, "http");

useEffect(() => {
if (repository) {
apiClient
.get((repository._links.changesets as Link).href)
.then(r => r.json())
.then(result => {
const empty = result._embedded.changesets.length === 0;
setEmptyRepository(empty);
});
}
return (
<div>
<h4>{t("scm-hg-plugin.information.clone")}</h4>
<pre>
<code>hg clone {href}</code>
</pre>
<h4>{t("scm-hg-plugin.information.create")}</h4>
<pre>
<code>
hg init {repository.name}
<br />
cd {repository.name}
<br />
echo "[paths]" &gt; .hg/hgrc
<br />
echo "default = {href}
" &gt;&gt; .hg/hgrc
<br />
echo "# {repository.name}
" &gt; README.md
<br />
hg add README.md
<br />
hg commit -m "added readme"
<br />
<br />
hg push
<br />
</code>
</pre>
<h4>{t("scm-hg-plugin.information.replace")}</h4>
<pre>
<code>
# add the repository url as default to your .hg/hgrc e.g:
<br />
default = {href}
<br />
# push to remote repository
<br />
hg push
</code>
</pre>
</div>
);
}, [repository]);

if (!href) {
return null;
}
}
return (
<div>
<h4>{t("scm-hg-plugin.information.clone")}</h4>
<pre>
<code>hg clone {href}</code>
</pre>
{emptyRepository && (
<>
<h4>{t("scm-hg-plugin.information.create")}</h4>
<pre>
<code>
hg init {repository.name}
<br />
cd {repository.name}
<br />
echo "[paths]" &gt; .hg/hgrc
<br />
echo "default = {href}
" &gt;&gt; .hg/hgrc
<br />
echo "# {repository.name}
" &gt; README.md
<br />
hg add README.md
<br />
hg commit -m "added readme"
<br />
<br />
hg push
<br />
</code>
</pre>
</>
)}
<h4>{t("scm-hg-plugin.information.replace")}</h4>
<pre>
<code>
# add the repository url as default to your .hg/hgrc e.g:
<br />
default = {href}
<br />
# push to remote repository
<br />
hg push
</code>
</pre>
</div>
);
};

export default withTranslation("plugins")(ProtocolInformation);
export default ProtocolInformation;
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

import javax.inject.Inject;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
Expand All @@ -61,6 +62,7 @@
import java.io.IOException;
import java.net.URI;
import java.util.Optional;
import java.util.function.Predicate;

import static sonia.scm.AlreadyExistsException.alreadyExists;
import static sonia.scm.ContextEntry.ContextBuilder.entity;
Expand Down Expand Up @@ -95,7 +97,7 @@ public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranc
* @param branchName the name of the branch
*/
@GET
@Path("{branch}")
@Path("{branch: ^(?!default-branch$)[^/]+$}")
@Produces(VndMediaType.BRANCH)
@Operation(summary = "Get single branch", description = "Returns a branch for a repository.", tags = "Repository")
@ApiResponse(
Expand Down Expand Up @@ -127,14 +129,63 @@ public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranc
public Response get(
@PathParam("namespace") String namespace,
@PathParam("name") String name,
@PathParam("branch") String branchName
@Pattern(regexp = "\\w{1,100}") @PathParam("branch") String branchName
) throws IOException {
return getSingleBranchResponse(namespace, name, branchName, branch -> branch.getName().equals(branchName));
}

/**
* Returns the default branch for the repository.
*
* <strong>Note:</strong> This method requires "repository" privilege.
*
* @param namespace the namespace of the repository
* @param name the name of the repository
*/
@GET
@Path("default-branch")
@Produces(VndMediaType.BRANCH)
@Operation(summary = "Get default branch", description = "Returns the default branch for the repository.", tags = "Repository")
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.BRANCH,
schema = @Schema(implementation = BranchDto.class)
)
)
@ApiResponse(responseCode = "400", description = "branches not supported for given repository")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the branch")
@ApiResponse(
responseCode = "404",
description = "not found, no default branch for the repository available or repository found",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
)
)
public Response getDefaultBranch(
@PathParam("namespace") String namespace,
@PathParam("name") String name
) throws IOException {
return getSingleBranchResponse(namespace, name, "defaultBranch", Branch::isDefaultBranch);
}

private Response getSingleBranchResponse(String namespace, String name, String branchName, Predicate<Branch> predicate) throws IOException {
NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name);
try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
Branches branches = repositoryService.getBranchesCommand().getBranches();
return branches.getBranches()
.stream()
.filter(branch -> branchName.equals(branch.getName()))
.filter(predicate)
.findFirst()
.map(branch -> branchToDtoMapper.map(branch, repositoryService.getRepository()))
.map(Response::ok)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ RepositoryDto createDto(Repository repository) {
}
if (repositoryService.isSupported(Command.BRANCHES)) {
linksBuilder.single(link("branches", resourceLinks.branchCollection().self(repository.getNamespace(), repository.getName())));
linksBuilder.single(link("defaultBranch", resourceLinks.branch().defaultBranch(repository.getNamespace(), repository.getName())));
}
if (repositoryService.isSupported(Feature.INCOMING_REVISION)) {
linksBuilder.single(link("incomingChangesets", resourceLinks.incoming().changesets(repository.getNamespace(), repository.getName())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ String self(String namespace, String name, String branch) {
return branchLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("branches").parameters().method("get").parameters(branch).href();
}

public String defaultBranch(String namespace, String name) {
return branchLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("branches").parameters().method("getDefaultBranch").parameters().href();
}

public String history(String namespace, String name, String branch) {
return branchLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("branches").parameters().method("history").parameters(branch).href();
}
Expand Down

0 comments on commit f028d3b

Please sign in to comment.