mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
GitRootConverter: cache detected roots
* GitRepositoryManager.GIT_ROOTS_CHANGE message bus Topic - to notify about git roots changes. * Fire the GIT_ROOTS_CHANGE event on every scan in GitRootScanner. * Listen to events in GitRootConverter and update the detected roots list. * Supply the GitRootDetectInfo to the GitRootErrorsFinder for better control on when to detect.
This commit is contained in:
@@ -21,40 +21,50 @@ import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.VcsDirectoryMapping;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import git4idea.roots.GitRootDetectInfo;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import git4idea.roots.GitRootDetector;
|
||||
import git4idea.roots.GitRootsListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Given VFS content roots, filters them and returns only those, which are actual Git roots.
|
||||
*/
|
||||
public class GitRootConverter implements AbstractVcs.RootsConvertor {
|
||||
public class GitRootConverter implements AbstractVcs.RootsConvertor, GitRootsListener {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
@Nullable private Collection<VirtualFile> myDetectedRoots;
|
||||
|
||||
public GitRootConverter(@NotNull Project project, @NotNull PlatformFacade facade) {
|
||||
myProject = project;
|
||||
myPlatformFacade = facade;
|
||||
myProject.getMessageBus().connect().subscribe(GitRepositoryManager.GIT_ROOTS_CHANGE, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<VirtualFile> convertRoots(@NotNull List<VirtualFile> result) {
|
||||
GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect();
|
||||
if (myDetectedRoots == null) {
|
||||
myDetectedRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots();
|
||||
}
|
||||
|
||||
ArrayList<VirtualFile> roots = new ArrayList<VirtualFile>();
|
||||
if (hasProjectMapping()) {
|
||||
roots.addAll(detectInfo.getRoots());
|
||||
roots.addAll(myDetectedRoots);
|
||||
}
|
||||
|
||||
HashSet<VirtualFile> listed = new HashSet<VirtualFile>();
|
||||
for (VirtualFile f : result) {
|
||||
VirtualFile r = GitUtil.gitRootOrNull(f);
|
||||
if (r != null && listed.add(r)) {
|
||||
roots.add(r);
|
||||
if (!roots.contains(r)) {
|
||||
roots.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
@@ -69,4 +79,9 @@ public class GitRootConverter implements AbstractVcs.RootsConvertor {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gitRootsChanged(Collection<VirtualFile> roots) {
|
||||
myDetectedRoots = roots;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package git4idea.repo;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import git4idea.roots.GitRootsListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -27,6 +29,8 @@ import java.util.List;
|
||||
*/
|
||||
public interface GitRepositoryManager {
|
||||
|
||||
Topic<GitRootsListener> GIT_ROOTS_CHANGE = Topic.create("Git Roots change", GitRootsListener.class);
|
||||
|
||||
/**
|
||||
* Returns the {@link GitRepository} which tracks the Git repository located in the given directory,
|
||||
* or {@code null} if the given file is not a Git root known to this {@link com.intellij.openapi.project.Project}.
|
||||
|
||||
@@ -35,7 +35,7 @@ public class GitRootChecker implements VcsRootChecker {
|
||||
private final boolean myProjectMappingIsInvalid;
|
||||
|
||||
public GitRootChecker(@NotNull Project project, @NotNull PlatformFacade platformFacade) {
|
||||
myErrors = new GitRootErrorsFinder(project, platformFacade).find();
|
||||
myErrors = new GitRootErrorsFinder(project, platformFacade).find(new GitRootDetector(project, platformFacade).detect());
|
||||
myProjectMappingIsInvalid = isProjectMappingInvalid();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,9 +48,9 @@ public class GitRootErrorsFinder {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<VcsRootError> find() {
|
||||
public Collection<VcsRootError> find(@NotNull GitRootDetectInfo rootDetectInfo) {
|
||||
List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings(myVcs);
|
||||
Collection<VirtualFile> gitRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots();
|
||||
Collection<VirtualFile> gitRoots = rootDetectInfo.getRoots();
|
||||
|
||||
Collection<VcsRootError> errors = new ArrayList<VcsRootError>();
|
||||
Collection<String> gitPaths = rootsToPaths(gitRoots);
|
||||
|
||||
@@ -67,17 +67,19 @@ public class GitRootProblemNotifier {
|
||||
mySettings = VcsConfiguration.getInstance(myProject);
|
||||
}
|
||||
|
||||
public void rescanAndNotifyIfNeeded() {
|
||||
public GitRootDetectInfo rescanAndNotifyIfNeeded() {
|
||||
GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect();
|
||||
|
||||
if (!mySettings.SHOW_VCS_ERROR_NOTIFICATIONS) {
|
||||
return;
|
||||
return detectInfo;
|
||||
}
|
||||
|
||||
Collection<VcsRootError> errors = scan();
|
||||
Collection<VcsRootError> errors = scan(detectInfo);
|
||||
if (errors.isEmpty()) {
|
||||
synchronized (NOTIFICATION_LOCK) {
|
||||
expireNotification();
|
||||
}
|
||||
return;
|
||||
return detectInfo;
|
||||
}
|
||||
|
||||
Collection<String> unregisteredRoots = getUnregisteredRoots(errors);
|
||||
@@ -89,9 +91,10 @@ public class GitRootProblemNotifier {
|
||||
synchronized (NOTIFICATION_LOCK) {
|
||||
expireNotification();
|
||||
myNotification = createNotification(IMPORTANT_ERROR_NOTIFICATION, title, description, ERROR,
|
||||
new MyNotificationListener(myProject, mySettings));
|
||||
new MyNotificationListener(myProject, mySettings, myPlatformFacade));
|
||||
myPlatformFacade.getNotificator(myProject).notify(myNotification);
|
||||
}
|
||||
return detectInfo;
|
||||
}
|
||||
|
||||
private void expireNotification() {
|
||||
@@ -109,8 +112,8 @@ public class GitRootProblemNotifier {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<VcsRootError> scan() {
|
||||
return new GitRootErrorsFinder(myProject, myPlatformFacade).find();
|
||||
private Collection<VcsRootError> scan(GitRootDetectInfo detectInfo) {
|
||||
return new GitRootErrorsFinder(myProject, myPlatformFacade).find(detectInfo);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
|
||||
@@ -195,10 +198,12 @@ public class GitRootProblemNotifier {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final VcsConfiguration mySettings;
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings) {
|
||||
private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings, @NotNull PlatformFacade facade) {
|
||||
myProject = project;
|
||||
mySettings = settings;
|
||||
myPlatformFacade = facade;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,7 +211,8 @@ public class GitRootProblemNotifier {
|
||||
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
if (event.getDescription().equals("configure")) {
|
||||
ShowSettingsUtil.getInstance().showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text"));
|
||||
Collection<VcsRootError> errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan();
|
||||
Collection<VcsRootError> errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan(
|
||||
new GitRootDetector(myProject, myPlatformFacade).detect());
|
||||
if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) {
|
||||
notification.expire();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -40,6 +41,7 @@ import java.util.List;
|
||||
*/
|
||||
public class GitRootScanner implements BulkFileListener, ModuleRootListener, Disposable, VcsListener {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final Runnable myExecuteAfterScan;
|
||||
@NotNull private final GitRootProblemNotifier myRootProblemNotifier;
|
||||
|
||||
@@ -49,6 +51,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
@NotNull private final Object SCAN_LOCK = new Object();
|
||||
|
||||
public GitRootScanner(@NotNull Project project, @NotNull Runnable executeAfterScan) {
|
||||
myProject = project;
|
||||
myExecuteAfterScan = executeAfterScan;
|
||||
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
@@ -129,7 +132,8 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
return;
|
||||
}
|
||||
myScanning = true;
|
||||
myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
GitRootDetectInfo detectInfo = myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
myProject.getMessageBus().syncPublisher(GitRepositoryManager.GIT_ROOTS_CHANGE).gitRootsChanged(detectInfo.getRoots());
|
||||
myExecuteAfterScan.run();
|
||||
myScanning = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 git4idea.roots;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public interface GitRootsListener {
|
||||
|
||||
void gitRootsChanged(Collection<VirtualFile> roots);
|
||||
|
||||
}
|
||||
@@ -172,7 +172,8 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest {
|
||||
expected.addAll map.errors.unreg.collect { unreg(it) }
|
||||
expected.addAll map.errors.extra.collect { extra(it) }
|
||||
|
||||
Collection<VcsRootError> actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find()
|
||||
Collection<VcsRootError> actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find(
|
||||
new GitRootDetector(myProject, myPlatformFacade).detect())
|
||||
assertEquals expected.toSet(), actual.toSet()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user