Gradle: do not show Import dialog when creating/opening gradle projects in CLion (IDEA-191523)

This commit is contained in:
Vladislav.Soroka
2018-08-21 14:25:47 +03:00
parent 8c70f2a20c
commit 8cbcdad690
3 changed files with 128 additions and 52 deletions
@@ -9,12 +9,14 @@ import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.EnvironmentUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;
@@ -75,8 +77,7 @@ public class ExternalSystemJdkUtil {
@NotNull
public static Pair<String, Sdk> getAvailableJdk(@Nullable Project project) throws ExternalSystemJdkException {
// JavaSdk.getInstance() can be null for non-java IDE
SdkType javaSdkType = JavaSdk.getInstance() == null ? SimpleJavaSdkType.getInstance() : JavaSdk.getInstance();
SdkType javaSdkType = getJavaSdkType();
if (project != null) {
Stream<Sdk> projectSdks = Stream.concat(
@@ -107,6 +108,18 @@ public class ExternalSystemJdkUtil {
return pair(USE_INTERNAL_JAVA, JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk());
}
@NotNull
public static Collection<String> suggestJdkHomePaths() {
return getJavaSdkType().suggestHomePaths();
}
@NotNull
public static SdkType getJavaSdkType() {
// JavaSdk.getInstance() can be null for non-java IDE
JavaSdk javaSdk = JavaSdk.getInstance();
return javaSdk == null ? SimpleJavaSdkType.getInstance() : javaSdk;
}
/** @deprecated trivial (to be removed in IDEA 2019) */
@Deprecated
public static boolean checkForJdk(@NotNull Project project, @Nullable String jdkName) {
@@ -121,4 +134,23 @@ public class ExternalSystemJdkUtil {
public static boolean isValidJdk(@Nullable String homePath) {
return !StringUtil.isEmptyOrSpaces(homePath) && (JdkUtil.checkForJdk(homePath) || JdkUtil.checkForJre(homePath));
}
@NotNull
public static Sdk addJdk(String homePath) {
// JavaSdk.getInstance() can be null for non-java IDE
JavaSdk javaSdk = JavaSdk.getInstance();
if (javaSdk == null) {
SimpleJavaSdkType simpleJavaSdkType = SimpleJavaSdkType.getInstance();
return simpleJavaSdkType.createJdk(simpleJavaSdkType.suggestSdkName(null, homePath), homePath);
}
else {
return ApplicationManager.getApplication().runWriteAction(
(Computable<Sdk>)() -> {
Sdk jdk = javaSdk.createJdk(javaSdk.suggestSdkName(null, homePath), homePath, false);
ProjectJdkTable.getInstance().addJdk(jdk);
return jdk;
}
);
}
}
}
@@ -39,6 +39,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -130,8 +131,10 @@ public class ContentRootDataService extends AbstractProjectDataService<ContentRo
if (roots.length > 0) {
VirtualFile virtualFile = roots[0];
ExternalSystemUtil.invokeLater(project, ModalityState.NON_MODAL, () -> {
final ProjectView projectView = ProjectView.getInstance(project);
projectView.changeViewCB(ProjectViewPane.ID, null).doWhenProcessed(() -> projectView.selectCB(null, virtualFile, false));
StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> {
final ProjectView projectView = ProjectView.getInstance(project);
projectView.changeViewCB(ProjectViewPane.ID, null).doWhenProcessed(() -> projectView.selectCB(null, virtualFile, false));
});
});
}
}
@@ -8,6 +8,7 @@ import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.ide.wizard.AbstractWizard;
import com.intellij.ide.wizard.CommitStepException;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager;
import com.intellij.openapi.externalSystem.importing.ImportSpec;
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
@@ -33,12 +34,19 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import icons.GradleIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -50,6 +58,9 @@ import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import javax.swing.*;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
@@ -88,60 +99,91 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessor {
@Nullable
@Override
public Project doOpenProject(@NotNull VirtualFile virtualFile, @Nullable Project projectToClose, boolean forceOpenInNewFrame) {
final WizardContext wizardContext = new WizardContext(null, null);
if (virtualFile.isDirectory()) {
projectToClose = forceOpenInNewFrame ? null : projectToClose;
Path path = Paths.get(virtualFile.getPath());
return openGradleProject(null, projectToClose, path);
}
@Nullable
public static Project openGradleProject(@Nullable Project projectToOpen,
@Nullable Project projectToClose,
@NotNull Path path) {
GradleProjectOpenProcessor gradleProjectOpenProcessor =
Extensions.findExtension(ProjectOpenProcessor.EXTENSION_POINT_NAME, GradleProjectOpenProcessor.class);
VirtualFile virtualFile = VfsUtil.findFile(path, false);
if (virtualFile != null && virtualFile.isDirectory()) {
for (VirtualFile file : virtualFile.getChildren()) {
if (canOpenProject(file)) {
if (gradleProjectOpenProcessor.canOpenProject(file)) {
virtualFile = file;
break;
}
}
}
VirtualFile baseDir = virtualFile.getParent();
String pathToOpen = baseDir.getPath();
wizardContext.setProjectFileDirectory(pathToOpen);
String pathToOpen = virtualFile != null ? virtualFile.getParent().getPath() : path.toString();
GradleAbstractWizard wizard = new GradleAbstractWizard(wizardContext, pathToOpen);
final WizardContext wizardContext = new WizardContext(null, null);
wizardContext.setProjectFileDirectory(pathToOpen);
GradleProjectSettings gradleProjectSettings = createDefaultProjectSettings();
gradleProjectSettings.setExternalProjectPath(pathToOpen);
boolean jvmFound = setupGradleJvm(ObjectUtils.chooseNotNull(projectToOpen, projectToClose), gradleProjectSettings);
GradleAbstractWizard wizard = new GradleAbstractWizard(wizardContext, gradleProjectSettings);
AbstractExternalModuleBuilder<GradleProjectSettings> wizardBuilder = wizard.getBuilder();
try {
wizard.show();
if (DialogWrapper.OK_EXIT_CODE == wizard.getExitCode()) {
final Project projectToOpen;
projectToOpen = ProjectManagerEx.getInstanceEx().newProject(wizardContext.getProjectName(), pathToOpen, true, false);
if (projectToOpen == null) return null;
if (!wizardBuilder.validate(projectToClose, projectToOpen)) {
return null;
if (!jvmFound) {
wizard.show();
}
if (jvmFound || DialogWrapper.OK_EXIT_CODE == wizard.getExitCode()) {
if (projectToOpen == null) {
projectToOpen = ProjectManagerEx.getInstanceEx().newProject(wizardContext.getProjectName(), pathToOpen, true, false);
}
if (projectToOpen == null) return null;
ExternalProjectsManagerImpl.getInstance(projectToOpen).setStoreExternally(true);
VirtualFile finalVirtualFile = virtualFile;
Project finalProjectToOpen = projectToOpen;
ExternalSystemApiUtil.subscribe(projectToOpen, GradleConstants.SYSTEM_ID, new GradleSettingsListenerAdapter() {
@Override
public void onProjectsLinked(@NotNull Collection<GradleProjectSettings> settings) {
createProjectPreview(projectToOpen, pathToOpen, finalVirtualFile);
createProjectPreview(finalProjectToOpen, pathToOpen, finalVirtualFile);
}
});
wizardBuilder.commit(projectToOpen, null, ModulesProvider.EMPTY_MODULES_PROVIDER);
projectToOpen.save();
if (!forceOpenInNewFrame) {
if (projectToClose != null) {
closePreviousProject(projectToClose);
}
ProjectUtil.updateLastProjectLocation(pathToOpen);
projectToOpen.putUserData(ExternalSystemDataKeys.NEWLY_IMPORTED_PROJECT, Boolean.TRUE);
ProjectManagerEx.getInstanceEx().openProject(projectToOpen);
if (!projectToOpen.isOpen()) {
ProjectManagerEx.getInstanceEx().openProject(projectToOpen);
}
return projectToOpen;
}
}
finally {
wizardBuilder.cleanup();
Disposer.dispose(wizard.getDisposable());
}
return null;
}
public static void closePreviousProject(final Project projectToClose) {
public static void attachGradleProjectAndRefresh(@NotNull Project project, @NotNull String gradleProjectPath) {
openGradleProject(project, null, Paths.get(gradleProjectPath));
}
@NotNull
private static GradleProjectSettings createDefaultProjectSettings() {
GradleProjectSettings settings = new GradleProjectSettings();
settings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
settings.setStoreProjectFilesExternally(ThreeState.YES);
settings.setUseQualifiedModuleNames(true);
return settings;
}
private static void closePreviousProject(final Project projectToClose) {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length > 0) {
int exitCode = ProjectUtil.confirmOpenNewProject(true);
@@ -154,26 +196,36 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessor {
private static class GradleAbstractWizard extends AbstractWizard<ExternalModuleSettingsStep> {
private final AbstractExternalModuleBuilder<GradleProjectSettings> myBuilder;
public GradleAbstractWizard(WizardContext wizardContext, String rootProjectPath) {
public GradleAbstractWizard(WizardContext wizardContext, GradleProjectSettings gradleProjectSettings) {
super("Open Gradle Project", (Project)null);
GradleProjectSettings gradleProjectSettings = createDefaultProjectSettings();
myBuilder = new AbstractExternalModuleBuilder<GradleProjectSettings>(GradleConstants.SYSTEM_ID, gradleProjectSettings) {
@Override
protected void setupModule(Module module) throws ConfigurationException {
super.setupModule(module);
assert rootProjectPath != null;
// it will be set later in any case, but save is called immediately after project creation, so, to ensure that it will be properly saved as external system module
ExternalSystemModulePropertyManager.getInstance(module).setExternalId(GradleConstants.SYSTEM_ID);
final Project project = module.getProject();
FileDocumentManager.getInstance().saveAllDocuments();
final GradleProjectSettings gradleProjectSettings = getExternalProjectSettings();
attachGradleProjectAndRefresh(project, rootProjectPath, gradleProjectSettings);
attachGradleProjectAndRefresh(project, gradleProjectSettings);
}
@Override
public void setupRootModel(ModifiableRootModel modifiableRootModel) {
String contentEntryPath = getContentEntryPath();
if (StringUtil.isEmpty(contentEntryPath)) {
return;
}
File contentRootDir = new File(contentEntryPath);
FileUtilRt.createDirectory(contentRootDir);
LocalFileSystem fileSystem = LocalFileSystem.getInstance();
VirtualFile modelContentRootDir = fileSystem.refreshAndFindFileByIoFile(contentRootDir);
if (modelContentRootDir == null) {
return;
}
modifiableRootModel.addContentEntry(modelContentRootDir);
}
@Override
@@ -210,26 +262,8 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessor {
}
}
public static void attachGradleProjectAndRefresh(@NotNull Project project, @NotNull String gradleProjectPath) {
GradleProjectSettings gradleProjectSettings = createDefaultProjectSettings();
setupGradleJvm(project, gradleProjectSettings);
attachGradleProjectAndRefresh(project, gradleProjectPath, gradleProjectSettings);
}
@NotNull
public static GradleProjectSettings createDefaultProjectSettings() {
GradleProjectSettings settings = new GradleProjectSettings();
settings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
settings.setStoreProjectFilesExternally(ThreeState.YES);
settings.setUseQualifiedModuleNames(true);
return settings;
}
private static void attachGradleProjectAndRefresh(@NotNull Project project,
@NotNull String gradleProjectPath,
@NotNull GradleProjectSettings gradleProjectSettings) {
private static void attachGradleProjectAndRefresh(@NotNull Project project, @NotNull GradleProjectSettings gradleProjectSettings) {
Runnable runnable = () -> {
gradleProjectSettings.setExternalProjectPath(gradleProjectPath);
AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID);
//noinspection unchecked
settings.linkProject(gradleProjectSettings);
@@ -238,7 +272,7 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessor {
.use(ProgressExecutionMode.IN_BACKGROUND_ASYNC)
.useDefaultCallback()
.build();
ExternalSystemUtil.refreshProject(gradleProjectPath, importSpec);
ExternalSystemUtil.refreshProject(gradleProjectSettings.getExternalProjectPath(), importSpec);
};
ExternalProjectsManagerImpl.getInstance(project)
.runWhenInitialized(
@@ -249,20 +283,27 @@ public class GradleProjectOpenProcessor extends ProjectOpenProcessor {
ExternalSystemUtil.invokeLater(project, ModalityState.NON_MODAL, runnable);
}
private static void setupGradleJvm(@NotNull Project project, @NotNull GradleProjectSettings projectSettings) {
private static boolean setupGradleJvm(@Nullable Project project, @NotNull GradleProjectSettings projectSettings) {
final Pair<String, Sdk> sdkPair = ExternalSystemJdkUtil.getAvailableJdk(project);
if (!ExternalSystemJdkUtil.USE_INTERNAL_JAVA.equals(sdkPair.first)) {
projectSettings.setGradleJvm(sdkPair.first);
return true;
}
else {
projectSettings.setGradleJvm(ExternalSystemJdkUtil.USE_JAVA_HOME);
String jdkPath = ContainerUtil.iterateAndGetLastItem(ExternalSystemJdkUtil.suggestJdkHomePaths());
if (jdkPath != null) {
Sdk sdk = ExternalSystemJdkUtil.addJdk(jdkPath);
projectSettings.setGradleJvm(sdk.getName());
return true;
}
return false;
}
private static void createProjectPreview(Project project, String rootProjectPath, VirtualFile virtualFile) {
private static void createProjectPreview(@NotNull Project project, @NotNull String rootProjectPath, @Nullable VirtualFile virtualFile) {
ExternalSystemUtil.refreshProject(project, GradleConstants.SYSTEM_ID, rootProjectPath, true, ProgressExecutionMode.MODAL_SYNC);
ExternalProjectsManagerImpl.getInstance(project).runWhenInitialized(() -> DumbService.getInstance(project).runWhenSmart(() -> {
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID);
if (virtualFile == null) return;
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (psiFile != null) {
ProjectView.getInstance(project).selectPsiElement(psiFile, false);