From 5d7bdc24d4d2957f1da97b079d36f5db3d0b78dd Mon Sep 17 00:00:00 2001 From: Florian Scholdei Date: Tue, 5 Nov 2019 16:10:41 +0100 Subject: [PATCH 1/7] Make payload parameter optional --- scm-ui/ui-components/src/apiclient.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scm-ui/ui-components/src/apiclient.ts b/scm-ui/ui-components/src/apiclient.ts index 396200f1c1..115b241724 100644 --- a/scm-ui/ui-components/src/apiclient.ts +++ b/scm-ui/ui-components/src/apiclient.ts @@ -47,7 +47,7 @@ class ApiClient { return fetch(createUrl(url), applyFetchOptions({})).then(handleFailure); } - post(url: string, payload: any, contentType = "application/json") { + post(url: string, payload?: any, contentType = "application/json") { return this.httpRequestWithJSONBody("POST", url, contentType, payload); } @@ -82,11 +82,13 @@ class ApiClient { return fetch(createUrl(url), options).then(handleFailure); } - httpRequestWithJSONBody(method: string, url: string, contentType: string, payload: any): Promise { + httpRequestWithJSONBody(method: string, url: string, contentType: string, payload?: any): Promise { const options: RequestInit = { - method: method, - body: JSON.stringify(payload) + method: method }; + if (payload) { + options.body = JSON.stringify(payload); + } return this.httpRequestWithBinaryBody(options, url, contentType); } From 6d2bdb6f294f96162712a0b5fb6ec96f54f8b1e4 Mon Sep 17 00:00:00 2001 From: Florian Scholdei Date: Tue, 12 Nov 2019 14:48:32 +0100 Subject: [PATCH 2/7] Add IconButton --- .../src/__snapshots__/storyshots.test.ts.snap | 20 +++++++ .../ui-components/src/buttons/IconButton.tsx | 56 +++++++++++++++++++ .../src/buttons/index.stories.tsx | 3 +- scm-ui/ui-components/src/buttons/index.ts | 1 + 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 scm-ui/ui-components/src/buttons/IconButton.tsx diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index 0350b44219..b7852bd927 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -282,6 +282,26 @@ exports[`Storyshots Buttons|EditButton Default 1`] = ` `; +exports[`Storyshots Buttons|IconButton Default 1`] = ` +
+ +
+`; + exports[`Storyshots Buttons|SubmitButton Default 1`] = `
void; + link?: string; + className?: string; +}; + +type Props = ButtonProps & + RouteComponentProps & { + type?: "button" | "submit" | "reset"; + color?: string; + }; + +class IconButton extends React.Component { + static defaultProps: Partial = { + type: "button", + color: "default" + }; + + onClick = (event: React.MouseEvent) => { + const { action, link, history } = this.props; + if (action) { + action(event); + } else if (link) { + history.push(link); + } + }; + + render() { + const { icon, title, loading, disabled, type, color, className } = this.props; + const loadingClass = loading ? "is-loading" : ""; + return ( + + ); + } +} + +export default withRouter(IconButton); diff --git a/scm-ui/ui-components/src/buttons/index.stories.tsx b/scm-ui/ui-components/src/buttons/index.stories.tsx index acfd513139..4da801f8a1 100644 --- a/scm-ui/ui-components/src/buttons/index.stories.tsx +++ b/scm-ui/ui-components/src/buttons/index.stories.tsx @@ -3,6 +3,7 @@ import Button from "./Button"; import { storiesOf } from "@storybook/react"; import styled from "styled-components"; import { MemoryRouter } from "react-router-dom"; +import IconButton from "./IconButton"; import AddButton from "./AddButton"; import CreateButton from "./CreateButton"; import DeleteButton from "./DeleteButton"; @@ -48,7 +49,7 @@ const buttonStory = (name: string, storyFn: () => ReactElement) => { .addDecorator(SpacingDecorator) .add("Default", storyFn); }; - +buttonStory("IconButton", () => ); buttonStory("AddButton", () => Add); buttonStory("CreateButton", () => Create); buttonStory("DeleteButton", () => Delete); diff --git a/scm-ui/ui-components/src/buttons/index.ts b/scm-ui/ui-components/src/buttons/index.ts index c5d536133f..3bbfd05c4b 100644 --- a/scm-ui/ui-components/src/buttons/index.ts +++ b/scm-ui/ui-components/src/buttons/index.ts @@ -2,6 +2,7 @@ export { default as AddButton } from "./AddButton"; export { default as Button } from "./Button"; +export { default as IconButton } from "./IconButton"; export { default as CreateButton } from "./CreateButton"; export { default as DeleteButton } from "./DeleteButton"; export { default as EditButton } from "./EditButton"; From 9132167a6cd9a18a325bc4fec2b7021a46f5ba9b Mon Sep 17 00:00:00 2001 From: Florian Scholdei Date: Tue, 12 Nov 2019 17:30:37 +0100 Subject: [PATCH 3/7] Add title option to Button and remove IconButton --- .../src/__snapshots__/storyshots.test.ts.snap | 20 ------- scm-ui/ui-components/src/buttons/Button.tsx | 17 +++++- .../ui-components/src/buttons/IconButton.tsx | 56 ------------------- .../src/buttons/index.stories.tsx | 2 - scm-ui/ui-components/src/buttons/index.ts | 1 - 5 files changed, 16 insertions(+), 80 deletions(-) delete mode 100644 scm-ui/ui-components/src/buttons/IconButton.tsx diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index b7852bd927..0350b44219 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -282,26 +282,6 @@ exports[`Storyshots Buttons|EditButton Default 1`] = `
`; -exports[`Storyshots Buttons|IconButton Default 1`] = ` -
- -
-`; - exports[`Storyshots Buttons|SubmitButton Default 1`] = `
{ }; render() { - const { label, loading, disabled, type, color, className, icon, fullWidth, reducedMobile, children } = this.props; + const { + label, + title, + loading, + disabled, + type, + color, + className, + icon, + fullWidth, + reducedMobile, + children + } = this.props; const loadingClass = loading ? "is-loading" : ""; const fullWidthClass = fullWidth ? "is-fullwidth" : ""; const reducedMobileClass = reducedMobile ? "is-reduced-mobile" : ""; @@ -46,6 +59,7 @@ class Button extends React.Component { return ( - ); - } -} - -export default withRouter(IconButton); diff --git a/scm-ui/ui-components/src/buttons/index.stories.tsx b/scm-ui/ui-components/src/buttons/index.stories.tsx index 4da801f8a1..79d5be448c 100644 --- a/scm-ui/ui-components/src/buttons/index.stories.tsx +++ b/scm-ui/ui-components/src/buttons/index.stories.tsx @@ -3,7 +3,6 @@ import Button from "./Button"; import { storiesOf } from "@storybook/react"; import styled from "styled-components"; import { MemoryRouter } from "react-router-dom"; -import IconButton from "./IconButton"; import AddButton from "./AddButton"; import CreateButton from "./CreateButton"; import DeleteButton from "./DeleteButton"; @@ -49,7 +48,6 @@ const buttonStory = (name: string, storyFn: () => ReactElement) => { .addDecorator(SpacingDecorator) .add("Default", storyFn); }; -buttonStory("IconButton", () => ); buttonStory("AddButton", () => Add); buttonStory("CreateButton", () => Create); buttonStory("DeleteButton", () => Delete); diff --git a/scm-ui/ui-components/src/buttons/index.ts b/scm-ui/ui-components/src/buttons/index.ts index 3bbfd05c4b..c5d536133f 100644 --- a/scm-ui/ui-components/src/buttons/index.ts +++ b/scm-ui/ui-components/src/buttons/index.ts @@ -2,7 +2,6 @@ export { default as AddButton } from "./AddButton"; export { default as Button } from "./Button"; -export { default as IconButton } from "./IconButton"; export { default as CreateButton } from "./CreateButton"; export { default as DeleteButton } from "./DeleteButton"; export { default as EditButton } from "./EditButton"; From d1747557b3d9df972c392d4fe45e32b8d7e86bf8 Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Wed, 13 Nov 2019 10:48:36 +0100 Subject: [PATCH 4/7] Make conflict exception accessible with complex context --- .../main/java/sonia/scm/ConcurrentModificationException.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java b/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java index d566859b4c..990d05181b 100644 --- a/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java +++ b/scm-core/src/main/java/sonia/scm/ConcurrentModificationException.java @@ -17,7 +17,7 @@ public class ConcurrentModificationException extends ExceptionWithContext { this(Collections.singletonList(new ContextEntry(type, id))); } - private ConcurrentModificationException(List context) { + public ConcurrentModificationException(List context) { super(context, createMessage(context)); } @@ -32,3 +32,4 @@ public class ConcurrentModificationException extends ExceptionWithContext { .collect(joining(" in ", "", " has been modified concurrently")); } } + From 2f5095e76a62aafa715dce9f2b2a2992713a9c9e Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Fri, 15 Nov 2019 09:33:38 +0100 Subject: [PATCH 5/7] Handle missing blobs in blob store for lfs pointers --- .../sonia/scm/repository/spi/GitBrowseCommand.java | 10 ++++++++-- .../java/sonia/scm/repository/spi/GitCatCommand.java | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java index 5ec69cccdd..2048d13dea 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java @@ -213,8 +213,14 @@ public class GitBrowseCommand extends AbstractGitCommand if (lfsPointer.isPresent()) { BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository); - Blob blob = lfsBlobStore.get(lfsPointer.get().getOid().getName()); - file.setLength(blob.getSize()); + String oid = lfsPointer.get().getOid().getName(); + Blob blob = lfsBlobStore.get(oid); + if (blob == null) { + logger.error("lfs blob for lob id {} not found in lfs store of repository {}", oid, repository.getNamespaceAndName()); + file.setLength(-1); + } else { + file.setLength(blob.getSize()); + } } else { file.setLength(loader.getSize()); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java index 35ff4d6ac2..193ab5bbc8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java @@ -145,7 +145,12 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand { private Loader loadFromLfsStore(TreeWalk treeWalk, RevWalk revWalk, LfsPointer lfsPointer) throws IOException { BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository); - Blob blob = lfsBlobStore.get(lfsPointer.getOid().getName()); + String oid = lfsPointer.getOid().getName(); + Blob blob = lfsBlobStore.get(oid); + if (blob == null) { + logger.error("lfs blob for lob id {} not found in lfs store of repository {}", oid, repository.getNamespaceAndName()); + throw notFound(entity("LFS", oid).in(repository)); + } GitUtil.release(revWalk); GitUtil.release(treeWalk); return new BlobLoader(blob); From cc4c4f0822ea9a5763c661e67131dbffd47379be Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Fri, 15 Nov 2019 09:50:28 +0100 Subject: [PATCH 6/7] Fix browse of empty repository In an empty hg repository the Changeset c is null. This leads to an NullPointerException in the original code. So we check whether we have a Changeset and otherwise use the old functionality. --- .../main/java/sonia/scm/repository/spi/HgBrowseCommand.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java index 48772ad5e5..b3e8e89a5f 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java @@ -77,7 +77,9 @@ public class HgBrowseCommand extends AbstractCommand implements BrowseCommand String revision = MoreObjects.firstNonNull(request.getRevision(), "tip"); Changeset c = LogCommand.on(getContext().open()).rev(revision).limit(1).single(); - cmd.rev(c.getNode()); + if (c != null) { + cmd.rev(c.getNode()); + } if (!Strings.isNullOrEmpty(request.getPath())) { @@ -100,6 +102,6 @@ public class HgBrowseCommand extends AbstractCommand implements BrowseCommand } FileObject file = cmd.execute(); - return new BrowserResult(c.getNode(), revision, file); + return new BrowserResult(c == null? "tip": c.getNode(), revision, file); } } From f5b7d9f8f9702b2eb776b3b13ae9b06f69f4863f Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Fri, 15 Nov 2019 11:35:27 +0000 Subject: [PATCH 7/7] Close branch feature/pr_approval