mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-02 03:25:56 +01:00
refactor backend for modifyCommand / add sourceExtension for plugins
This commit is contained in:
@@ -208,7 +208,6 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
|||||||
GitLogCommand command = createCommand();
|
GitLogCommand command = createCommand();
|
||||||
Changeset c = command.getChangeset("435df2f061add3589cb3", request);
|
Changeset c = command.getChangeset("435df2f061add3589cb3", request);
|
||||||
|
|
||||||
Assertions.assertThat(c.getBranches().isEmpty()).isFalse();
|
|
||||||
Assertions.assertThat(c.getBranches().contains("master")).isTrue();
|
Assertions.assertThat(c.getBranches().contains("master")).isTrue();
|
||||||
Assertions.assertThat(c.getBranches().size()).isEqualTo(1);
|
Assertions.assertThat(c.getBranches().size()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package sonia.scm.repository.spi;
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
|
import org.tmatesoft.svn.core.SVNCommitInfo;
|
||||||
import org.tmatesoft.svn.core.SVNDepth;
|
import org.tmatesoft.svn.core.SVNDepth;
|
||||||
import org.tmatesoft.svn.core.SVNException;
|
import org.tmatesoft.svn.core.SVNException;
|
||||||
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
import org.tmatesoft.svn.core.wc.SVNClientManager;
|
||||||
@@ -72,10 +73,9 @@ public class SvnModifyCommand implements ModifyCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
clientManager.getCommitClient().doCommit(new File[] {workingRepository}, false,
|
SVNCommitInfo svnCommitInfo = clientManager.getCommitClient().doCommit(new File[]{workingRepository}, false,
|
||||||
request.getCommitMessage(), null, null, false, true, SVNDepth.INFINITY);
|
request.getCommitMessage(), null, null, false, true, SVNDepth.INFINITY);
|
||||||
//I can't get the newest revision after commiting without creating a new working copy
|
return String.valueOf(svnCommitInfo.getNewRevision());
|
||||||
return String.valueOf(clientManager.getStatusClient().doStatus(workingRepository, false).getCommittedRevision().getNumber() + 1);
|
|
||||||
} catch (SVNException e) {
|
} catch (SVNException e) {
|
||||||
throw new InternalRepositoryException(repository, "could not commit changes on repository");
|
throw new InternalRepositoryException(repository, "could not commit changes on repository");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Branch, Repository } from "@scm-manager/ui-types";
|
|||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
|
|
||||||
type Props = WithTranslation & {
|
type Props = WithTranslation & {
|
||||||
|
repository: Repository;
|
||||||
branch: Branch;
|
branch: Branch;
|
||||||
defaultBranch: Branch;
|
defaultBranch: Branch;
|
||||||
revision: string;
|
revision: string;
|
||||||
@@ -58,7 +59,7 @@ class Breadcrumb extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { baseUrl, branch, defaultBranch, sources, revision, path, t } = this.props;
|
const { repository, baseUrl, branch, defaultBranch, sources, revision, path, t } = this.props;
|
||||||
|
|
||||||
let homeUrl = baseUrl + "/";
|
let homeUrl = baseUrl + "/";
|
||||||
if (revision) {
|
if (revision) {
|
||||||
@@ -80,14 +81,15 @@ class Breadcrumb extends React.Component<Props> {
|
|||||||
</FlexStartNav>
|
</FlexStartNav>
|
||||||
{binder.hasExtension("repos.sources.actionbar") && (
|
{binder.hasExtension("repos.sources.actionbar") && (
|
||||||
<ActionWrapper>
|
<ActionWrapper>
|
||||||
{console.log(sources)}
|
|
||||||
<ExtensionPoint
|
<ExtensionPoint
|
||||||
name="repos.sources.actionbar"
|
name="repos.sources.actionbar"
|
||||||
props={{
|
props={{
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
revision,
|
||||||
branch: branch ? branch : defaultBranch,
|
branch: branch ? branch : defaultBranch,
|
||||||
path,
|
path,
|
||||||
sources
|
sources,
|
||||||
|
repository
|
||||||
}}
|
}}
|
||||||
renderAll={true}
|
renderAll={true}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import PermissionsNavLink from "../components/PermissionsNavLink";
|
|||||||
import Sources from "../sources/containers/Sources";
|
import Sources from "../sources/containers/Sources";
|
||||||
import RepositoryNavLink from "../components/RepositoryNavLink";
|
import RepositoryNavLink from "../components/RepositoryNavLink";
|
||||||
import { getLinks, getRepositoriesLink } from "../../modules/indexResource";
|
import { getLinks, getRepositoriesLink } from "../../modules/indexResource";
|
||||||
|
import SourceExtensions from "../sources/containers/SourceExtensions";
|
||||||
|
|
||||||
type Props = WithTranslation & {
|
type Props = WithTranslation & {
|
||||||
namespace: string;
|
namespace: string;
|
||||||
@@ -120,6 +121,15 @@ class RepositoryRoot extends React.Component<Props> {
|
|||||||
path={`${url}/sources/:revision/:path*`}
|
path={`${url}/sources/:revision/:path*`}
|
||||||
render={() => <Sources repository={repository} baseUrl={`${url}/sources`} />}
|
render={() => <Sources repository={repository} baseUrl={`${url}/sources`} />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path={`${url}/sourceext/:extension`}
|
||||||
|
exact={true}
|
||||||
|
render={() => <SourceExtensions repository={repository} />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`${url}/sourceext/:extension/:revision/:path*`}
|
||||||
|
render={() => <SourceExtensions repository={repository} />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={`${url}/changesets`}
|
path={`${url}/changesets`}
|
||||||
render={() => (
|
render={() => (
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class Content extends React.Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
showHeader() {
|
showHeader() {
|
||||||
const { file, revision } = this.props;
|
const { repository, file, revision } = this.props;
|
||||||
const { showHistory, collapsed } = this.state;
|
const { showHistory, collapsed } = this.state;
|
||||||
const icon = collapsed ? "angle-right" : "angle-down";
|
const icon = collapsed ? "angle-right" : "angle-down";
|
||||||
|
|
||||||
@@ -99,6 +99,7 @@ class Content extends React.Component<Props, State> {
|
|||||||
<ExtensionPoint
|
<ExtensionPoint
|
||||||
name="repos.sources.content.actionbar"
|
name="repos.sources.content.actionbar"
|
||||||
props={{
|
props={{
|
||||||
|
repository,
|
||||||
file,
|
file,
|
||||||
revision,
|
revision,
|
||||||
handleExtensionError: this.handleExtensionError
|
handleExtensionError: this.handleExtensionError
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Repository, File } from "@scm-manager/ui-types";
|
||||||
|
import { withRouter, RouteComponentProps } from "react-router-dom";
|
||||||
|
|
||||||
|
import { ExtensionPoint, binder } from "@scm-manager/ui-extensions";
|
||||||
|
import {
|
||||||
|
fetchSources,
|
||||||
|
getFetchSourcesFailure,
|
||||||
|
getSources,
|
||||||
|
isFetchSourcesPending
|
||||||
|
} from "../modules/sources";
|
||||||
|
import { connect} from "react-redux";
|
||||||
|
import { Loading, ErrorNotification } from "@scm-manager/ui-components";
|
||||||
|
import Notification from "@scm-manager/ui-components/src/Notification";
|
||||||
|
|
||||||
|
type Props = RouteComponentProps & {
|
||||||
|
repository: Repository;
|
||||||
|
|
||||||
|
// url params
|
||||||
|
extension: string;
|
||||||
|
revision?: string;
|
||||||
|
path?: string;
|
||||||
|
|
||||||
|
// redux state
|
||||||
|
loading: boolean;
|
||||||
|
error?: Error | null;
|
||||||
|
sources?: File | null;
|
||||||
|
|
||||||
|
// dispatch props
|
||||||
|
fetchSources: (repository: Repository, revision: string, path: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const extensionPointName = "repos.sources.extensions";
|
||||||
|
|
||||||
|
class SourceExtensions extends React.Component<Props> {
|
||||||
|
componentDidMount() {
|
||||||
|
const { fetchSources, repository, revision, path } = this.props;
|
||||||
|
// TODO get typing right
|
||||||
|
fetchSources(repository, revision || "", path || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, error, repository, extension, revision, path, sources } = this.props;
|
||||||
|
if (error) {
|
||||||
|
return <ErrorNotification error={error} />;
|
||||||
|
}
|
||||||
|
if (loading) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extprops = { extension, repository, revision, path, sources };
|
||||||
|
if (!binder.hasExtension(extensionPointName, extprops)) {
|
||||||
|
// TODO i18n
|
||||||
|
return <Notification type="warning">No extension bound</Notification>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ExtensionPoint name={extensionPointName} props={extprops} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: any, ownProps: Props): Partial<Props> => {
|
||||||
|
const { repository, match } = ownProps;
|
||||||
|
// TODO add query-string v6
|
||||||
|
// see : https://www.pluralsight.com/guides/react-router-typescript
|
||||||
|
// @ts-ignore
|
||||||
|
const revision: string = match.params.revision;
|
||||||
|
// @ts-ignore
|
||||||
|
const path: string = match.params.path;
|
||||||
|
// @ts-ignore
|
||||||
|
const extension: string = match.params.extension;
|
||||||
|
const decodedRevision = revision ? decodeURIComponent(revision) : undefined;
|
||||||
|
const loading = isFetchSourcesPending(state, repository, revision, path);
|
||||||
|
const error = getFetchSourcesFailure(state, repository, revision, path);
|
||||||
|
const sources = getSources(state, repository, revision, path);
|
||||||
|
|
||||||
|
return {
|
||||||
|
repository,
|
||||||
|
extension,
|
||||||
|
revision: decodedRevision,
|
||||||
|
path,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
sources
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
fetchSources: (repository: Repository, revision: string, path: string) => {
|
||||||
|
dispatch(fetchSources(repository, revision, path));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withRouter(connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(SourceExtensions));
|
||||||
@@ -149,11 +149,12 @@ class Sources extends React.Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderBreadcrumb = () => {
|
renderBreadcrumb = () => {
|
||||||
const { revision, path, baseUrl, branches, sources } = this.props;
|
const { revision, path, baseUrl, branches, sources, repository } = this.props;
|
||||||
const { selectedBranch } = this.state;
|
const { selectedBranch } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
|
repository={repository}
|
||||||
revision={revision}
|
revision={revision}
|
||||||
path={path}
|
path={path}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
|
|||||||
Reference in New Issue
Block a user