Mercurial > hg > mercurial
view mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java @ 977:38adef4f1b8f Indore-2017.2.x
Update copyright
author | pavel.sher |
---|---|
date | Mon, 22 Jan 2018 11:40:45 +0100 |
parents | a6405f5aad54 |
children | f342d25311c1 |
line wrap: on
line source
/* * Copyright 2000-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.buildTriggers.vcs.mercurial; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.WrongSubrepoUrlException; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.Map; import static jetbrains.buildServer.util.FileUtil.delete; /** * Repository checkout which uses mirrors (updates them first) * and supports subrepos. */ public class CheckoutRepository { private final MirrorManager myMirrorManager; private final HgRepoFactory myHgRepoFactory; private final int myPullTimeout; private boolean myGlobalTagsAsBranches; private final HgVcsRoot myRoot; private final File myWorkingDir; private String myRevision; private String myBranch; CheckoutRepository(@NotNull MirrorManager mirrorManager, @NotNull HgRepoFactory hgRepoFactory, int pullTimeout, boolean globalTagsAsBranches, @NotNull HgVcsRoot root, @NotNull File workingDir) { myMirrorManager = mirrorManager; myHgRepoFactory = hgRepoFactory; myPullTimeout = pullTimeout; myRoot = root; myWorkingDir = workingDir; myGlobalTagsAsBranches = globalTagsAsBranches; } public CheckoutRepository setRevision(String revision) { myRevision = revision; return this; } public CheckoutRepository setBranch(String branch) { myBranch = branch; return this; } public void checkout() throws VcsException { checkout(myRoot, myWorkingDir, myRevision); } private void checkout(@NotNull HgVcsRoot root, @NotNull File workingDir, @Nullable String revision) throws VcsException { revision = updateRepository(root, workingDir, revision); if (revision == null) return; updateSubrepos(root, workingDir, revision); updateWorkingDir(root, workingDir, revision); } @Nullable private String updateRepository(@NotNull HgVcsRoot root, @NotNull File workingDir, @Nullable String revision) throws VcsException { HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); if (revision != null && repo.containsRevision(revision)) return revision; String rev = updateMirror(root, revision); String mirrorUrl = getMirrorUrl(root); if (!repo.isValidRepository()) repo.init().call(); repo.pull().fromRepository(mirrorUrl) .withTimeout(myPullTimeout) .call(); repo.setDefaultPath(root.getRepository()); repo.setTeamCityConfig(root.getCustomHgConfig()); return rev; } private void updateWorkingDir(@NotNull HgVcsRoot root, @NotNull File workingDir, @NotNull String revision) throws VcsException { HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); repo.update().toRevision(revision).call(); } private void updateSubrepos(@NotNull HgVcsRoot root, @NotNull File workingDir, @Nullable String revision) throws VcsException { HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); if (!repo.hasSubreposAtRevision(revision)) return; String workingDirRevision = repo.getWorkingDirRevision(); Map<String, SubRepo> workingDirSubrepos = repo.getSubrepositories(workingDirRevision); Map<String, SubRepo> subrepos = repo.getSubrepositories(revision); for (Map.Entry<String, SubRepo> entry : subrepos.entrySet()) { String path = entry.getKey(); SubRepo subrepoConfig = entry.getValue(); SubRepo workingDirSubrepo = workingDirSubrepos.get(path); if (workingDirSubrepo != null && subrepoConfig.hasDifferentUrlThan(workingDirSubrepo)) delete(subrepoConfigDir(repo, subrepoConfig)); File subrepoDir = new File(workingDir, subrepoConfig.path()); String subrepoUrl; try { subrepoUrl = subrepoConfig.resolveUrl(root.getRepository()); if (subrepoConfig.vcsType() == SubRepo.VcsType.hg && !isRelativeUrl(subrepoUrl)) { HgVcsRoot subrepoRoot = root.withUrl(subrepoUrl); updateRepository(subrepoRoot, subrepoDir, subrepoConfig.revision()); } } catch (WrongSubrepoUrlException e) { subrepoUrl = subrepoConfig.url(); } updateSubrepos(root.withUrl(subrepoUrl), subrepoDir, subrepoConfig.revision()); } } private boolean isRelativeUrl(@NotNull String url) { return url.startsWith("."); } private File subrepoConfigDir(@NotNull HgRepo parentRepo, @NotNull SubRepo subrepo) { return new File(parentRepo.getWorkingDir(), subrepo.path()); } /** * @return the given revision if it was not null, or revision of the myBranch if myBranch != null, * otherwise returns null. Need to resolve a branch revision with mirror lock because bookmarks * can be deleted by another thread. */ @Nullable private String updateMirror(@NotNull HgVcsRoot root, @Nullable String revision) throws VcsException { String url = root.getRepository(); File mirrorDir = myMirrorManager.getMirrorDir(url); myMirrorManager.lockDir(mirrorDir); try { HgRepo repo = myHgRepoFactory.createRepo(root, mirrorDir); if (revision != null && repo.containsRevision(revision)) { return revision; } if (!repo.isValidRepository()) repo.init().call(); repo.pull().fromRepository(root.getRepository()) .withTimeout(myPullTimeout) .call(); repo.setDefaultPath(root.getRepository()); repo.setTeamCityConfig(root.getCustomHgConfig()); if (revision != null) return revision; if (myBranch == null) return null; boolean includeTags = myGlobalTagsAsBranches && root.useTagsAsBranches(); return repo.getBranchRevisions(true, includeTags).get(myBranch); } finally { myMirrorManager.unlockDir(mirrorDir); } } private String getMirrorUrl(@NotNull HgVcsRoot root) throws VcsException { try { return myMirrorManager.getMirrorDir(root.getRepository()).getCanonicalPath(); } catch (IOException e) { throw new VcsException(e); } } }