From 77af3569363c859cbdb3bb3ba71fcd135a1d68a1 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 30 Jan 2014 16:36:41 +0400 Subject: [PATCH] VcsRootDetector refactoring *VcsRootDetector Implementation moved to vcs-impl; *VcsRooDetector interface added; *below detector removed from appropriate class; *VcsRootDetectorInfo removed as unnecessary; *method for below project dir detection created in VcsIntegrationEnabler class --- .../src/META-INF/VcsExtensions.xml | 2 + .../openapi/vcs/roots/VcsRootDetectInfo.java | 44 ------------------- .../openapi/vcs/roots/VcsRootDetectorI.java | 28 ++++++++++++ .../src/com/intellij/vcsUtil/VcsUtil.java | 8 ++-- .../vcs/roots/VcsRootDetectorImpl.java} | 40 +++++++++++------ .../vcs/roots/VcsRootErrorsFinder.java | 3 +- .../vcs/roots/VcsRootDetectorTest.java | 9 ++-- plugins/git4idea/src/git4idea/GitVcs.java | 8 ++-- .../git4idea/roots/GitIntegrationEnabler.java | 19 ++++++-- .../roots/GitIntegrationEnablerTest.java | 27 ++++++------ 10 files changed, 99 insertions(+), 89 deletions(-) delete mode 100644 platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectInfo.java create mode 100644 platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectorI.java rename platform/{vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetector.java => vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java} (75%) diff --git a/platform/platform-resources/src/META-INF/VcsExtensions.xml b/platform/platform-resources/src/META-INF/VcsExtensions.xml index b2d032028189..664a9b35c7fc 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensions.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensions.xml @@ -13,6 +13,8 @@ + diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectInfo.java b/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectInfo.java deleted file mode 100644 index eae6956f1893..000000000000 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.intellij.openapi.vcs.roots; - -import com.intellij.openapi.vcs.VcsRoot; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * @author Nadya Zabrodina - */ -public class VcsRootDetectInfo { - - private final @NotNull Collection myRoots; - private final boolean myBelow; - - /** - * @param roots Vcs roots important for the project. - * @param below Pass true to indicate that the project dir is below Vcs dir, - */ - public VcsRootDetectInfo(@NotNull Collection roots, boolean below) { - myRoots = new ArrayList(roots); - myBelow = below; - } - - public boolean empty() { - return myRoots.isEmpty(); - } - - @NotNull - public Collection getRoots() { - return new ArrayList(myRoots); - } - - /** - * Below implies totally under Vcs. - * - * @return true if the uppermost interesting Vcs root is above the project dir, - * false if all vcs internal directories are immediately under the project dir or deeper. - */ - public boolean projectIsBelowVcs() { - return myBelow; - } -} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectorI.java b/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectorI.java new file mode 100644 index 000000000000..493eaec0928c --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetectorI.java @@ -0,0 +1,28 @@ +package com.intellij.openapi.vcs.roots; + +import com.intellij.openapi.vcs.VcsRoot; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * Interface for detecting VCS roots in the project. + * + * @author Nadya Zabrodina + */ +public interface VcsRootDetectorI { + + /** + * Detect vcs roots for whole project + */ + @NotNull + Collection detect(); + + /** + * Detect vcs roots for startDir + */ + @NotNull + Collection detect(@Nullable VirtualFile startDir); +} diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java index bcec7b54a340..05e8461dd195 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -37,13 +38,11 @@ import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; -import com.intellij.openapi.vcs.roots.VcsRootDetectInfo; -import com.intellij.openapi.vcs.roots.VcsRootDetector; +import com.intellij.openapi.vcs.roots.VcsRootDetectorI; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.openapi.wm.StatusBar; import com.intellij.util.ConcurrencyUtil; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -630,8 +629,7 @@ public class VcsUtil { + rootDir.getParent() ); } - VcsRootDetectInfo info = new VcsRootDetector(project).detect(rootDir); - Collection roots = info.getRoots(); + Collection roots = ServiceManager.getService(project, VcsRootDetectorI.class).detect(rootDir); Collection result = ContainerUtilRt.newArrayList(); for (VcsRoot vcsRoot : roots) { VirtualFile vFile = vcsRoot.getPath(); diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java similarity index 75% rename from platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetector.java rename to platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java index a9524e53d6e3..753b4d3ff4c1 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/roots/VcsRootDetector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2014 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 com.intellij.openapi.vcs.roots; import com.intellij.openapi.extensions.Extensions; @@ -16,43 +31,42 @@ import java.util.*; /** * @author Nadya Zabrodina */ -public class VcsRootDetector { +public class VcsRootDetectorImpl implements VcsRootDetectorI { private static final int MAXIMUM_SCAN_DEPTH = 2; @NotNull private final Project myProject; @NotNull private final ProjectRootManager myProjectManager; @NotNull private final ProjectLevelVcsManager myVcsManager; - public VcsRootDetector(@NotNull Project project) { + public VcsRootDetectorImpl(@NotNull Project project, + @NotNull ProjectRootManager projectRootManager, + @NotNull ProjectLevelVcsManager projectLevelVcsManager) { myProject = project; - myProjectManager = ProjectRootManager.getInstance(project); - myVcsManager = ProjectLevelVcsManager.getInstance(project); + myProjectManager = projectRootManager; + myVcsManager = projectLevelVcsManager; } @NotNull - public VcsRootDetectInfo detect() { + public Collection detect() { return detect(myProject.getBaseDir()); } @NotNull - public VcsRootDetectInfo detect(@Nullable VirtualFile startDir) { + public Collection detect(@Nullable VirtualFile startDir) { if (startDir == null) { - return new VcsRootDetectInfo(Collections.emptyList(), false); + return Collections.emptyList(); } final Set roots = scanForRootsInsideDir(startDir); roots.addAll(scanForRootsInContentRoots()); for (VcsRoot root : roots) { if (startDir.equals(root.getPath())) { - return new VcsRootDetectInfo(roots, false); + return roots; } } List rootsAbove = scanForSingleRootAboveDir(startDir); - if (!rootsAbove.isEmpty()) { - roots.addAll(rootsAbove); - return new VcsRootDetectInfo(roots, true); - } - return new VcsRootDetectInfo(roots, false); + roots.addAll(rootsAbove); + return roots; } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java index 14be8a0d24be..2742b1897601 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java @@ -1,5 +1,6 @@ package com.intellij.openapi.vcs.roots; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -30,7 +31,7 @@ public class VcsRootErrorsFinder { @NotNull public Collection find() { List mappings = myVcsManager.getDirectoryMappings(); - Collection vcsRoots = new VcsRootDetector(myProject).detect().getRoots(); + Collection vcsRoots = ServiceManager.getService(myProject, VcsRootDetectorI.class).detect(); Collection errors = new ArrayList(); errors.addAll(findExtraMappings(mappings)); diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/roots/VcsRootDetectorTest.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/roots/VcsRootDetectorTest.java index a5a3abdf1ff1..a7118f2346ad 100644 --- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/roots/VcsRootDetectorTest.java +++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/roots/VcsRootDetectorTest.java @@ -16,6 +16,7 @@ package com.intellij.openapi.vcs.roots; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; @@ -169,8 +170,8 @@ public class VcsRootDetectorTest extends VcsRootPlatformTest { } @NotNull - private VcsRootDetectInfo detect(@Nullable VirtualFile startDir) { - return new VcsRootDetector(myProject).detect(startDir); + private Collection detect(@Nullable VirtualFile startDir) { + return ServiceManager.getService(myProject, VcsRootDetectorI.class).detect(startDir); } public void doTest(@NotNull VcsRootConfiguration vcsRootConfiguration, @@ -178,9 +179,9 @@ public class VcsRootDetectorTest extends VcsRootPlatformTest { @NotNull Collection expectedPaths) throws IOException { initProject(vcsRootConfiguration); - VcsRootDetectInfo info = detect(startDir); + Collection vcsRoots = detect(startDir); assertRoots(expectedPaths, getPaths( - ContainerUtil.filter(info.getRoots(), new Condition() { + ContainerUtil.filter(vcsRoots, new Condition() { @Override public boolean value(VcsRoot root) { assert root.getVcs() != null; diff --git a/plugins/git4idea/src/git4idea/GitVcs.java b/plugins/git4idea/src/git4idea/GitVcs.java index 6d62a07bf422..99c43f93ee13 100644 --- a/plugins/git4idea/src/git4idea/GitVcs.java +++ b/plugins/git4idea/src/git4idea/GitVcs.java @@ -46,8 +46,7 @@ import com.intellij.openapi.vcs.history.VcsHistoryProvider; import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vcs.merge.MergeProvider; import com.intellij.openapi.vcs.rollback.RollbackEnvironment; -import com.intellij.openapi.vcs.roots.VcsRootDetectInfo; -import com.intellij.openapi.vcs.roots.VcsRootDetector; +import com.intellij.openapi.vcs.roots.VcsRootDetectorI; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vcs.update.UpdateEnvironment; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; @@ -89,6 +88,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.event.HyperlinkEvent; import java.io.File; import java.text.SimpleDateFormat; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -586,8 +586,8 @@ public class GitVcs extends AbstractVcs { public void enableIntegration() { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { public void run() { - VcsRootDetectInfo detectInfo = new VcsRootDetector(myProject).detect(); - new GitIntegrationEnabler(myProject, myGit, myPlatformFacade).enable(detectInfo); + Collection roots = ServiceManager.getService(myProject, VcsRootDetectorI.class).detect(); + new GitIntegrationEnabler(myProject, myGit, myPlatformFacade).enable(roots); } }); } diff --git a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java index 15c98d9c8e92..c06a0aec1ed7 100644 --- a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java +++ b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java @@ -22,8 +22,8 @@ import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vcs.VcsRoot; -import com.intellij.openapi.vcs.roots.VcsRootDetectInfo; import com.intellij.openapi.vcs.roots.VcsRootErrorsFinder; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; @@ -56,9 +56,9 @@ public class GitIntegrationEnabler { myPlatformFacade = platformFacade; } - public void enable(@NotNull VcsRootDetectInfo detectInfo) { + public void enable(@NotNull Collection vcsRoots) { Notificator notificator = myPlatformFacade.getNotificator(myProject); - Collection gitRoots = ContainerUtil.filter(detectInfo.getRoots(), new Condition() { + Collection gitRoots = ContainerUtil.filter(vcsRoots, new Condition() { @Override public boolean value(VcsRoot root) { AbstractVcs vcs = root.getVcs(); @@ -77,13 +77,24 @@ public class GitIntegrationEnabler { } else { assert !roots.isEmpty(); - if (roots.size() > 1 || detectInfo.projectIsBelowVcs()) { + if (roots.size() > 1 || isProjectBelowVcs(roots)) { notifyAddedRoots(notificator, roots); } addVcsRoots(roots); } } + private boolean isProjectBelowVcs(@NotNull Collection gitRoots) { + //check if there are vcs roots strictly above the project dir + VirtualFile baseDir = myProject.getBaseDir(); + for (VirtualFile root : gitRoots) { + if (VfsUtilCore.isAncestor(root, baseDir, true)) { + return true; + } + } + return false; + } + private static void notifyAddedRoots(Notificator notificator, Collection roots) { notificator.notifySuccess("", String.format("Added Git %s: %s", pluralize("root", roots.size()), joinRootsPaths(roots))); } diff --git a/plugins/git4idea/tests/git4idea/roots/GitIntegrationEnablerTest.java b/plugins/git4idea/tests/git4idea/roots/GitIntegrationEnablerTest.java index 8643348ba2f5..37b1d926303a 100644 --- a/plugins/git4idea/tests/git4idea/roots/GitIntegrationEnablerTest.java +++ b/plugins/git4idea/tests/git4idea/roots/GitIntegrationEnablerTest.java @@ -22,7 +22,6 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.VcsRoot; import com.intellij.openapi.vcs.VcsTestUtil; -import com.intellij.openapi.vcs.roots.VcsRootDetectInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -38,7 +37,7 @@ import org.junit.Test; import java.io.File; import java.util.*; -import static junit.framework.Assert.*; +import static org.junit.Assert.*; /** * @author Nadya Zabrodina @@ -63,7 +62,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { public void oneRootForTheWholeProjectThenJustAddVcsrRoot() { Map> map = new HashMap>(); map.put("git_init", Collections.emptyList()); - doTest(given(Arrays.asList("."), false), + doTest(given(Arrays.asList(".")), map, null); } @@ -74,7 +73,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { map.put("vcs_roots", VcsTestUtil.toAbsolute(Arrays.asList("."), myProject)); - doTest(given(Collections.emptyList(), false), + doTest(given(Collections.emptyList()), map, notification("Created Git repository in " + myProjectRoot)); } @@ -83,7 +82,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { Map> map = new HashMap>(); map.put("git_init", Collections.emptyList()); - doTest(given(Arrays.asList(".."), true), + doTest(given(Arrays.asList("..")), map, notification("Added Git root: " + myTestRoot)); } @@ -92,7 +91,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { Map> map = new HashMap>(); map.put("git_init", Collections.emptyList()); - doTest(given(Arrays.asList(".", "community"), false), + doTest(given(Arrays.asList(".", "community")), map, notification("Added Git roots: " + myProjectRoot + ", " + getPresentationForRoot("community"))); } @@ -101,7 +100,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { Map> map = new HashMap>(); map.put("git_init", Collections.emptyList()); - doTest(given(Arrays.asList("..", "community"), true), + doTest(given(Arrays.asList("..", "community")), map, notification("Added Git roots: " + myTestRoot + ", " + getPresentationForRoot("community"))); } @@ -110,16 +109,16 @@ public class GitIntegrationEnablerTest extends GitLightTest { Map> map = new HashMap>(); map.put("git_init", Collections.emptyList()); - doTest(given(Arrays.asList("community", "contrib"), false), + doTest(given(Arrays.asList("community", "contrib")), map, notification( "Added Git roots: " + getPresentationForRoot("community") + ", " + getPresentationForRoot("contrib"))); } - private void doTest(@NotNull VcsRootDetectInfo detectInfo, @NotNull Map> map, @Nullable Notification notification) { + private void doTest(@NotNull Collection vcsRoots, @NotNull Map> map, @Nullable Notification notification) { //default if (map.get("vcs_roots") == null) { - map.put("vcs_roots", ContainerUtil.map(detectInfo.getRoots(), new Function() { + map.put("vcs_roots", ContainerUtil.map(vcsRoots, new Function() { @Override public String fun(VcsRoot root) { @@ -129,7 +128,7 @@ public class GitIntegrationEnablerTest extends GitLightTest { })); } - new GitIntegrationEnabler(myProject, myGit, myPlatformFacade).enable(detectInfo); + new GitIntegrationEnabler(myProject, myGit, myPlatformFacade).enable(vcsRoots); assertVcsRoots(map.get("vcs_roots")); assertGitInit(map.get("git_init")); @@ -148,14 +147,14 @@ public class GitIntegrationEnablerTest extends GitLightTest { VcsTestUtil.assertEqualCollections(expectedVcsRoots, getPaths(actualRoots)); } - VcsRootDetectInfo given(@NotNull Collection roots, boolean below) { - return new VcsRootDetectInfo(ContainerUtil.map(roots, new Function() { + Collection given(@NotNull Collection roots) { + return ContainerUtil.map(roots, new Function() { @Override public VcsRoot fun(String s) { return new VcsRoot(myVcs, new MockVirtualFile(VcsTestUtil.toAbsolute(s, myProject))); } - }), below); + }); } Notification notification(String content) {