Mercurial > hg > mercurial
view mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java @ 429:04eab204ba39
Remove HgVcsRoot's dependency on HgPathProvider
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Fri, 11 May 2012 16:37:00 +0400 |
parents | c91c4f1ebd53 |
children | 2af623e989f6 |
line wrap: on
line source
package jetbrains.buildServer.buildTriggers.vcs.mercurial; import jetbrains.buildServer.agent.AgentRunningBuild; import jetbrains.buildServer.agent.BuildProgressLogger; import jetbrains.buildServer.agent.vcs.IncludeRuleUpdater; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.UnrelatedRepositoryException; import jetbrains.buildServer.vcs.IncludeRule; import jetbrains.buildServer.vcs.VcsException; import jetbrains.buildServer.vcs.VcsRoot; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.util.Map; import static com.intellij.openapi.util.io.FileUtil.delete; /** * @author dmitry.neverov */ public class MercurialIncludeRuleUpdater implements IncludeRuleUpdater { private final AgentPluginConfig myConfig; private final MirrorManager myMirrorManager; private final HgVcsRoot myRoot; private final AuthSettings myAuthSettings; private final String myHgPath; private final String myToVersion; private final BuildProgressLogger myLogger; private final boolean myUseLocalMirrors; private int myPullTimeout; public MercurialIncludeRuleUpdater(@NotNull final AgentPluginConfig pluginConfig, @NotNull final MirrorManager mirrorManager, @NotNull final HgPathProvider hgPathProvider, @NotNull final VcsRoot root, @NotNull final String toVersion, @NotNull final AgentRunningBuild build) { myConfig = pluginConfig; myMirrorManager = mirrorManager; myRoot = new HgVcsRoot(root); myAuthSettings = myRoot.getAuthSettings(); myHgPath = hgPathProvider.getHgPath(myRoot); myToVersion = toVersion; myLogger = build.getBuildLogger(); myUseLocalMirrors = myConfig.isUseLocalMirrors(build); myPullTimeout = myConfig.getPullTimeout(build); } public void process(@NotNull IncludeRule rule, @NotNull File workingDir) throws VcsException { try { checkRuleIsValid(rule); if (myUseLocalMirrors) updateLocalMirror(myRoot.getRepository(), myToVersion); updateRepository(workingDir); updateWorkingDir(workingDir, myToVersion, myRoot.getRepository()); } catch (Exception e) { throwVcsException(e); } } public void dispose() throws VcsException { } private void updateLocalMirror(@NotNull String repositoryUrl, @NotNull String revision) throws VcsException, IOException { File mirrorDir = myMirrorManager.getMirrorDir(repositoryUrl); HgRepo mirrorRepo = new HgRepo(mirrorDir, myHgPath, myAuthSettings); if (!mirrorRepo.isValidRepository()) { delete(mirrorDir); myLogger.message("Clone repository " + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl) + " into local mirror " + mirrorRepo.path()); mirrorRepo.doClone().fromRepository(repositoryUrl) .setUpdateWorkingDir(false) .setUsePullProtocol(false) .useUncompressedTransfer(myRoot.isUncompressedTransfer()) .call(); myLogger.message("Clone successfully finished"); } else { myLogger.message("Update local mirror of " + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl) + " at " + mirrorDir); if (mirrorRepo.containsRevision(revision)) { myLogger.message("Local mirror is already up-to-date"); } else { myLogger.message("Start pulling changes from " + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl)); mirrorRepo.pull().fromRepository(repositoryUrl) .withTimeout(myPullTimeout) .call(); myLogger.message("Local mirror changes successfully pulled"); } } } private void updateRepository(@NotNull File workingDir) throws VcsException, IOException { String repositoryUrl = getDefaultPullUrl(myRoot, myUseLocalMirrors); HgRepo repo = new HgRepo(workingDir, myHgPath, myAuthSettings); myLogger.message("Update repository " + workingDir.getAbsolutePath()); if (repo.isEmpty()) {//can do clone only in empty dir myLogger.message("Start cloning from " + (myUseLocalMirrors ? "local mirror " : "") + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl)); repo.doClone().fromRepository(repositoryUrl) .setUsePullProtocol(false) .setUpdateWorkingDir(false) .useUncompressedTransfer(!myUseLocalMirrors && myRoot.isUncompressedTransfer()) .call(); repo.setDefaultPath(myRoot.getRepository()); myLogger.message("Repository successfully cloned"); } else { if (!repo.isValidRepository()) repo.init().call(); repo.setDefaultPath(myRoot.getRepository()); if (repo.containsRevision(myToVersion)) { myLogger.message("Repository already contains revision " + myToVersion); } else { myLogger.message("Start pulling changes from " + (myUseLocalMirrors ? "local mirror " : "") + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl)); try { repo.pull().fromRepository(repositoryUrl) .withTimeout(myPullTimeout) .call(); } catch (UnrelatedRepositoryException e) { throw new UnrelatedRepositoryException(myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl), workingDir); } myLogger.message("Changes successfully pulled"); } } } private void updateWorkingDir(@NotNull File workingDir, @NotNull String toVersion, @NotNull String repositoryUrl) throws VcsException, IOException { HgRepo repo = new HgRepo(workingDir, myHgPath, myAuthSettings); updateSubrepositories(repo, toVersion, repositoryUrl); doUpdateWorkingDir(repo, toVersion); } private void updateSubrepositories(@NotNull HgRepo repo, @NotNull String toVersion, @NotNull String parentRepositoryUrl) throws VcsException, IOException { if (!repo.hasSubreposAtRevision(toVersion)) return; myLogger.message("Process subrepos of " + parentRepositoryUrl); String workingDirRevision = repo.getWorkingDirRevision(); Map<String, SubRepo> workingDirSubrepos = repo.getSubrepositories(workingDirRevision); Map<String, SubRepo> subrepos = repo.getSubrepositories(toVersion); for (Map.Entry<String, SubRepo> entry : subrepos.entrySet()) { String path = entry.getKey(); myLogger.message("Process subrepo " + path); SubRepo subrepo = entry.getValue(); SubRepo workingDirSubrepo = workingDirSubrepos.get(path); if (workingDirSubrepo != null && subrepo.hasDifferentUrlThan(workingDirSubrepo)) { myLogger.message("The url of subrepo was changed between revisions " + workingDirRevision + " and " + toVersion + " , delete the subrepo"); delete(subrepo.dir()); } HgRepo subrepository = new HgRepo(subrepo.dir(), myHgPath, myAuthSettings); if (myUseLocalMirrors && subrepo.vcsType() == SubRepo.VcsType.hg) { if (subrepo.isRelative()) { myLogger.message("Subrepo url " + subrepo.url() + " is relative, subrepo will be updated during parent repository update"); } else { if (!subrepository.isValidRepository() || !subrepository.containsRevision(subrepo.revision())) { updateLocalMirror(subrepo.url(), subrepo.revision()); File mirrorDir = myMirrorManager.getMirrorDir(subrepo.url()); if (subrepository.isValidRepository()) { myLogger.message("Pull from local mirror"); subrepository.pull().fromRepository(mirrorDir) .withTimeout(myPullTimeout) .call(); myLogger.message("done"); } else { myLogger.message("Clone subrepo from local mirror"); subrepository.doClone().fromRepository(mirrorDir) .setUpdateWorkingDir(false) .setUsePullProtocol(false) .call(); subrepository.setDefaultPath(subrepo.url()); myLogger.message("done"); } } } } else { myLogger.message("Local mirrors aren't used, subrepo will be updated during the parent repo update"); } updateSubrepositories(subrepository, subrepo.revision(), subrepo.url()); } } private void doUpdateWorkingDir(@NotNull HgRepo repo, @NotNull String revision) throws VcsException { myLogger.message("Updating working dir " + repo.path() + " to revision " + revision); repo.update().toRevision(revision).call(); myLogger.message("Working dir updated"); } private String getDefaultPullUrl(HgVcsRoot root, boolean useLocalMirror) throws IOException { if (useLocalMirror) { File mirrorDir = myMirrorManager.getMirrorDir(root.getRepository()); return mirrorDir.getCanonicalPath(); } else { return root.getRepository(); } } private void checkRuleIsValid(IncludeRule includeRule) throws VcsException { if (includeRule.getTo() != null && includeRule.getTo().length() > 0) { if (!".".equals(includeRule.getFrom()) && includeRule.getFrom().length() != 0) throw new VcsException("Invalid include rule: " + includeRule.toString() + ", Mercurial plugin supports mapping of the form: +:.=>dir only."); } } private void throwVcsException(Exception e) throws VcsException { if (e instanceof VcsException) throw (VcsException) e; else throw new VcsException(e); } }