GitRootProblemNotifier; use if GitRepository is invalid.

GitRootProblemNotifier searches for Git roots problems via the GitRootErrorsFinder and notifies about them.
GitRepositoryManager creates a GitRepository instance only if the root is valid, otherwise shows the notification.
This commit is contained in:
Kirill Likhodedov
2012-03-06 17:53:26 +04:00
parent b51e5de726
commit 7b52b13e65
2 changed files with 181 additions and 8 deletions
@@ -18,13 +18,16 @@ package git4idea.repo;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsListener;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import git4idea.GitVcs;
import git4idea.PlatformFacade;
import git4idea.roots.GitRootProblemNotifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,23 +42,27 @@ import static git4idea.GitUtil.sortRepositories;
*/
public final class GitRepositoryManager extends AbstractProjectComponent implements Disposable, VcsListener {
private final GitVcs myVcs;
private final ProjectLevelVcsManager myVcsManager;
private static final Logger LOG = Logger.getInstance(GitRepositoryManager.class);
private final @NotNull AbstractVcs myVcs;
private final @NotNull ProjectLevelVcsManager myVcsManager;
private final @NotNull PlatformFacade myPlatformFacade;
private final Map<VirtualFile, GitRepository> myRepositories = new HashMap<VirtualFile, GitRepository>();
private final Set<GitRepositoryChangeListener> myListeners = new HashSet<GitRepositoryChangeListener>();
private final ReentrantReadWriteLock REPO_LOCK = new ReentrantReadWriteLock();
@NotNull
public static GitRepositoryManager getInstance(@NotNull Project project) {
return ServiceManager.getService(project, GitRepositoryManager.class);
}
public GitRepositoryManager(@NotNull Project project) {
public GitRepositoryManager(@NotNull Project project, @NotNull PlatformFacade platformFacade) {
super(project);
myPlatformFacade = platformFacade;
myVcsManager = ProjectLevelVcsManager.getInstance(myProject);
myVcs = GitVcs.getInstance(myProject);
assert myVcs != null;
myVcs = myPlatformFacade.getVcs(myProject);
}
@Override
@@ -166,8 +173,14 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
// add GitRepositories for all roots that don't have correspondent GitRepositories yet.
for (VirtualFile root : roots) {
if (!myRepositories.containsKey(root)) {
GitRepository repository = createGitRepository(root);
myRepositories.put(root, repository);
if (gitRootOK(root)) {
GitRepository repository = createGitRepository(root);
myRepositories.put(root, repository);
}
else {
LOG.info("Invalid Git root: " + root);
GitRootProblemNotifier.getInstance(myProject, myPlatformFacade).rescanAndNotifyIfNeeded();
}
}
}
}
@@ -176,6 +189,11 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
}
}
private static boolean gitRootOK(@NotNull VirtualFile root) {
VirtualFile gitDir = root.findChild(".git");
return gitDir != null && gitDir.exists();
}
private GitRepository createGitRepository(VirtualFile root) {
GitRepository repository = GitRepository.getFullInstance(root, myProject, this);
for (GitRepositoryChangeListener listener : myListeners) {
@@ -0,0 +1,155 @@
/*
* 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.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsRootError;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
import git4idea.GitVcs;
import git4idea.PlatformFacade;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.HyperlinkEvent;
import java.util.ArrayList;
import java.util.Collection;
import static com.intellij.openapi.util.text.StringUtil.pluralize;
/**
* Searches for Git roots problems via {@link GitRootErrorsFinder} and notifies about them.
*
* @author Kirill Likhodedov
*/
public class GitRootProblemNotifier {
private final @NotNull Project myProject;
private final @NotNull PlatformFacade myPlatformFacade;
public static GitRootProblemNotifier getInstance(@NotNull Project project, @NotNull PlatformFacade platformFacade) {
return new GitRootProblemNotifier(project, platformFacade);
}
public GitRootProblemNotifier(@NotNull Project project, @NotNull PlatformFacade platformFacade) {
myProject = project;
myPlatformFacade = platformFacade;
}
public void rescanAndNotifyIfNeeded() {
Collection<VcsRootError> errors = new GitRootErrorsFinder(myProject, myPlatformFacade).find();
if (errors.isEmpty()) {
return;
}
Collection<VirtualFile> unregisteredRoots = getUnregisteredRoots(errors);
Collection<VirtualFile> invalidRoots = getInvalidRoots(errors);
String title = makeTitle(unregisteredRoots, invalidRoots);
String description = makeDescription(unregisteredRoots, invalidRoots);
myPlatformFacade.getNotificator(myProject).notify(GitVcs.IMPORTANT_ERROR_NOTIFICATION, title, description,
NotificationType.ERROR, new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED && event.getDescription().equals("configure")) {
ShowSettingsUtil.getInstance().showSettingsDialog(myProject, "Version Control");
}
}
});
}
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
private static String makeDescription(Collection<VirtualFile> unregisteredRoots, Collection<VirtualFile> invalidRoots) {
Function<VirtualFile, String> rootToString = new Function<VirtualFile, String>() {
@Override
public String fun(VirtualFile virtualFile) {
return FileUtil.toSystemDependentName(virtualFile.getPath());
}
};
StringBuilder description = new StringBuilder();
if (!invalidRoots.isEmpty()) {
if (invalidRoots.size() == 1) {
description.append("The directory " + invalidRoots.iterator().next() + " is registered as a Git root, " +
"but it doesn't have .git directory inside.");
}
else {
description.append("The following directories are registered as Git roots, but they don't have .git directotires inside: <br/>" +
StringUtil.join(invalidRoots, rootToString, ", "));
}
description.append("<br/>");
}
if (!unregisteredRoots.isEmpty()) {
if (unregisteredRoots.size() == 1) {
description.append("The directory " + unregisteredRoots.iterator().next() + " is under Git, " +
"but is not registered in the Settings.");
}
else {
description.append("The following directories are roots of Git repositories, but they are not registered in the Settings: <br/>" +
StringUtil.join(unregisteredRoots, rootToString, ", "));
}
description.append("<br/>");
}
description.append("<a href='configure'>Configure</a>");
return description.toString();
}
private static String makeTitle(Collection<VirtualFile> unregisteredRoots, Collection<VirtualFile> invalidRoots) {
String title;
String roots = pluralize("root", invalidRoots.size());
if (unregisteredRoots.isEmpty()) {
title = "Invalid Git " + roots;
}
else if (invalidRoots.isEmpty()) {
title = "Unregistered Git " + roots + " detected";
}
else {
title = "Git root configuration problems";
}
return title;
}
@NotNull
private static Collection<VirtualFile> getUnregisteredRoots(@NotNull Collection<VcsRootError> errors) {
return filterErrorsByType(errors, VcsRootError.Type.UNREGISTERED_ROOT);
}
@NotNull
private static Collection<VirtualFile> getInvalidRoots(@NotNull Collection<VcsRootError> errors) {
return filterErrorsByType(errors, VcsRootError.Type.EXTRA_ROOT);
}
@NotNull
private static Collection<VirtualFile> filterErrorsByType(@NotNull Collection<VcsRootError> errors, @NotNull VcsRootError.Type type) {
Collection<VirtualFile> roots = new ArrayList<VirtualFile>();
for (VcsRootError error : errors) {
if (error.getType() == type) {
roots.add(error.getRoot());
}
}
return roots;
}
}