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
This commit is contained in:
Nadya Zabrodina
2014-01-30 16:44:29 +04:00
parent ec25543549
commit 77af356936
10 changed files with 99 additions and 89 deletions
@@ -13,6 +13,8 @@
<projectService serviceImplementation="com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationSettings"/>
<projectService serviceImplementation="com.intellij.openapi.diff.impl.settings.MergeToolSettings"/>
<projectService serviceImplementation="com.intellij.openapi.diff.impl.settings.DiffToolSettings"/>
<projectService serviceInterface="com.intellij.openapi.vcs.roots.VcsRootDetectorI"
serviceImplementation="com.intellij.openapi.vcs.roots.VcsRootDetectorImpl"/>
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
@@ -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<VcsRoot> 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<VcsRoot> roots, boolean below) {
myRoots = new ArrayList<VcsRoot>(roots);
myBelow = below;
}
public boolean empty() {
return myRoots.isEmpty();
}
@NotNull
public Collection<VcsRoot> getRoots() {
return new ArrayList<VcsRoot>(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;
}
}
@@ -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<VcsRoot> detect();
/**
* Detect vcs roots for startDir
*/
@NotNull
Collection<VcsRoot> detect(@Nullable VirtualFile startDir);
}
@@ -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<VcsRoot> roots = info.getRoots();
Collection<VcsRoot> roots = ServiceManager.getService(project, VcsRootDetectorI.class).detect(rootDir);
Collection<VcsDirectoryMapping> result = ContainerUtilRt.newArrayList();
for (VcsRoot vcsRoot : roots) {
VirtualFile vFile = vcsRoot.getPath();
@@ -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<VcsRoot> detect() {
return detect(myProject.getBaseDir());
}
@NotNull
public VcsRootDetectInfo detect(@Nullable VirtualFile startDir) {
public Collection<VcsRoot> detect(@Nullable VirtualFile startDir) {
if (startDir == null) {
return new VcsRootDetectInfo(Collections.<VcsRoot>emptyList(), false);
return Collections.emptyList();
}
final Set<VcsRoot> roots = scanForRootsInsideDir(startDir);
roots.addAll(scanForRootsInContentRoots());
for (VcsRoot root : roots) {
if (startDir.equals(root.getPath())) {
return new VcsRootDetectInfo(roots, false);
return roots;
}
}
List<VcsRoot> 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
@@ -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<VcsRootError> find() {
List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings();
Collection<VcsRoot> vcsRoots = new VcsRootDetector(myProject).detect().getRoots();
Collection<VcsRoot> vcsRoots = ServiceManager.getService(myProject, VcsRootDetectorI.class).detect();
Collection<VcsRootError> errors = new ArrayList<VcsRootError>();
errors.addAll(findExtraMappings(mappings));
@@ -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<VcsRoot> 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<String> expectedPaths)
throws IOException {
initProject(vcsRootConfiguration);
VcsRootDetectInfo info = detect(startDir);
Collection<VcsRoot> vcsRoots = detect(startDir);
assertRoots(expectedPaths, getPaths(
ContainerUtil.filter(info.getRoots(), new Condition<VcsRoot>() {
ContainerUtil.filter(vcsRoots, new Condition<VcsRoot>() {
@Override
public boolean value(VcsRoot root) {
assert root.getVcs() != null;
+4 -4
View File
@@ -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<CommittedChangeList> {
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<VcsRoot> roots = ServiceManager.getService(myProject, VcsRootDetectorI.class).detect();
new GitIntegrationEnabler(myProject, myGit, myPlatformFacade).enable(roots);
}
});
}
@@ -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<VcsRoot> vcsRoots) {
Notificator notificator = myPlatformFacade.getNotificator(myProject);
Collection<VcsRoot> gitRoots = ContainerUtil.filter(detectInfo.getRoots(), new Condition<VcsRoot>() {
Collection<VcsRoot> gitRoots = ContainerUtil.filter(vcsRoots, new Condition<VcsRoot>() {
@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<VirtualFile> 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<VirtualFile> roots) {
notificator.notifySuccess("", String.format("Added Git %s: %s", pluralize("root", roots.size()), joinRootsPaths(roots)));
}
@@ -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<String, List<String>> map = new HashMap<String, List<String>>();
map.put("git_init", Collections.<String>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.<String>emptyList(), false),
doTest(given(Collections.<String>emptyList()),
map, notification("Created Git repository in " + myProjectRoot));
}
@@ -83,7 +82,7 @@ public class GitIntegrationEnablerTest extends GitLightTest {
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("git_init", Collections.<String>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<String, List<String>> map = new HashMap<String, List<String>>();
map.put("git_init", Collections.<String>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<String, List<String>> map = new HashMap<String, List<String>>();
map.put("git_init", Collections.<String>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<String, List<String>> map = new HashMap<String, List<String>>();
map.put("git_init", Collections.<String>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<String, List<String>> map, @Nullable Notification notification) {
private void doTest(@NotNull Collection<VcsRoot> vcsRoots, @NotNull Map<String, List<String>> map, @Nullable Notification notification) {
//default
if (map.get("vcs_roots") == null) {
map.put("vcs_roots", ContainerUtil.map(detectInfo.getRoots(), new Function<VcsRoot, String>() {
map.put("vcs_roots", ContainerUtil.map(vcsRoots, new Function<VcsRoot, String>() {
@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<String> roots, boolean below) {
return new VcsRootDetectInfo(ContainerUtil.map(roots, new Function<String, VcsRoot>() {
Collection<VcsRoot> given(@NotNull Collection<String> roots) {
return ContainerUtil.map(roots, new Function<String, VcsRoot>() {
@Override
public VcsRoot fun(String s) {
return new VcsRoot(myVcs, new MockVirtualFile(VcsTestUtil.toAbsolute(s, myProject)));
}
}), below);
});
}
Notification notification(String content) {