mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-06 13:35:44 +01:00
implemented git repository type configuration
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
183
scm-plugins/scm-git-plugin/src/main/js/GitConfiguration.js
Normal file
183
scm-plugins/scm-git-plugin/src/main/js/GitConfiguration.js
Normal 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);
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user