You should create an ScmScmCommands
interface like this:
public interface ScmScmCommands {
public StringString[] getRevisionCommand();
public StringList<String[]> getDiffCommand();
public StringList<String[]> getCodebaseInfoCommand();
}
and two implementations: SvnSvnCommands
, GitGitCommands
.
It would improve type safety a lot. (With a Map<String, Object>
you usually have to cast the values which is error-prone). Furthermore, it eliminates the magic constants. It's easy to call Map.get()
with a mistyped key. With the interface the compiler warns you if the method name is wrong.
Edit: I've changed the return types. Sample implementations are the following:
public class GitCommands implements ScmCommands {
private static final String GIT_COMMAND = "git";
public GitCommands() {
}
@Override
public String[] getRevisionCommand() {
return new String[] { GIT_COMMAND, "rev-parse", "HEAD" };
}
@Override
public List<String[]> getDiffCommand() {
final List<String[]> result = new ArrayList<String[]>();
result.add(new String[] { GIT_COMMAND, "diff", "HEAD" });
result.add(new String[] { GIT_COMMAND, "diff", "HEAD", "--no-prefix" });
return result;
}
@Override
public List<String[]> getCodebaseInfoCommand() {
final List<String[]> result = new ArrayList<String[]>();
result.add(new String[] { GIT_COMMAND, "branch", "-v" });
result.add(new String[] { GIT_COMMAND, "remote", "-v" });
result.add(new String[] { GIT_COMMAND, "log", "--max-count=1" });
result.add(new String[] { GIT_COMMAND, "status" });
return result;
}
}
public class SvnCommands implements ScmCommands {
private static final String SVN_COMMAND = "svn";
public SvnCommands() {
}
@Override
public String[] getRevisionCommand() {
return new String[] { SVN_COMMAND, "info" };
}
@Override
public List<String[]> getDiffCommand() {
final List<String[]> result = new ArrayList<String[]>();
result.add(new String[] {SVN_COMMAND, "diff"});
return result;
}
@Override
public List<String[]> getCodebaseInfoCommand() {
final List<String[]> result = new ArrayList<String[]>();
result.add(new String[] { SVN_COMMAND, "status" });
return result;
}
}
It fits well to ProcessBuilder
but I'd consider extracting out all SCM related methods to an interface (for example Scm
), and move the code to SCM-specific classes which implement the Scm
interface, like GitScm
, SubversionScm
etc. Calling command line executables doesn't smell good, maybe it would be better to use native Subversion and Git Java libraries.