diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java index a20bae9bee45..c14bfd49c21d 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalSystemSettingsListenerAdapter.java @@ -24,7 +24,7 @@ import java.util.Set; * @author Denis Zhdanov * @since 6/13/13 7:37 PM */ -public class ExternalSystemSettingsListenerAdapter implements ExternalSystemSettingsListener { +public abstract class ExternalSystemSettingsListenerAdapter implements ExternalSystemSettingsListener { @Override public void onProjectsLinked(@NotNull Collection settings) { diff --git a/platform/external-system-impl/external-system-impl.iml b/platform/external-system-impl/external-system-impl.iml index d27fd1119996..0813fb4ab833 100644 --- a/platform/external-system-impl/external-system-impl.iml +++ b/platform/external-system-impl/external-system-impl.iml @@ -15,6 +15,8 @@ + + diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemStartupActivity.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemStartupActivity.java index d3f63f3aee82..716990de6dc3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemStartupActivity.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemStartupActivity.java @@ -19,6 +19,7 @@ import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; import com.intellij.openapi.externalSystem.service.project.autoimport.ExternalSystemAutoImporter; import com.intellij.openapi.externalSystem.service.ui.ExternalToolWindowManager; +import com.intellij.openapi.externalSystem.service.vcs.ExternalSystemVcsRegistrar; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.project.Project; @@ -49,6 +50,7 @@ public class ExternalSystemStartupActivity implements StartupActivity { } ExternalSystemAutoImporter.letTheMagicBegin(project); ExternalToolWindowManager.handle(project); + ExternalSystemVcsRegistrar.handle(project); } }; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/vcs/ExternalSystemVcsRegistrar.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/vcs/ExternalSystemVcsRegistrar.java new file mode 100644 index 000000000000..00f2dadec49c --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/vcs/ExternalSystemVcsRegistrar.java @@ -0,0 +1,134 @@ +/* + * Copyright 2000-2013 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.externalSystem.service.vcs; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.externalSystem.ExternalSystemManager; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; +import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; +import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsDirectoryMapping; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtilRt; +import git4idea.GitPlatformFacade; +import git4idea.GitVcs; +import git4idea.roots.GitRootDetector; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Collection; +import java.util.List; + +/** + * It's rather often when open-source project is backed by an external system and stored at public repo hosting + * like github, bitbucket etc. Standard actions sequence looks as below then: + *
+ * 
    + *
  1. Clone target repo to local machine;
  2. + *
  3. Execute 'import from external system' wizard;
  4. + *
+ *
+ * The problem is that the ide detects unregistered vcs roots at the newly imported project and shows corresponding notification + * with suggestion to configure vcs roots for the current project. We want to simplify that in a way to not showing the notification + * but register them automatically. This class manages that. + * + * @author Denis Zhdanov + * @since 7/15/13 6:00 PM + */ +public class ExternalSystemVcsRegistrar { + + @SuppressWarnings("unchecked") + public static void handle(@NotNull final Project project) { + + // VCS api doesn't offer generic ability to detect and configure VCS roots at the moment(see IDEA-102703 for more details). + // That's why we have only git support here. + + final Ref gitFacade = new Ref(); + try { + gitFacade.set(ServiceManager.getService(GitPlatformFacade.class)); + } + catch (Throwable e) { + // Assuming that git integration is disabled + } + + if (gitFacade.get() == null) { + // Assuming that git integration is disabled + return; + } + + for (final ExternalSystemManager manager : ExternalSystemApiUtil.getAllManagers()) { + final AbstractExternalSystemSettings settings = manager.getSettingsProvider().fun(project); + settings.subscribe(new ExternalSystemSettingsListenerAdapter() { + @Override + public void onProjectsLinked(@NotNull final Collection linked) { + final LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); + for (Object o : linked) { + final ExternalProjectSettings settings = (ExternalProjectSettings)o; + + // Hack into git processing. + Project projectProxy = (Project)Proxy.newProxyInstance( + getClass().getClassLoader(), + new Class[]{Project.class}, + new InvocationHandler() { + @SuppressWarnings("ConstantConditions") + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if ("getBaseDir".equals(method.getName())) { + return fileSystem.refreshAndFindFileByPath(settings.getExternalProjectPath()); + } + return method.invoke(project, args); + } + } + ); + + Collection roots = new GitRootDetector(projectProxy, gitFacade.get()).detect().getRoots(); + if (!roots.isEmpty()) { + List mappings = ContainerUtilRt.newArrayList(vcsManager.getDirectoryMappings()); + + // There is a possible case that no VCS mappings are configured for the current project. There is a single + // mapping like - then. We want to replace it if only one mapping to the project root dir + // has been detected then. + if (roots.size() == 1 + && mappings.size() == 1 + && StringUtil.isEmpty(mappings.get(0).getVcs()) + && roots.iterator().next().equals(project.getBaseDir())) + { + mappings.clear(); + mappings.add(new VcsDirectoryMapping("", GitVcs.getKey().getName())); + } + else { + for (VirtualFile root : roots) { + mappings.add(new VcsDirectoryMapping(root.getPath(), GitVcs.getKey().getName())); + } + } + + vcsManager.setDirectoryMappings(mappings); + } + } + } + }); + } + } +} diff --git a/plugins/git4idea/src/git4idea/roots/GitRootDetector.java b/plugins/git4idea/src/git4idea/roots/GitRootDetector.java index d8a01bfb493e..7a7c332d0000 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootDetector.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootDetector.java @@ -50,21 +50,25 @@ public class GitRootDetector { myPlatformFacade = platformFacade; } + @NotNull public GitRootDetectInfo detect() { - VirtualFile projectDir = myProject.getBaseDir(); - - if (projectDir == null) { + return detect(myProject.getBaseDir()); + } + + @NotNull + public GitRootDetectInfo detect(@Nullable VirtualFile startDir) { + if (startDir == null) { return new GitRootDetectInfo(Collections.emptyList(), false, false); } - final Set roots = scanForRootsInsideDir(projectDir); + final Set roots = scanForRootsInsideDir(startDir); roots.addAll(scanForRootsInContentRoots()); - if (roots.contains(projectDir)) { + if (roots.contains(startDir)) { return new GitRootDetectInfo(roots, true, false); } - VirtualFile rootAbove = scanForSingleRootAboveDir(projectDir); + VirtualFile rootAbove = scanForSingleRootAboveDir(startDir); if (rootAbove != null) { roots.add(rootAbove); return new GitRootDetectInfo(roots, true, true); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index 91b0e9553858..4ba711e19b66 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -16,7 +16,7 @@ public class GradleConstants { @NonNls public static final String EXTENSION = "gradle"; @NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle"; - @NonNls public static final String SETTINGS_FILE_NAME = "setting.gradle"; + @NonNls public static final String SETTINGS_FILE_NAME = "settings.gradle"; public static final String SYSTEM_DIRECTORY_PATH_KEY = "GRADLE_USER_HOME";