mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 23:45:44 +01:00
merge
This commit is contained in:
@@ -1,348 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.installer.HgInstallerFactory;
|
||||
import sonia.scm.installer.HgPackage;
|
||||
import sonia.scm.installer.HgPackageReader;
|
||||
import sonia.scm.installer.HgPackages;
|
||||
import sonia.scm.net.ahc.AdvancedHttpClient;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Singleton
|
||||
@Path("config/repositories/hg")
|
||||
public class HgConfigResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param client
|
||||
* @param handler
|
||||
* @param pkgReader
|
||||
*/
|
||||
@Inject
|
||||
public HgConfigResource(AdvancedHttpClient client,
|
||||
HgRepositoryHandler handler, HgPackageReader pkgReader)
|
||||
{
|
||||
this.client = client;
|
||||
this.handler = handler;
|
||||
this.pkgReader = pkgReader;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param uriInfo
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Path("auto-configuration")
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public HgConfig autoConfiguration(@Context UriInfo uriInfo)
|
||||
{
|
||||
return autoConfiguration(uriInfo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param uriInfo
|
||||
* @param config
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Path("auto-configuration")
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public HgConfig autoConfiguration(@Context UriInfo uriInfo, HgConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
config = new HgConfig();
|
||||
}
|
||||
|
||||
handler.doAutoConfiguration(config);
|
||||
|
||||
return handler.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Path("packages/{pkgId}")
|
||||
public Response installPackage(@PathParam("pkgId") String id)
|
||||
{
|
||||
Response response = null;
|
||||
HgPackage pkg = pkgReader.getPackage(id);
|
||||
|
||||
if (pkg != null)
|
||||
{
|
||||
if (HgInstallerFactory.createInstaller().installPackage(client, handler,
|
||||
SCMContext.getContext().getBaseDirectory(), pkg))
|
||||
{
|
||||
response = Response.noContent().build();
|
||||
}
|
||||
else
|
||||
{
|
||||
response =
|
||||
Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response = Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public HgConfig getConfig()
|
||||
{
|
||||
HgConfig config = handler.getConfig();
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
config = new HgConfig();
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("installations/hg")
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public InstallationsResponse getHgInstallations()
|
||||
{
|
||||
List<String> installations =
|
||||
HgInstallerFactory.createInstaller().getHgInstallations();
|
||||
|
||||
return new InstallationsResponse(installations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("packages")
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public HgPackages getPackages()
|
||||
{
|
||||
return pkgReader.getPackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("installations/python")
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public InstallationsResponse getPythonInstallations()
|
||||
{
|
||||
List<String> installations =
|
||||
HgInstallerFactory.createInstaller().getPythonInstallations();
|
||||
|
||||
return new InstallationsResponse(installations);
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param uriInfo
|
||||
* @param config
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
public Response setConfig(@Context UriInfo uriInfo, HgConfig config)
|
||||
throws IOException
|
||||
{
|
||||
handler.setConfig(config);
|
||||
handler.storeConfig();
|
||||
|
||||
return Response.created(uriInfo.getRequestUri()).build();
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 11/04/25
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "installations")
|
||||
public static class InstallationsResponse
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public InstallationsResponse() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param paths
|
||||
*/
|
||||
public InstallationsResponse(List<String> paths)
|
||||
{
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getPaths()
|
||||
{
|
||||
return paths;
|
||||
}
|
||||
|
||||
//~--- set methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param paths
|
||||
*/
|
||||
public void setPaths(List<String> paths)
|
||||
{
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "path")
|
||||
private List<String> paths;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private AdvancedHttpClient client;
|
||||
|
||||
/** Field description */
|
||||
private HgRepositoryHandler handler;
|
||||
|
||||
/** Field description */
|
||||
private HgPackageReader pkgReader;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class AbstractHgHandler
|
||||
} catch (JAXBException ex) {
|
||||
logger.error("could not parse result", ex);
|
||||
|
||||
throw new InternalRepositoryException("could not parse result", ex);
|
||||
throw new InternalRepositoryException(repository, "could not parse result", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ package sonia.scm.repository.spi;
|
||||
import com.aragost.javahg.commands.ExecutionException;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Closeables;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.web.HgUtil;
|
||||
@@ -46,6 +49,8 @@ import java.io.OutputStream;
|
||||
|
||||
public class HgCatCommand extends AbstractCommand implements CatCommand {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HgCatCommand.class);
|
||||
|
||||
HgCatCommand(HgCommandContext context, Repository repository) {
|
||||
super(context, repository);
|
||||
}
|
||||
@@ -70,7 +75,8 @@ public class HgCatCommand extends AbstractCommand implements CatCommand {
|
||||
try {
|
||||
return cmd.execute(request.getPath());
|
||||
} catch (ExecutionException e) {
|
||||
throw new InternalRepositoryException(e);
|
||||
log.error("could not execute cat command", e);
|
||||
throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity(getRepository()), "could not execute cat command", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class HgIncomingCommand extends AbstractCommand
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute incoming command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute incoming command", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class HgOutgoingCommand extends AbstractCommand
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute outgoing command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute outgoing command", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class HgPullCommand extends AbstractHgPushOrPullCommand
|
||||
}
|
||||
catch (ExecutionException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute push command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute push command", ex);
|
||||
}
|
||||
|
||||
return new PullResponse(result.size());
|
||||
|
||||
@@ -97,7 +97,7 @@ public class HgPushCommand extends AbstractHgPushOrPullCommand
|
||||
}
|
||||
catch (ExecutionException ex)
|
||||
{
|
||||
throw new InternalRepositoryException("could not execute push command", ex);
|
||||
throw new InternalRepositoryException(getRepository(), "could not execute push command", ex);
|
||||
}
|
||||
|
||||
return new PushResponse(result.size());
|
||||
|
||||
@@ -44,11 +44,11 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.HgContext;
|
||||
import sonia.scm.repository.HgHookManager;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryHookType;
|
||||
import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.RepositoryUtil;
|
||||
import sonia.scm.repository.api.HgHookMessage;
|
||||
import sonia.scm.repository.api.HgHookMessage.Severity;
|
||||
@@ -275,17 +275,11 @@ public class HgHookCallbackServlet extends HttpServlet
|
||||
|
||||
printMessages(response, context);
|
||||
}
|
||||
catch (RepositoryNotFoundException ex)
|
||||
catch (NotFoundException ex)
|
||||
{
|
||||
if (logger.isErrorEnabled())
|
||||
{
|
||||
logger.error("could not find repository with id {}", id);
|
||||
logger.error(ex.getMessage());
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("repository not found", ex);
|
||||
}
|
||||
}
|
||||
logger.trace("repository not found", ex);
|
||||
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
113
scm-plugins/scm-hg-plugin/src/main/js/HgConfigurationForm.js
Normal file
113
scm-plugins/scm-hg-plugin/src/main/js/HgConfigurationForm.js
Normal file
@@ -0,0 +1,113 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import type { Links } from "@scm-manager/ui-types";
|
||||
import { translate } from "react-i18next";
|
||||
import { InputField, Checkbox } from "@scm-manager/ui-components";
|
||||
|
||||
type Configuration = {
|
||||
"hgBinary": string,
|
||||
"pythonBinary": string,
|
||||
"pythonPath"?: string,
|
||||
"repositoryDirectory": string,
|
||||
"encoding": string,
|
||||
"useOptimizedBytecode": boolean,
|
||||
"showRevisionInId": boolean,
|
||||
"disabled": boolean,
|
||||
"_links": Links
|
||||
};
|
||||
|
||||
type Props = {
|
||||
initialConfiguration: Configuration,
|
||||
readOnly: boolean,
|
||||
|
||||
onConfigurationChange: (Configuration, boolean) => void,
|
||||
|
||||
// context props
|
||||
t: (string) => string
|
||||
}
|
||||
|
||||
type State = Configuration & {
|
||||
validationErrors: string[]
|
||||
};
|
||||
|
||||
class HgConfigurationForm extends React.Component<Props, State> {
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = { ...props.initialConfiguration, validationErrors: [] };
|
||||
}
|
||||
|
||||
updateValidationStatus = () => {
|
||||
const requiredFields = [
|
||||
"hgBinary", "pythonBinary", "repositoryDirectory", "encoding"
|
||||
];
|
||||
|
||||
const validationErrors = [];
|
||||
for (let field of requiredFields) {
|
||||
if (!this.state[field]) {
|
||||
validationErrors.push( field );
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
validationErrors
|
||||
});
|
||||
|
||||
return validationErrors.length === 0;
|
||||
};
|
||||
|
||||
|
||||
hasValidationError = (name: string) => {
|
||||
return this.state.validationErrors.indexOf(name) >= 0;
|
||||
};
|
||||
|
||||
handleChange = (value: any, name: string) => {
|
||||
this.setState({
|
||||
[name]: value
|
||||
}, () => this.props.onConfigurationChange(this.state, this.updateValidationStatus()));
|
||||
};
|
||||
|
||||
inputField = (name: string) => {
|
||||
const { readOnly, t } = this.props;
|
||||
return <InputField
|
||||
name={ name }
|
||||
label={t("scm-hg-plugin.config." + name)}
|
||||
helpText={t("scm-hg-plugin.config." + name + "HelpText")}
|
||||
value={this.state[name]}
|
||||
onChange={this.handleChange}
|
||||
validationError={this.hasValidationError(name)}
|
||||
errorMessage={t("scm-hg-plugin.config.required")}
|
||||
disabled={readOnly}
|
||||
/>;
|
||||
};
|
||||
|
||||
checkbox = (name: string) => {
|
||||
const { readOnly, t } = this.props;
|
||||
return <Checkbox
|
||||
name={ name }
|
||||
label={t("scm-hg-plugin.config." + name)}
|
||||
helpText={t("scm-hg-plugin.config." + name + "HelpText")}
|
||||
checked={this.state[name]}
|
||||
onChange={this.handleChange}
|
||||
disabled={readOnly}
|
||||
/>;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
{this.inputField("hgBinary")}
|
||||
{this.inputField("pythonBinary")}
|
||||
{this.inputField("pythonPath")}
|
||||
{this.inputField("repositoryDirectory")}
|
||||
{this.inputField("encoding")}
|
||||
{this.checkbox("useOptimizedBytecode")}
|
||||
{this.checkbox("showRevisionInId")}
|
||||
{this.checkbox("disabled")}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default translate("plugins")(HgConfigurationForm);
|
||||
@@ -0,0 +1,28 @@
|
||||
//@flow
|
||||
import React from "react";
|
||||
import { Title, GlobalConfiguration } from "@scm-manager/ui-components";
|
||||
import { translate } from "react-i18next";
|
||||
import HgConfigurationForm from "./HgConfigurationForm";
|
||||
|
||||
type Props = {
|
||||
link: string,
|
||||
|
||||
// context props
|
||||
t: (string) => string
|
||||
}
|
||||
|
||||
class HgGlobalConfiguration extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const { link, t } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Title title={t("scm-hg-plugin.config.title")}/>
|
||||
<GlobalConfiguration link={link} render={props => <HgConfigurationForm {...props} />}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default translate("plugins")(HgGlobalConfiguration);
|
||||
@@ -2,6 +2,8 @@
|
||||
import { binder } from "@scm-manager/ui-extensions";
|
||||
import ProtocolInformation from "./ProtocolInformation";
|
||||
import HgAvatar from "./HgAvatar";
|
||||
import { ConfigurationBinder as cfgBinder } from "@scm-manager/ui-components";
|
||||
import HgGlobalConfiguration from "./HgGlobalConfiguration";
|
||||
|
||||
const hgPredicate = (props: Object) => {
|
||||
return props.repository && props.repository.type === "hg";
|
||||
@@ -9,3 +11,7 @@ const hgPredicate = (props: Object) => {
|
||||
|
||||
binder.bind("repos.repository-details.information", ProtocolInformation, hgPredicate);
|
||||
binder.bind("repos.repository-avatar", HgAvatar, hgPredicate);
|
||||
|
||||
// bind global configuration
|
||||
|
||||
cfgBinder.bindGlobal("/hg", "scm-hg-plugin.config.link", "hgConfig", HgGlobalConfiguration);
|
||||
|
||||
@@ -4,6 +4,27 @@
|
||||
"clone" : "Clone the repository",
|
||||
"create" : "Create a new repository",
|
||||
"replace" : "Push an existing repository"
|
||||
},
|
||||
"config": {
|
||||
"link": "Mercurial",
|
||||
"title": "Mercurial Configuration",
|
||||
"hgBinary": "HG Binary",
|
||||
"hgBinaryHelpText": "Location of Mercurial binary.",
|
||||
"pythonBinary": "Python Binary",
|
||||
"pythonBinaryHelpText": "Location of Python binary.",
|
||||
"pythonPath": "Python Module Search Path",
|
||||
"pythonPathHelpText": "Python Module Search Path (PYTHONPATH).",
|
||||
"repositoryDirectory": "Repository directory",
|
||||
"repositoryDirectoryHelpText": "Location of Mercurial repositories.",
|
||||
"encoding": "Encoding",
|
||||
"encodingHelpText": "Repository Encoding.",
|
||||
"useOptimizedBytecode": "Optimized Bytecode (.pyo)",
|
||||
"useOptimizedBytecodeHelpText": "Use the Python '-O' switch.",
|
||||
"showRevisionInId": "Show Revision",
|
||||
"showRevisionInIdHelpText": "Show revision as part of the node id.",
|
||||
"disabled": "Disabled",
|
||||
"disabledHelpText": "Enable or disable the Mercurial plugin.",
|
||||
"required": "This configuration value is required"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.junit.Test;
|
||||
import sonia.scm.repository.Changeset;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.Modifications;
|
||||
import sonia.scm.repository.RevisionNotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -151,7 +150,7 @@ public class HgLogCommandTest extends AbstractHgCommandTestBase
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommit() throws IOException, RevisionNotFoundException {
|
||||
public void testGetCommit() throws IOException {
|
||||
HgLogCommand command = createComamnd();
|
||||
String revision = "a9bacaf1b7fa0cebfca71fed4e59ed69a6319427";
|
||||
Changeset c =
|
||||
|
||||
Reference in New Issue
Block a user