vcs: skip ignored directories in VcsRootScanner listener

GitOrigin-RevId: 6e9ac9d26b12127c20f7a4bbe3707b428480ee53
This commit is contained in:
Aleksey Pivovarov
2020-03-10 12:33:08 +00:00
committed by intellij-monorepo-bot
parent c287906b0f
commit 52eb927cd6
2 changed files with 43 additions and 34 deletions
@@ -5,7 +5,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsRoot;
@@ -16,12 +15,12 @@ import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import static com.intellij.openapi.vfs.VirtualFileVisitor.CONTINUE;
import static com.intellij.openapi.vfs.VirtualFileVisitor.SKIP_CHILDREN;
public class VcsRootDetectorImpl implements VcsRootDetector {
private static final Logger LOG = Logger.getInstance(VcsRootDetectorImpl.class);
@@ -29,19 +28,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector {
@NotNull private final Project myProject;
@NotNull private final ProjectLevelVcsManager myVcsManager;
private final Pattern myIgnorePattern = parseIgnorePattern();
@NotNull
private static Pattern parseIgnorePattern() {
try {
return Pattern.compile(Registry.stringValue("vcs.root.detector.ignore.pattern"));
}
catch (MissingResourceException | PatternSyntaxException e) {
LOG.warn(e);
return Pattern.compile(".{0}"); // match nothing
}
}
@Nullable private Collection<VcsRoot> myDetectedRoots;
@NotNull private final Object LOCK = new Object();
@@ -114,7 +100,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector {
private Set<VcsRoot> scanForRootsInsideDir(@NotNull VirtualFile root) {
Set<VcsRoot> roots = new HashSet<>();
VcsRootScanner.visitDirsRecursivelyWithoutExcluded(myProject, ProjectRootManager.getInstance(myProject), root, dir -> {
if (isIgnoredDirectory(dir)) return SKIP_CHILDREN;
VcsRoot vcsRoot = getVcsRootFor(dir);
if (vcsRoot != null) {
LOG.debug("Found VCS " + vcsRoot.getVcs() + " in " + vcsRoot.getPath());
@@ -129,18 +114,6 @@ public class VcsRootDetectorImpl implements VcsRootDetector {
return rootsInsideDir.stream().noneMatch(it -> startDir.equals(it.getPath()));
}
private boolean isIgnoredDirectory(@NotNull VirtualFile dir) {
if (myVcsManager.isIgnored(dir)) {
LOG.debug("Skipping ignored dir: ", dir);
return true;
}
if (myIgnorePattern.matcher(dir.getName()).matches()) {
LOG.debug("Skipping dir by pattern: ", dir);
return true;
}
return false;
}
@Nullable
private VcsRoot scanForSingleRootAboveDir(@NotNull final VirtualFile dir) {
if (myProject.isDisposed()) {
@@ -16,12 +16,14 @@
package com.intellij.openapi.vcs.roots;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.BackgroundTaskUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsRootChecker;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -31,14 +33,20 @@ import com.intellij.util.Alarm;
import com.intellij.vfs.AsyncVfsEventsListener;
import com.intellij.vfs.AsyncVfsEventsPostProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.MissingResourceException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static com.intellij.openapi.diagnostic.Logger.getInstance;
import static com.intellij.openapi.vfs.VirtualFileVisitor.*;
public class VcsRootScanner implements AsyncVfsEventsListener {
private static final Logger LOG = getInstance(VcsRootScanner.class);
@NotNull private final VcsRootProblemNotifier myRootProblemNotifier;
@NotNull private final Project myProject;
@@ -85,6 +93,7 @@ public class VcsRootScanner implements AsyncVfsEventsListener {
@NotNull Function<? super VirtualFile, ? extends Result> dirFound) {
ProjectFileIndex fileIndex = projectRootManager.getFileIndex();
Option depthLimit = limit(Registry.intValue("vcs.root.detector.folder.depth"));
Pattern ignorePattern = parseDirIgnorePattern();
VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor<Void>(NO_FOLLOW_SYMLINKS, depthLimit) {
@NotNull
@Override
@@ -94,6 +103,10 @@ public class VcsRootScanner implements AsyncVfsEventsListener {
return CONTINUE;
}
if (isIgnoredDirectory(project, ignorePattern, file)) {
return SKIP_CHILDREN;
}
VirtualFileVisitor.Result result = dirFound.apply(file);
if (result != CONTINUE) {
return result;
@@ -118,8 +131,31 @@ public class VcsRootScanner implements AsyncVfsEventsListener {
}
myAlarm.cancelAllRequests(); // one scan is enough, no need to queue, they all do the same
myAlarm.addRequest(() ->
BackgroundTaskUtil.runUnderDisposeAwareIndicator(myAlarm, () ->
myRootProblemNotifier.rescanAndNotifyIfNeeded()), WAIT_BEFORE_SCAN);
myAlarm.addRequest(() -> BackgroundTaskUtil.runUnderDisposeAwareIndicator(myAlarm, () ->
myRootProblemNotifier.rescanAndNotifyIfNeeded()), WAIT_BEFORE_SCAN);
}
private static boolean isIgnoredDirectory(@NotNull Project project, @Nullable Pattern ignorePattern, @NotNull VirtualFile dir) {
if (ProjectLevelVcsManager.getInstance(project).isIgnored(dir)) {
LOG.debug("Skipping ignored dir: ", dir);
return true;
}
if (ignorePattern != null && ignorePattern.matcher(dir.getName()).matches()) {
LOG.debug("Skipping dir by pattern: ", dir);
return true;
}
return false;
}
@Nullable
private static Pattern parseDirIgnorePattern() {
try {
return Pattern.compile(Registry.stringValue("vcs.root.detector.ignore.pattern"));
}
catch (MissingResourceException | PatternSyntaxException e) {
LOG.warn(e);
return null;
}
}
}