Mercurial > hg > mercurial
diff mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java @ 399:45f25ca68312 Faradi-7.0.x
Support local mirrors for subrepos
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Fri, 02 Mar 2012 14:24:58 +0400 |
parents | |
children | e33c3e4918f5 4a76645fe087 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Fri Mar 02 14:24:58 2012 +0400 @@ -0,0 +1,216 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*; +import jetbrains.buildServer.util.FileUtil; +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static com.intellij.openapi.util.io.FileUtil.delete; +import static java.util.Collections.emptyMap; +import static jetbrains.buildServer.util.FileUtil.isEmptyDir; + +/** +* @author dmitry.neverov +*/ +public class HgRepo { + + protected final File myWorkingDir; + protected final String myHgPath; + protected final AuthSettings myAuthSettings; + private final Map<String, Map<String, SubRepo>> mySubreposCache = new HashMap<String, Map<String, SubRepo>>(); + + public HgRepo(@NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings) { + myWorkingDir = workingDir; + myHgPath = hgPath; + myAuthSettings = authSettings; + } + + public PullCommand pull() { + return new PullCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public PushCommand push() { + return new PushCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public CloneCommand doClone() { + return new CloneCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public IdentifyCommand id() { + return new IdentifyCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public Init init() { + return new Init(myHgPath, myWorkingDir, myAuthSettings); + } + + public LogCommand log() { + return new LogCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public UpdateCommand update() { + return new UpdateCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public BranchesCommand branches() { + return new BranchesCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public StatusCommand status() { + return new StatusCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public TagCommand tag() { + return new TagCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public CatCommand cat() { + return new CatCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public ArchiveCommand archive() { + return new ArchiveCommand(myHgPath, myWorkingDir, myAuthSettings); + } + + public String path() { + return myWorkingDir.getAbsolutePath(); + } + + public File getWorkingDir() { + return myWorkingDir; + } + + public boolean isEmpty() { + return isEmptyDir(myWorkingDir); + } + + public String getWorkingDirRevision() throws VcsException { + return id().inLocalRepository().call(); + } + + public boolean containsRevision(@NotNull String revision) { + return containsRevision(new ChangeSet(revision)); + } + + public boolean containsRevision(@NotNull ChangeSet cset) { + try { + id().revision(cset).inLocalRepository().call(); + return true; + } catch (VcsException e) { + return false; + } + } + + public boolean isValidRepository() { + // need better way to check that repository copy is ok + return myWorkingDir.isDirectory() && new File(myWorkingDir, ".hg").isDirectory(); + } + + public void setDefaultPath(@NotNull String defaultPath) { + File hgrc = new File(new File(myWorkingDir, ".hg"), "hgrc"); + String content = "[paths]\ndefault = " + defaultPath; + FileUtil.writeFile(hgrc, content); + } + + public boolean hasSubreposAtRevision(@NotNull String revision) { + return !getSubrepositories(new ChangeSet(revision)).isEmpty(); + } + + public boolean hasSubreposAtRevision(@NotNull ChangeSet cset) { + return !getSubrepositories(cset).isEmpty(); + } + + public Map<String, SubRepo> getSubrepositories(@NotNull String revision) { + return getSubrepositories(new ChangeSet(revision)); + } + + public Map<String, SubRepo> getSubrepositories(@NotNull ChangeSet cset) { + String revId = cset.getId(); + Map<String, SubRepo> subrepos = mySubreposCache.get(revId); + if (subrepos != null) + return subrepos; + CatCommand cc = cat(); + cc.setRevId(revId); + File catDir = null; + try { + catDir = cc.execute(Arrays.asList(".hgsub", ".hgsubstate"), false); + File hgsub = new File(catDir, ".hgsub"); + File hgsubstate = new File(catDir, ".hgsubstate"); + subrepos = readSubrepositories(hgsub, hgsubstate); + mySubreposCache.put(revId, subrepos); + return subrepos; + } catch (VcsException e) { + return emptyMap(); + } finally { + if (catDir != null) + delete(catDir); + } + } + + @Override + public String toString() { + return myWorkingDir.getAbsolutePath(); + } + + private Map<String, SubRepo> readSubrepositories(@NotNull final File hgsub, @NotNull final File hgsubstate) { + if (hgsub.exists() && hgsubstate.exists()) { + try { + Map<String, String> path2repo = readHgsub(hgsub); + Map<String, String> path2revision = readHgsubstate(hgsubstate); + Map<String, SubRepo> result = new HashMap<String, SubRepo>(); + for (Map.Entry<String, String> entry : path2repo.entrySet()) { + String path = entry.getKey(); + String url = entry.getValue(); + String revision = path2revision.get(path); + if (revision != null) { + result.put(path, new SubRepo(this, path, url, revision)); + } else { +// myLogger.warning("Cannot find revision for subrepository at path " + path + " skip it"); + } + } + return result; + } catch (IOException e) { +// myLogger.warning("Error while trying to read subrepositories " + e.getMessage()); + return emptyMap(); + } + } else { + return emptyMap(); + } + } + + /*returns map: relative path -> repository url */ + private Map<String, String> readHgsub(@NotNull final File hgsub) throws IOException { + Map<String, String> result = new HashMap<String, String>(); + for (String line : FileUtil.readFile(hgsub)) { + String[] parts = line.split(" = "); + if (parts.length == 2) { + result.put(parts[0], parts[1]); + } else { +// myLogger.warning("Cannot parse the line '" + line + "' from .hgsub, skip it"); + } + } + return result; + } + + + /*returns map: relative path -> revision */ + private Map<String, String> readHgsubstate(@NotNull final File hgsubstate) throws IOException { + Map<String, String> result = new HashMap<String, String>(); + for (String line : FileUtil.readFile(hgsubstate)) { + String[] parts = line.split(" "); + if (parts.length == 2) { + result.put(parts[1], parts[0]); + } else { +// myLogger.warning("Cannot parse the line '" + line + "' from .hgsubstate, skip it"); + } + } + return result; + } +}