mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-06 12:20:56 +01:00
Show hg binary verification error messages (#1637)
Show hg verification error messages on global hg config page if trying to save invalid hg binary.
This commit is contained in:
@@ -35,6 +35,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import sonia.scm.config.ConfigurationPermissions;
|
||||
import sonia.scm.repository.HgGlobalConfig;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.HgVerifier;
|
||||
import sonia.scm.web.HgVndMediaType;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
@@ -48,6 +49,8 @@ import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import static sonia.scm.ScmConstraintViolationException.Builder.doThrow;
|
||||
|
||||
/**
|
||||
* RESTful Web Service Resource to manage the configuration of the hg plugin.
|
||||
*/
|
||||
@@ -144,6 +147,7 @@ public class HgConfigResource {
|
||||
responseCode = "204",
|
||||
description = "update success"
|
||||
)
|
||||
@ApiResponse(responseCode = "400", description = "invalid configuration")
|
||||
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
|
||||
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"configuration:write:hg\" privilege")
|
||||
@ApiResponse(
|
||||
@@ -154,11 +158,16 @@ public class HgConfigResource {
|
||||
schema = @Schema(implementation = ErrorDto.class)
|
||||
))
|
||||
public Response update(@Valid HgGlobalGlobalConfigDto configDto) {
|
||||
|
||||
HgGlobalConfig config = dtoToConfigMapper.map(configDto);
|
||||
|
||||
ConfigurationPermissions.write(config).check();
|
||||
|
||||
if (config.getHgBinary() != null) {
|
||||
HgVerifier.HgVerifyStatus verifyStatus = new HgVerifier().verify(config.getHgBinary());
|
||||
doThrow()
|
||||
.violation(verifyStatus.getDescription())
|
||||
.when(verifyStatus != HgVerifier.HgVerifyStatus.VALID);
|
||||
}
|
||||
|
||||
repositoryHandler.setConfig(config);
|
||||
repositoryHandler.storeConfig();
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -29,6 +29,9 @@ import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.io.SimpleCommand;
|
||||
import sonia.scm.io.SimpleCommandResult;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnum;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -48,23 +51,31 @@ public class HgVerifier {
|
||||
}
|
||||
|
||||
public boolean isValid(HgGlobalConfig config) {
|
||||
return isValid(config.getHgBinary());
|
||||
return verify(config) == HgVerifyStatus.VALID;
|
||||
}
|
||||
|
||||
public boolean isValid(String hg) {
|
||||
return isValid(Paths.get(hg));
|
||||
public boolean isValid(Path path) {
|
||||
return verify(path) == HgVerifyStatus.VALID;
|
||||
}
|
||||
|
||||
public boolean isValid(Path hg) {
|
||||
public HgVerifyStatus verify(HgGlobalConfig config) {
|
||||
return verify(config.getHgBinary());
|
||||
}
|
||||
|
||||
public HgVerifyStatus verify(String hg) {
|
||||
return verify(Paths.get(hg));
|
||||
}
|
||||
|
||||
public HgVerifyStatus verify(Path hg) {
|
||||
LOG.trace("check if hg binary {} is valid", hg);
|
||||
if (!Files.isRegularFile(hg)) {
|
||||
LOG.warn("{} is not a regular file", hg);
|
||||
return false;
|
||||
return HgVerifyStatus.NOT_REGULAR_FILE;
|
||||
}
|
||||
|
||||
if (!Files.isExecutable(hg)) {
|
||||
LOG.warn("{} is not executable", hg);
|
||||
return false;
|
||||
return HgVerifyStatus.NOT_EXECUTABLE;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -72,31 +83,31 @@ public class HgVerifier {
|
||||
return isVersionValid(hg, version);
|
||||
} catch (IOException ex) {
|
||||
LOG.warn("failed to resolve version of {}: ", hg, ex);
|
||||
return false;
|
||||
return HgVerifyStatus.COULD_NOT_RESOLVE_VERSION;
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.warn("failed to resolve version of {}: ", hg, ex);
|
||||
return false;
|
||||
return HgVerifyStatus.COULD_NOT_RESOLVE_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVersionValid(Path hg, String version) {
|
||||
private HgVerifyStatus isVersionValid(Path hg, String version) {
|
||||
String[] parts = version.split("\\.");
|
||||
if (parts.length < 2) {
|
||||
LOG.warn("{} returned invalid version: {}", hg, version);
|
||||
return false;
|
||||
return HgVerifyStatus.INVALID_VERSION;
|
||||
}
|
||||
try {
|
||||
int major = Integer.parseInt(parts[0]);
|
||||
if (major < 4) {
|
||||
LOG.warn("{} is too old, we need at least mercurial 4.x", hg);
|
||||
return false;
|
||||
return HgVerifyStatus.VERSION_TOO_OLD;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
LOG.warn("{} returned invalid version {}", hg, version);
|
||||
return false;
|
||||
return HgVerifyStatus.INVALID_VERSION;
|
||||
}
|
||||
return true;
|
||||
return HgVerifyStatus.VALID;
|
||||
}
|
||||
|
||||
private VersionResolver defaultVersionResolver() {
|
||||
@@ -115,4 +126,22 @@ public class HgVerifier {
|
||||
String resolveVersion(Path hg) throws IOException, InterruptedException;
|
||||
}
|
||||
|
||||
public enum HgVerifyStatus {
|
||||
VALID("hg binary is valid"),
|
||||
NOT_REGULAR_FILE("hg binary is not a regular file"),
|
||||
NOT_EXECUTABLE("hg binary is not executable"),
|
||||
INVALID_VERSION("hg binary returned invalid version"),
|
||||
VERSION_TOO_OLD("hg binary version is too old, we need at least 4.x"),
|
||||
COULD_NOT_RESOLVE_VERSION("failed to resolve version of hg binary");
|
||||
|
||||
private final String description;
|
||||
|
||||
HgVerifyStatus(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user