implemented git repository type configuration

This commit is contained in:
Sebastian Sdorra
2018-11-06 07:59:34 +01:00
parent ef23178fad
commit dd95c9c306
22 changed files with 321 additions and 1368 deletions

View File

@@ -116,17 +116,17 @@ public class GitRepositoryHandler
public void init(SCMContextProvider context)
{
super.init(context);
scheduleGc();
scheduleGc(getConfig().getGcExpression());
}
@Override
public void setConfig(GitConfig config)
{
scheduleGc(config.getGcExpression());
super.setConfig(config);
scheduleGc();
}
private void scheduleGc()
private void scheduleGc(String expression)
{
synchronized (LOCK){
if ( task != null ){
@@ -134,11 +134,10 @@ public class GitRepositoryHandler
task.cancel();
task = null;
}
String exp = getConfig().getGcExpression();
if (!Strings.isNullOrEmpty(exp))
if (!Strings.isNullOrEmpty(expression))
{
logger.info("schedule git gc task with expression {}", exp);
task = scheduler.schedule(exp, GitGcTask.class);
logger.info("schedule git gc task with expression {}", expression);
task = scheduler.schedule(expression, GitGcTask.class);
}
}
}

View File

@@ -0,0 +1,183 @@
//@flow
import React from "react";
import { translate } from "react-i18next";
import type { Links } from "@scm-manager/ui-types";
import {
apiClient,
Title,
InputField,
Checkbox,
SubmitButton,
Loading,
ErrorNotification
} from "@scm-manager/ui-components";
type Props = {
url: string,
// context props
t: (string) => string
};
type Configuration = {
repositoryDirectory?: string,
gcExpression?: string,
disabled: boolean,
_links?: Links
}
type State = Configuration & {
error?: Error,
fetching: boolean,
modifying: boolean
};
class GitConfiguration extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
disabled: false,
fetching: true,
modifying: false
};
}
componentDidMount() {
const { url } = this.props;
// TODO capture content-type for sending
apiClient.get(url)
.then(response => response.json())
.then(this.loadConfig)
.catch(this.handleError);
}
handleError = (error: Error) => {
this.setState({
error,
fetching: false,
modifying: false
});
};
loadConfig = (configuration: Configuration) => {
this.setState({
...configuration,
fetching: false,
error: undefined
});
};
handleInputChange = (value: string, name: string) => {
this.setState({
[name]: value
});
};
handleCheckboxChange = (value: boolean, name: string) => {
this.setState({
[name]: value
});
};
isValid = (): boolean => {
const { repositoryDirectory } = this.state;
return !!repositoryDirectory;
};
getModificationUrl = (): ?string => {
const links = this.state._links;
if (links && links.update) {
return links.update.href;
}
};
isReadOnly = (): boolean => {
const links = this.state._links;
return !links || !links.update;
};
render() {
const { fetching, error } = this.state;
if (error) {
return this.renderWithFrame(<ErrorNotification error={error}/>);
} else if (fetching) {
return this.renderWithFrame(<Loading/>);
}
return this.renderForm();
}
renderWithFrame(child) {
const { t } = this.props;
return (
<div>
<Title title={t("scm-git-plugin.config.title")}/>
{child}
</div>
);
}
modifyConfiguration = (event: Event) => {
event.preventDefault();
this.setState({ modifying: true });
const { repositoryDirectory, gcExpression, disabled } = this.state;
const configuration = {
repositoryDirectory,
gcExpression,
disabled
};
apiClient.put(this.getModificationUrl(), configuration, "application/vnd.scmm-gitconfig+json;v=2")
.then(() => this.setState({ modifying: false }))
.catch(this.handleError);
};
renderForm() {
const { repositoryDirectory, gcExpression, disabled, modifying } = this.state;
const { t } = this.props;
const readOnly = this.isReadOnly();
return this.renderWithFrame(
<form onSubmit={this.modifyConfiguration}>
<InputField name="repositoryDirectory"
label={t("scm-git-plugin.config.directory")}
helpText={t("scm-git-plugin.config.directoryHelpText")}
value={repositoryDirectory}
onChange={this.handleInputChange}
disabled={readOnly}
/>
<InputField name="gcExpression"
label={t("scm-git-plugin.config.gcExpression")}
helpText={t("scm-git-plugin.config.gcExpressionHelpText")}
value={gcExpression}
onChange={this.handleInputChange}
disabled={readOnly}
/>
<Checkbox name="disabled"
label={t("scm-git-plugin.config.disabled")}
helpText={t("scm-git-plugin.config.disabledHelpText")}
checked={disabled}
onChange={this.handleCheckboxChange}
disabled={readOnly}
/>
<hr/>
<SubmitButton
label={t("scm-git-plugin.config.submit")}
disabled={!this.isValid() || readOnly}
loading={modifying}
/>
</form>
);
}
}
export default translate("plugins")(GitConfiguration);

View File

@@ -0,0 +1,21 @@
//@flow
import React from "react";
import { NavLink } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
type Props = {
url: string,
// context props
t: (string) => string
}
class GitConfigurationNavLink extends React.Component<Props> {
render() {
const { url, t } = this.props;
return <NavLink to={`${url}/git`} label={t("scm-git-plugin.config.link")} />;
}
}
export default translate("plugins")(GitConfigurationNavLink);

View File

@@ -0,0 +1,25 @@
//@flow
import React from "react";
import type { Links } from "@scm-manager/ui-types";
import GitConfiguration from "./GitConfiguration";
import { Route } from "react-router-dom";
type Props = {
url: string,
links: Links
}
class GitConfigurationRoute extends React.Component<Props> {
render() {
const { url, links } = this.props;
const configLink = links["gitConfig"].href;
return <Route path={url + "/git"}
component={() => <GitConfiguration url={configLink} />}
exact />;
}
}
export default GitConfigurationRoute;

View File

@@ -2,6 +2,10 @@
import { binder } from "@scm-manager/ui-extensions";
import ProtocolInformation from "./ProtocolInformation";
import GitAvatar from "./GitAvatar";
import GitConfigurationNavLink from "./GitConfigurationNavLink";
import GitConfigurationRoute from "./GitConfigurationRoute";
// repository
const gitPredicate = (props: Object) => {
return props.repository && props.repository.type === "git";
@@ -9,3 +13,12 @@ const gitPredicate = (props: Object) => {
binder.bind("repos.repository-details.information", ProtocolInformation, gitPredicate);
binder.bind("repos.repository-avatar", GitAvatar, gitPredicate);
// global config
const gitConfigPredicate = (props: Object) => {
return props.links && props.links["gitConfig"];
};
binder.bind("config.navigation", GitConfigurationNavLink, gitConfigPredicate);
binder.bind("config.route", GitConfigurationRoute, gitConfigPredicate);

View File

@@ -4,6 +4,17 @@
"clone" : "Clone the repository",
"create" : "Create a new repository",
"replace" : "Push an existing repository"
},
"config": {
"link": "Git",
"title": "Git Configuration",
"directory": "Repository Directory",
"directoryHelpText": "Location of the Git repositories.",
"gcExpression": "GC Cron Expression",
"gcExpressionHelpText": "Use Quartz Cron Expressions (SECOND MINUTE HOUR DAYOFMONTH MONTH DAYOFWEEK) to run git gc in intervals.",
"disabled": "Disabled",
"disabledHelpText": "Enable or disable the Git plugin",
"submit": "Submit"
}
}
}