diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleConstants.kt.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleConstants.kt.172 new file mode 100644 index 00000000000..0e47c8a1a5d --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleConstants.kt.172 @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2017 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. + */ + +@file:JvmName("GradleKotlinDSLConstants") + +package org.jetbrains.kotlin.gradle.kdsl + +const val DEFAULT_SCRIPT_NAME = "build.gradle.kts" diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.form.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.form.172 new file mode 100644 index 00000000000..814609f97dd --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.form.172 @@ -0,0 +1,55 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.java.172 new file mode 100644 index 00000000000..3cb08deadb5 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleFrameworksWizardStep.java.172 @@ -0,0 +1,101 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl; + +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider; +import com.intellij.ide.util.newProjectWizard.AddSupportForFrameworksPanel; +import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase; +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleFrameworkSupportProvider; +import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider; + +import javax.swing.*; +import java.awt.*; +import java.util.Collections; +import java.util.List; + +public class GradleFrameworksWizardStep extends ModuleWizardStep implements Disposable { + + private JPanel myPanel; + private final AddSupportForFrameworksPanel myFrameworksPanel; + private JPanel myFrameworksPanelPlaceholder; + private JPanel myOptionsPanel; + @SuppressWarnings("unused") private JBLabel myFrameworksLabel; + + public GradleFrameworksWizardStep(WizardContext context, final ModuleBuilder builder) { + + Project project = context.getProject(); + final LibrariesContainer container = LibrariesContainerFactory.createContainer(context.getProject()); + FrameworkSupportModelBase model = new FrameworkSupportModelBase(project, null, container) { + @NotNull + @Override + public String getBaseDirectoryForLibrariesPath() { + return StringUtil.notNullize(builder.getContentEntryPath()); + } + }; + + myFrameworksPanel = + new AddSupportForFrameworksPanel(Collections.emptyList(), model, true, null); + + List providers = ContainerUtil.newArrayList(); + Collections.addAll(providers, GradleFrameworkSupportProvider.EP_NAME.getExtensions()); + + myFrameworksPanel.setProviders(providers, Collections.emptySet(), Collections.singleton(GradleJavaFrameworkSupportProvider.ID)); + Disposer.register(this, myFrameworksPanel); + myFrameworksPanelPlaceholder.add(myFrameworksPanel.getMainPanel()); + + ModuleBuilder.ModuleConfigurationUpdater configurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() { + @Override + public void update(@NotNull Module module, @NotNull ModifiableRootModel rootModel) { + myFrameworksPanel.addSupport(module, rootModel); + } + }; + builder.addModuleConfigurationUpdater(configurationUpdater); + + ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, "frameworks card"); + } + + @Override + public JComponent getComponent() { + return myPanel; + } + + @Override + public void updateDataModel() { + } + + @Override + public void dispose() { + } + + @Override + public void disposeUIResources() { + Disposer.dispose(this); + } +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleBuilder.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleBuilder.java.172 new file mode 100644 index 00000000000..a91d3d1b20d --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleBuilder.java.172 @@ -0,0 +1,495 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl; + +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.ide.projectWizard.ProjectSettingsStep; +import com.intellij.ide.util.EditorHelper; +import com.intellij.ide.util.projectWizard.JavaModuleBuilder; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.SettingsStep; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.components.StorageScheme; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager; +import com.intellij.openapi.externalSystem.importing.ImportSpec; +import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder; +import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; +import com.intellij.openapi.externalSystem.model.project.ProjectData; +import com.intellij.openapi.externalSystem.model.project.ProjectId; +import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode; +import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl; +import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder; +import com.intellij.openapi.externalSystem.service.project.wizard.ExternalModuleSettingsStep; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.LoadTextUtil; +import com.intellij.openapi.module.*; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.projectRoots.JavaSdkType; +import com.intellij.openapi.projectRoots.SdkTypeId; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.io.FileUtil; +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.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.containers.ContainerUtil; +import org.gradle.util.GradleVersion; +import org.jdom.JDOMException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.BuildScriptDataBuilder; +import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.KotlinBuildScriptDataBuilder; +import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl; +import org.jetbrains.plugins.gradle.settings.DistributionType; +import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import static org.jetbrains.kotlin.gradle.kdsl.GradleKotlinDSLConstants.DEFAULT_SCRIPT_NAME; + +public class GradleModuleBuilder extends AbstractExternalModuleBuilder { + + private static final Logger LOG = Logger.getInstance(GradleModuleBuilder.class); + + private static final String TEMPLATE_GRADLE_SETTINGS = "Gradle Kotlin DSL Settings.gradle"; + private static final String TEMPLATE_GRADLE_SETTINGS_MERGE = "Gradle Settings merge.gradle"; + private static final String TEMPLATE_GRADLE_BUILD_WITH_WRAPPER = "Gradle Build Script with wrapper.gradle"; + private static final String DEFAULT_TEMPLATE_GRADLE_BUILD = "Gradle Kotlin DSL Build Script.gradle"; + + private static final String TEMPLATE_ATTRIBUTE_PROJECT_NAME = "PROJECT_NAME"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_PATH = "MODULE_PATH"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_FLAT_DIR = "MODULE_FLAT_DIR"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_NAME = "MODULE_NAME"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_GROUP = "MODULE_GROUP"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_VERSION = "MODULE_VERSION"; + private static final String TEMPLATE_ATTRIBUTE_GRADLE_VERSION = "GRADLE_VERSION"; + private static final String TEMPLATE_ATTRIBUTE_BUILD_FILE_NAME = "BUILD_FILE_NAME"; + private static final Key BUILD_SCRIPT_DATA = + Key.create("gradle.module.kotlinBuildScriptData"); + + private WizardContext myWizardContext; + + @Nullable + private ProjectData myParentProject; + private boolean myInheritGroupId; + private boolean myInheritVersion; + private ProjectId myProjectId; + private String rootProjectPath; + + public GradleModuleBuilder() { + super(GradleConstants.SYSTEM_ID, new GradleProjectSettings()); + } + + @Override + public String getPresentableName() { + return "Gradle (Kotlin DSL)"; + } + + @NotNull + @Override + public Module createModule(@NotNull ModifiableModuleModel moduleModel) + throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException { + LOG.assertTrue(getName() != null); + final String originModuleFilePath = getModuleFilePath(); + LOG.assertTrue(originModuleFilePath != null); + + String moduleName; + if (myProjectId == null) { + moduleName = getName(); + } + else { + moduleName = getExternalProjectSettings().isUseQualifiedModuleNames() && StringUtil.isNotEmpty(myProjectId.getGroupId()) + ? (myProjectId.getGroupId() + '.' + myProjectId.getArtifactId()) + : myProjectId.getArtifactId(); + } + Project contextProject = myWizardContext.getProject(); + String projectFileDirectory = null; + if (myWizardContext.isCreatingNewProject() || contextProject == null || contextProject.getBasePath() == null) { + projectFileDirectory = myWizardContext.getProjectFileDirectory(); + } + else if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) { + String moduleFileDirectory = getModuleFileDirectory(); + if (moduleFileDirectory != null) { + projectFileDirectory = moduleFileDirectory; + } + } + if (projectFileDirectory == null) { + projectFileDirectory = contextProject.getBasePath(); + } + if (myWizardContext.getProjectStorageFormat() == StorageScheme.DIRECTORY_BASED) { + projectFileDirectory += "/.idea/modules"; + } + String moduleFilePath = projectFileDirectory + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION; + deleteModuleFile(moduleFilePath); + final ModuleType moduleType = getModuleType(); + final Module module = moduleModel.newModule(moduleFilePath, moduleType.getId()); + setupModule(module); + return module; + } + + @Override + public void setupRootModel(final ModifiableRootModel modifiableRootModel) throws ConfigurationException { + 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); + // todo this should be moved to generic ModuleBuilder + if (myJdk != null) { + modifiableRootModel.setSdk(myJdk); + } + else { + modifiableRootModel.inheritSdk(); + } + + final Project project = modifiableRootModel.getProject(); + if (myParentProject != null) { + rootProjectPath = myParentProject.getLinkedExternalProjectPath(); + } + else { + rootProjectPath = + FileUtil.toCanonicalPath(myWizardContext.isCreatingNewProject() ? project.getBasePath() : modelContentRootDir.getPath()); + } + assert rootProjectPath != null; + + final VirtualFile gradleBuildFile = setupGradleBuildFile(modelContentRootDir); + setupGradleSettingsFile( + rootProjectPath, modelContentRootDir, modifiableRootModel.getProject().getName(), + myProjectId == null ? modifiableRootModel.getModule().getName() : myProjectId.getArtifactId(), + myWizardContext.isCreatingNewProject() || myParentProject == null + ); + + if (gradleBuildFile != null) { + modifiableRootModel.getModule().putUserData( + BUILD_SCRIPT_DATA, new KotlinBuildScriptDataBuilder(gradleBuildFile)); + } + } + + @Override + protected void setupModule(Module module) throws ConfigurationException { + super.setupModule(module); + assert rootProjectPath != null; + + VirtualFile buildScriptFile = null; + final BuildScriptDataBuilder buildScriptDataBuilder = getBuildScriptData(module); + try { + if (buildScriptDataBuilder != null) { + buildScriptFile = buildScriptDataBuilder.getBuildScriptFile(); + String lineSeparator = lineSeparator(buildScriptFile); + String configurationPart = StringUtil.convertLineSeparators(buildScriptDataBuilder.buildConfigurationPart(), lineSeparator); + String existingText = StringUtil.trimTrailing(VfsUtilCore.loadText(buildScriptFile)); + String content = (!configurationPart.isEmpty() ? configurationPart + lineSeparator : "") + + (!existingText.isEmpty() ? existingText + lineSeparator : "") + + lineSeparator + + StringUtil.convertLineSeparators(buildScriptDataBuilder.buildMainPart(), lineSeparator); + VfsUtil.saveText(buildScriptFile, content); + } + } + catch (IOException e) { + LOG.warn("Unexpected exception on applying frameworks templates", e); + } + + // 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(); + if (myWizardContext.isCreatingNewProject()) { + getExternalProjectSettings().setExternalProjectPath(rootProjectPath); + AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID); + project.putUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT, Boolean.TRUE); + //noinspection unchecked + settings.linkProject(getExternalProjectSettings()); + } + else { + FileDocumentManager.getInstance().saveAllDocuments(); + final GradleProjectSettings gradleProjectSettings = getExternalProjectSettings(); + final VirtualFile finalBuildScriptFile = buildScriptFile; + Runnable runnable = () -> { + if (myParentProject == null) { + gradleProjectSettings.setExternalProjectPath(rootProjectPath); + AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID); + //noinspection unchecked + settings.linkProject(gradleProjectSettings); + } + + ImportSpec importSpec = new ImportSpecBuilder(project, GradleConstants.SYSTEM_ID) + .use(ProgressExecutionMode.IN_BACKGROUND_ASYNC) + .createDirectoriesForEmptyContentRoots() + .useDefaultCallback() + .build(); + ExternalSystemUtil.refreshProject(rootProjectPath, importSpec); + + final PsiFile psiFile; + if (finalBuildScriptFile != null) { + psiFile = PsiManager.getInstance(project).findFile(finalBuildScriptFile); + if (psiFile != null) { + EditorHelper.openInEditor(psiFile); + } + } + }; + + // execute when current dialog is closed + ExternalSystemUtil.invokeLater(project, ModalityState.NON_MODAL, runnable); + } + } + + @Override + public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) { + myWizardContext = wizardContext; + return new ModuleWizardStep[]{ + new GradleModuleWizardStep(this, wizardContext), + new ExternalModuleSettingsStep<>( + wizardContext, this, new GradleProjectSettingsControl(getExternalProjectSettings())) + }; + } + + @Nullable + @Override + public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) { + final GradleFrameworksWizardStep step = new GradleFrameworksWizardStep(context, this); + Disposer.register(parentDisposable, step); + return step; + } + + @Override + public boolean isSuitableSdkType(SdkTypeId sdk) { + return sdk instanceof JavaSdkType; + } + + @Override + public String getParentGroup() { + return JavaModuleType.BUILD_TOOLS_GROUP; + } + + @Override + public int getWeight() { + return JavaModuleBuilder.BUILD_SYSTEM_WEIGHT; + } + + @Override + public ModuleType getModuleType() { + return StdModuleTypes.JAVA; + } + + @Nullable + private VirtualFile setupGradleBuildFile(@NotNull VirtualFile modelContentRootDir) + throws ConfigurationException { + final VirtualFile file = getOrCreateExternalProjectConfigFile(modelContentRootDir.getPath(), GradleKotlinDSLConstants.DEFAULT_SCRIPT_NAME); + + if (file != null) { + final String templateName = getExternalProjectSettings().getDistributionType() == DistributionType.WRAPPED + ? TEMPLATE_GRADLE_BUILD_WITH_WRAPPER + : DEFAULT_TEMPLATE_GRADLE_BUILD; + Map attributes = ContainerUtil.newHashMap(); + if (myProjectId != null) { + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_VERSION, myProjectId.getVersion()); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_GROUP, myProjectId.getGroupId()); + attributes.put(TEMPLATE_ATTRIBUTE_GRADLE_VERSION, GradleVersion.current().getVersion()); + } + saveFile(file, templateName, attributes); + } + return file; + } + + @Nullable + public static VirtualFile setupGradleSettingsFile(@NotNull String rootProjectPath, + @NotNull VirtualFile modelContentRootDir, + String projectName, + String moduleName, + boolean renderNewFile) + throws ConfigurationException { + final VirtualFile file = getOrCreateExternalProjectConfigFile(rootProjectPath, GradleConstants.SETTINGS_FILE_NAME); + if (file == null) return null; + + if (renderNewFile) { + final String moduleDirName = VfsUtilCore.getRelativePath(modelContentRootDir, file.getParent(), '/'); + + Map attributes = ContainerUtil.newHashMap(); + attributes.put(TEMPLATE_ATTRIBUTE_PROJECT_NAME, projectName); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, moduleDirName); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, moduleName); + attributes.put(TEMPLATE_ATTRIBUTE_BUILD_FILE_NAME, DEFAULT_SCRIPT_NAME); // TODO: gradle > 4.0 doesn't need this + saveFile(file, TEMPLATE_GRADLE_SETTINGS, attributes); + } + else { + char separatorChar = file.getParent() == null || !VfsUtilCore.isAncestor(file.getParent(), modelContentRootDir, true) ? '/' : ':'; + String modulePath = VfsUtil.getPath(file, modelContentRootDir, separatorChar); + + Map attributes = ContainerUtil.newHashMap(); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, moduleName); + // check for flat structure + final String flatStructureModulePath = + modulePath != null && StringUtil.startsWith(modulePath, "../") ? StringUtil.trimStart(modulePath, "../") : null; + if (StringUtil.equals(flatStructureModulePath, modelContentRootDir.getName())) { + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_FLAT_DIR, "true"); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, flatStructureModulePath); + } + else { + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, modulePath); + } + + appendToFile(file, TEMPLATE_GRADLE_SETTINGS_MERGE, attributes); + } + return file; + } + + private static void saveFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes) + throws ConfigurationException { + FileTemplateManager manager = FileTemplateManager.getDefaultInstance(); + FileTemplate template = manager.getInternalTemplate(templateName); + try { + appendToFile(file, templateAttributes != null ? template.getText(templateAttributes) : template.getText()); + } + catch (IOException e) { + LOG.warn(String.format("Unexpected exception on applying template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e); + throw new ConfigurationException( + e.getMessage(), String.format("Can't apply %s template config text", GradleConstants.SYSTEM_ID.getReadableName()) + ); + } + } + + private static void appendToFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes) + throws ConfigurationException { + FileTemplateManager manager = FileTemplateManager.getDefaultInstance(); + FileTemplate template = manager.getInternalTemplate(templateName); + try { + appendToFile(file, templateAttributes != null ? template.getText(templateAttributes) : template.getText()); + } + catch (IOException e) { + LOG.warn(String.format("Unexpected exception on appending template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e); + throw new ConfigurationException( + e.getMessage(), String.format("Can't append %s template config text", GradleConstants.SYSTEM_ID.getReadableName()) + ); + } + } + + + @Nullable + private static VirtualFile getOrCreateExternalProjectConfigFile(@NotNull String parent, @NotNull String fileName) { + File file = new File(parent, fileName); + FileUtilRt.createIfNotExists(file); + return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + } + + public void setParentProject(@Nullable ProjectData parentProject) { + myParentProject = parentProject; + } + + public boolean isInheritGroupId() { + return myInheritGroupId; + } + + public void setInheritGroupId(boolean inheritGroupId) { + myInheritGroupId = inheritGroupId; + } + + public boolean isInheritVersion() { + return myInheritVersion; + } + + public void setInheritVersion(boolean inheritVersion) { + myInheritVersion = inheritVersion; + } + + public ProjectId getProjectId() { + return myProjectId; + } + + public void setProjectId(@NotNull ProjectId projectId) { + myProjectId = projectId; + } + + @Nullable + @Override + public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) { + if (settingsStep instanceof ProjectSettingsStep) { + final ProjectSettingsStep projectSettingsStep = (ProjectSettingsStep)settingsStep; + if (myProjectId != null) { + final JTextField moduleNameField = settingsStep.getModuleNameField(); + if (moduleNameField != null) { + moduleNameField.setText(myProjectId.getArtifactId()); + } + projectSettingsStep.setModuleName(myProjectId.getArtifactId()); + } + projectSettingsStep.bindModuleSettings(); + } + return super.modifySettingsStep(settingsStep); + } + + public static void appendToFile(@NotNull VirtualFile file, @NotNull String text) throws IOException { + String lineSeparator = lineSeparator(file); + final String existingText = StringUtil.trimTrailing(VfsUtilCore.loadText(file)); + String content = (StringUtil.isNotEmpty(existingText) ? existingText + lineSeparator : "") + + StringUtil.convertLineSeparators(text, lineSeparator); + VfsUtil.saveText(file, content); + } + + @NotNull + private static String lineSeparator(@NotNull VirtualFile file) { + String lineSeparator = LoadTextUtil.detectLineSeparator(file, true); + if (lineSeparator == null) { + lineSeparator = CodeStyleSettingsManager.getSettings(ProjectManagerEx.getInstanceEx().getDefaultProject()).getLineSeparator(); + } + return lineSeparator; + } + + @Nullable + public static BuildScriptDataBuilder getBuildScriptData(@Nullable Module module) { + return module == null ? null : module.getUserData(BUILD_SCRIPT_DATA); + } + + @Nullable + @Override + public Project createProject(String name, String path) { + Project project = super.createProject(name, path); + if (project != null) { + GradleProjectSettings settings = getExternalProjectSettings(); + ExternalProjectsManagerImpl.getInstance(project).setStoreExternally(settings.isStoreProjectFilesExternally()); + } + return project; + } +} \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.form.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.form.172 new file mode 100644 index 00000000000..b94d1e0017f --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.form.172 @@ -0,0 +1,105 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.java.172 new file mode 100644 index 00000000000..f540c42a4d1 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/GradleModuleWizardStep.java.172 @@ -0,0 +1,257 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.externalSystem.model.project.ProjectData; +import com.intellij.openapi.externalSystem.model.project.ProjectId; +import com.intellij.openapi.externalSystem.service.project.wizard.ExternalModuleSettingsStep; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFocusManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.service.project.wizard.GradleParentProjectForm; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class GradleModuleWizardStep extends ModuleWizardStep { + private static final Icon WIZARD_ICON = null; + + private static final String INHERIT_GROUP_ID_KEY = "GradleModuleWizard.inheritGroupId"; + private static final String INHERIT_VERSION_KEY = "GradleModuleWizard.inheritVersion"; + private static final String DEFAULT_VERSION = "1.0-SNAPSHOT"; + + @Nullable + private final Project myProjectOrNull; + @NotNull + private final GradleModuleBuilder myBuilder; + @NotNull + private final WizardContext myContext; + @NotNull + private final GradleParentProjectForm myParentProjectForm; + + private String myInheritedGroupId; + private String myInheritedVersion; + + private JPanel myMainPanel; + + private JTextField myGroupIdField; + private JCheckBox myInheritGroupIdCheckBox; + private JTextField myArtifactIdField; + private JTextField myVersionField; + private JCheckBox myInheritVersionCheckBox; + private JPanel myAddToPanel; + + public GradleModuleWizardStep(@NotNull GradleModuleBuilder builder, @NotNull WizardContext context) { + myProjectOrNull = context.getProject(); + myBuilder = builder; + myContext = context; + myParentProjectForm = new GradleParentProjectForm(context, parentProject -> updateComponents()); + initComponents(); + loadSettings(); + } + + private void initComponents() { + myAddToPanel.add(myParentProjectForm.getComponent()); + ActionListener updatingListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateComponents(); + } + }; + myInheritGroupIdCheckBox.addActionListener(updatingListener); + myInheritVersionCheckBox.addActionListener(updatingListener); + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myGroupIdField; + } + + @Override + public void onStepLeaving() { + saveSettings(); + } + + private void loadSettings() { + myBuilder.setInheritGroupId(getSavedValue(INHERIT_GROUP_ID_KEY, true)); + myBuilder.setInheritVersion(getSavedValue(INHERIT_VERSION_KEY, true)); + } + + private void saveSettings() { + saveValue(INHERIT_GROUP_ID_KEY, myInheritGroupIdCheckBox.isSelected()); + saveValue(INHERIT_VERSION_KEY, myInheritVersionCheckBox.isSelected()); + } + + private static boolean getSavedValue(String key, boolean defaultValue) { + return getSavedValue(key, String.valueOf(defaultValue)).equals(String.valueOf(true)); + } + + private static String getSavedValue(String key, String defaultValue) { + String value = PropertiesComponent.getInstance().getValue(key); + return value == null ? defaultValue : value; + } + + private static void saveValue(String key, boolean value) { + saveValue(key, String.valueOf(value)); + } + + private static void saveValue(String key, String value) { + PropertiesComponent.getInstance().setValue(key, value); + } + + public JComponent getComponent() { + return myMainPanel; + } + + @Override + public boolean validate() throws ConfigurationException { + if (StringUtil.isEmptyOrSpaces(myArtifactIdField.getText())) { + ApplicationManager.getApplication().invokeLater( + () -> IdeFocusManager.getInstance(myProjectOrNull).requestFocus(myArtifactIdField, true)); + throw new ConfigurationException("Please, specify artifactId"); + } + + return true; + } + + @Override + public void updateStep() { + ProjectData parentProject = myParentProjectForm.getParentProject(); + ProjectId projectId = myBuilder.getProjectId(); + + if (projectId == null) { + setTestIfEmpty(myArtifactIdField, myBuilder.getName()); + setTestIfEmpty(myGroupIdField, parentProject == null ? myBuilder.getName() : parentProject.getGroup()); + setTestIfEmpty(myVersionField, parentProject == null ? DEFAULT_VERSION : parentProject.getVersion()); + } + else { + setTestIfEmpty(myArtifactIdField, projectId.getArtifactId()); + setTestIfEmpty(myGroupIdField, projectId.getGroupId()); + setTestIfEmpty(myVersionField, projectId.getVersion()); + } + + myInheritGroupIdCheckBox.setSelected(myBuilder.isInheritGroupId()); + myInheritVersionCheckBox.setSelected(myBuilder.isInheritVersion()); + + updateComponents(); + } + + + private void updateComponents() { + final boolean isAddToVisible = myParentProjectForm.isVisible(); + + myInheritGroupIdCheckBox.setVisible(isAddToVisible); + myInheritVersionCheckBox.setVisible(isAddToVisible); + + myParentProjectForm.updateComponents(); + ProjectData parentProject = myParentProjectForm.getParentProject(); + if (parentProject == null) { + myContext.putUserData(ExternalModuleSettingsStep.SKIP_STEP_KEY, Boolean.FALSE); + myGroupIdField.setEnabled(true); + myVersionField.setEnabled(true); + myInheritGroupIdCheckBox.setEnabled(false); + myInheritVersionCheckBox.setEnabled(false); + + setTestIfEmpty(myArtifactIdField, myBuilder.getName()); + setTestIfEmpty(myGroupIdField, ""); + setTestIfEmpty(myVersionField, DEFAULT_VERSION); + } + else { + myContext.putUserData(ExternalModuleSettingsStep.SKIP_STEP_KEY, Boolean.TRUE); + myGroupIdField.setEnabled(!myInheritGroupIdCheckBox.isSelected()); + myVersionField.setEnabled(!myInheritVersionCheckBox.isSelected()); + + if (myInheritGroupIdCheckBox.isSelected() + || myGroupIdField.getText().equals(myInheritedGroupId)) { + myGroupIdField.setText(parentProject.getGroup()); + } + if (myInheritVersionCheckBox.isSelected() + || myVersionField.getText().equals(myInheritedVersion)) { + myVersionField.setText(parentProject.getVersion()); + } + myInheritedGroupId = myGroupIdField.getText(); + myInheritedVersion = myVersionField.getText(); + + myInheritGroupIdCheckBox.setEnabled(true); + myInheritVersionCheckBox.setEnabled(true); + } + } + + public static boolean isGradleModuleExist(WizardContext myContext) { + for (Module module : myContext.getModulesProvider().getModules()) { + if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return true; + } + return false; + } + + @Override + public void updateDataModel() { + myContext.setProjectBuilder(myBuilder); + ProjectData parentProject = myParentProjectForm.getParentProject(); + myBuilder.setParentProject(parentProject); + + myBuilder.setProjectId(new ProjectId(myGroupIdField.getText(), + myArtifactIdField.getText(), + myVersionField.getText())); + myBuilder.setInheritGroupId(myInheritGroupIdCheckBox.isSelected()); + myBuilder.setInheritVersion(myInheritVersionCheckBox.isSelected()); + + if (StringUtil.isNotEmpty(myBuilder.getProjectId().getArtifactId())) { + myContext.setProjectName(myBuilder.getProjectId().getArtifactId()); + } + if (parentProject != null) { + myContext.setProjectFileDirectory(parentProject.getLinkedExternalProjectPath() + '/' + myContext.getProjectName()); + } + else { + if (myProjectOrNull != null) { + myContext.setProjectFileDirectory(myProjectOrNull.getBaseDir().getPath() + '/' + myContext.getProjectName()); + } + } + } + + @Override + public Icon getIcon() { + return WIZARD_ICON; + } + + private static void setTestIfEmpty(@NotNull JTextField field, @Nullable String text) { + if (StringUtil.isEmpty(field.getText())) { + field.setText(StringUtil.notNullize(text)); + } + } + + @Override + public String getHelpId() { + return "Gradle_Archetype_Dialog"; + } + + @Override + public void disposeUIResources() { + Disposer.dispose(myParentProjectForm); + } +} + diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/BuildScriptDataBuilder.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/BuildScriptDataBuilder.java.172 new file mode 100644 index 00000000000..679e583b4c3 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/BuildScriptDataBuilder.java.172 @@ -0,0 +1,158 @@ +/* + * Copyright 2000-2017 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Set; + +public class BuildScriptDataBuilder { + @NotNull private final VirtualFile myBuildScriptFile; + private final Set plugins = ContainerUtil.newTreeSet(); + private final Set pluginsInGroup = ContainerUtil.newTreeSet(); + private final Set repositories = ContainerUtil.newTreeSet(); + private final Set dependencies = ContainerUtil.newTreeSet(); + private final Set properties = ContainerUtil.newTreeSet(); + private final Set buildScriptProperties = ContainerUtil.newTreeSet(); + private final Set buildScriptRepositories = ContainerUtil.newTreeSet(); + private final Set buildScriptDependencies = ContainerUtil.newTreeSet(); + private final Set other = ContainerUtil.newTreeSet(); + + public BuildScriptDataBuilder(@NotNull VirtualFile buildScriptFile) { + myBuildScriptFile = buildScriptFile; + } + + @NotNull + public VirtualFile getBuildScriptFile() { + return myBuildScriptFile; + } + + public String buildConfigurationPart() { + List lines = ContainerUtil.newArrayList(); + addBuildscriptLines(lines, BuildScriptDataBuilder::padding); + if (!pluginsInGroup.isEmpty()) { + lines.add("plugins {"); + lines.addAll(ContainerUtil.map(pluginsInGroup, BuildScriptDataBuilder::padding)); + lines.add("}"); + lines.add(""); + } + return StringUtil.join(lines, "\n"); + } + + public String buildMainPart() { + List lines = ContainerUtil.newArrayList(); + if (!plugins.isEmpty()) { + lines.addAll(plugins); + lines.add(""); + } + if (!properties.isEmpty()) { + lines.addAll(properties); + lines.add(""); + } + if (!repositories.isEmpty()) { + lines.add("repositories {"); + lines.addAll(ContainerUtil.map(repositories, BuildScriptDataBuilder::padding)); + lines.add("}"); + lines.add(""); + } + if (!dependencies.isEmpty()) { + lines.add("dependencies {"); + lines.addAll(ContainerUtil.map(dependencies, BuildScriptDataBuilder::padding)); + lines.add("}"); + lines.add(""); + } + if (!other.isEmpty()) { + lines.addAll(other); + } + return StringUtil.join(lines, "\n"); + } + + private void addBuildscriptLines(@NotNull List lines, @NotNull Function padding) { + if (!buildScriptRepositories.isEmpty() || !buildScriptDependencies.isEmpty() || !buildScriptProperties.isEmpty()) { + lines.add("buildscript {"); + final List buildScriptLines = ContainerUtil.newSmartList(); + if (!buildScriptProperties.isEmpty()) { + buildScriptLines.addAll(buildScriptProperties); + buildScriptLines.add(""); + } + if (!buildScriptRepositories.isEmpty()) { + buildScriptLines.add("repositories {"); + buildScriptLines.addAll(ContainerUtil.map(buildScriptRepositories, padding)); + buildScriptLines.add("}"); + } + if (!buildScriptDependencies.isEmpty()) { + buildScriptLines.add("dependencies {"); + buildScriptLines.addAll(ContainerUtil.map(buildScriptDependencies, padding)); + buildScriptLines.add("}"); + } + lines.addAll(ContainerUtil.map(buildScriptLines, padding)); + lines.add("}"); + lines.add(""); + } + } + + public BuildScriptDataBuilder addBuildscriptPropertyDefinition(@NotNull String definition) { + buildScriptProperties.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addBuildscriptRepositoriesDefinition(@NotNull String definition) { + buildScriptRepositories.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addBuildscriptDependencyNotation(@NotNull String notation) { + buildScriptDependencies.add(notation.trim()); + return this; + } + + public BuildScriptDataBuilder addPluginDefinitionInPluginsGroup(@NotNull String definition) { + pluginsInGroup.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addPluginDefinition(@NotNull String definition) { + plugins.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addRepositoriesDefinition(@NotNull String definition) { + repositories.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addDependencyNotation(@NotNull String notation) { + dependencies.add(notation.trim()); + return this; + } + + public BuildScriptDataBuilder addPropertyDefinition(@NotNull String definition) { + properties.add(definition.trim()); + return this; + } + + public BuildScriptDataBuilder addOther(@NotNull String definition) { + other.add(definition.trim()); + return this; + } + + private static String padding(String s) {return StringUtil.isNotEmpty(s) ? " " + s : "";} +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleFrameworkSupportProvider.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleFrameworkSupportProvider.java.172 new file mode 100644 index 00000000000..cfe1c3eef59 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleFrameworkSupportProvider.java.172 @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport; + +import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable; +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider; +import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.roots.ModifiableModelsProvider; +import com.intellij.openapi.roots.ModifiableRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +import static org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder.getBuildScriptData; + +public abstract class GradleFrameworkSupportProvider extends FrameworkSupportInModuleProvider { + + public static final ExtensionPointName EP_NAME = + ExtensionPointName.create("org.jetbrains.kotlin.gradleFrameworkSupport"); + + public abstract void addSupport(@NotNull Module module, @NotNull ModifiableRootModel rootModel, + @NotNull ModifiableModelsProvider modifiableModelsProvider, + @NotNull BuildScriptDataBuilder buildScriptData); + + public JComponent createComponent() { + return null; + } + + @NotNull + @Override + public FrameworkSupportInModuleConfigurable createConfigurable(@NotNull FrameworkSupportModel model) { + return new FrameworkSupportInModuleConfigurable() { + @Nullable + @Override + public JComponent createComponent() { + return GradleFrameworkSupportProvider.this.createComponent(); + } + + @Override + public void addSupport(@NotNull Module module, + @NotNull ModifiableRootModel rootModel, + @NotNull ModifiableModelsProvider modifiableModelsProvider) { + final BuildScriptDataBuilder buildScriptData = getBuildScriptData(module); + if (buildScriptData != null) { + GradleFrameworkSupportProvider.this.addSupport(module, rootModel, modifiableModelsProvider, buildScriptData); + } + } + }; + } + + @Override + public boolean isEnabledForModuleType(@NotNull ModuleType moduleType) { + return false; + } +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleGroovyFrameworkSupportProvider.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleGroovyFrameworkSupportProvider.java.172 new file mode 100644 index 00000000000..7d9daced59c --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleGroovyFrameworkSupportProvider.java.172 @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport; + +import com.intellij.framework.FrameworkTypeEx; +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModifiableModelsProvider; +import com.intellij.openapi.roots.ModifiableRootModel; +import icons.JetgroovyIcons; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class GradleGroovyFrameworkSupportProvider extends GradleFrameworkSupportProvider { + + public static final String ID = "groovy"; + + @NotNull + @Override + public FrameworkTypeEx getFrameworkType() { + return new FrameworkTypeEx(ID) { + @NotNull + @Override + public FrameworkSupportInModuleProvider createProvider() { + return GradleGroovyFrameworkSupportProvider.this; + } + + @NotNull + @Override + public String getPresentableName() { + return "Groovy"; + } + + @NotNull + @Override + public Icon getIcon() { + return JetgroovyIcons.Groovy.Groovy_16x16; + } + }; + } + + @Override + public void addSupport(@NotNull Module module, + @NotNull ModifiableRootModel rootModel, + @NotNull ModifiableModelsProvider modifiableModelsProvider, + @NotNull BuildScriptDataBuilder buildScriptData) { + buildScriptData + .addPluginDefinition("plugin(\"groovy\")") + .addRepositoriesDefinition("mavenCentral()") + .addDependencyNotation("compile(\"org.codehaus.groovy:groovy-all:2.3.11\")") + .addDependencyNotation("testCompile(\"junit\", \"junit\", \"4.12\")"); + } +} \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleJavaFrameworkSupportProvider.java.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleJavaFrameworkSupportProvider.java.172 new file mode 100644 index 00000000000..0bde690ccc1 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleJavaFrameworkSupportProvider.java.172 @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport; + +import com.intellij.framework.FrameworkTypeEx; +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModifiableModelsProvider; +import com.intellij.openapi.roots.ModifiableRootModel; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class GradleJavaFrameworkSupportProvider extends GradleFrameworkSupportProvider { + + public static final String ID = "java"; + + @NotNull + @Override + public FrameworkTypeEx getFrameworkType() { + return new FrameworkTypeEx(ID) { + @NotNull + @Override + public FrameworkSupportInModuleProvider createProvider() { + return GradleJavaFrameworkSupportProvider.this; + } + + @NotNull + @Override + public String getPresentableName() { + return "Java"; + } + + @NotNull + @Override + public Icon getIcon() { + return AllIcons.Nodes.Module; + } + }; + } + + @Override + public void addSupport(@NotNull Module module, + @NotNull ModifiableRootModel rootModel, + @NotNull ModifiableModelsProvider modifiableModelsProvider, + @NotNull BuildScriptDataBuilder buildScriptData) { + buildScriptData + .addPluginDefinition("plugin(\"java\")") + // TODO: in gradle > 4.0 it is just 'java { ... }' + .addOther("configure {\n sourceCompatibility = JavaVersion.VERSION_1_8\n}") + .addRepositoriesDefinition("mavenCentral()") + .addDependencyNotation("testCompile(\"junit\", \"junit\", \"4.12\")"); + } +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleKotlinFrameworkSupportProvider.kt.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleKotlinFrameworkSupportProvider.kt.172 new file mode 100644 index 00000000000..e16ad485689 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/GradleKotlinFrameworkSupportProvider.kt.172 @@ -0,0 +1,115 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport + +import com.intellij.framework.FrameworkTypeEx +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ModifiableModelsProvider +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.vfs.VfsUtil +import org.jetbrains.kotlin.idea.KotlinIcons +import org.jetbrains.kotlin.idea.configuration.* +import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.GSK_KOTLIN_VERSION_PROPERTY_NAME +import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getCompileDependencySnippet +import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getKotlinGradlePluginClassPathSnippet +import org.jetbrains.kotlin.idea.versions.* +import javax.swing.Icon + +abstract class GradleKotlinDSLKotlinFrameworkSupportProvider( + val frameworkTypeId: String, + val displayName: String, + val frameworkIcon: Icon +) : GradleFrameworkSupportProvider() { + override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) { + override fun getIcon(): Icon = frameworkIcon + override fun getPresentableName(): String = displayName + override fun createProvider(): FrameworkSupportInModuleProvider = this@GradleKotlinDSLKotlinFrameworkSupportProvider + } + + override fun addSupport( + module: Module, + rootModel: ModifiableRootModel, + modifiableModelsProvider: ModifiableModelsProvider, + buildScriptData: BuildScriptDataBuilder + ) { + var kotlinVersion = bundledRuntimeVersion() + val additionalRepository = getRepositoryForVersion(kotlinVersion) + if (isSnapshot(bundledRuntimeVersion())) { + kotlinVersion = LAST_SNAPSHOT_VERSION + } + + if (additionalRepository != null) { + val repository = additionalRepository.toKotlinRepositorySnippet() + buildScriptData.addBuildscriptRepositoriesDefinition(repository) + buildScriptData.addRepositoriesDefinition("mavenCentral()") + buildScriptData.addRepositoriesDefinition(repository) + } + + buildScriptData + .addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra") + .addPluginDefinition(getPluginDefinition()) + .addBuildscriptRepositoriesDefinition("mavenCentral()") + .addRepositoriesDefinition("mavenCentral()") + // TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }' + .addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n$GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"") + .addDependencyNotation(getRuntimeLibrary(rootModel)) + .addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet()) + } + + protected abstract fun getRuntimeLibrary(rootModel: ModifiableRootModel): String + + protected abstract fun getPluginDefinition(): String +} + +class GradleKotlinDSLKotlinJavaFrameworkSupportProvider : + GradleKotlinDSLKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) { + + override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")" + + override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = + getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion())) + + override fun addSupport( + module: Module, + rootModel: ModifiableRootModel, + modifiableModelsProvider: ModifiableModelsProvider, + buildScriptData: BuildScriptDataBuilder + ) { + super.addSupport(module, rootModel, modifiableModelsProvider, buildScriptData) + val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion()) + if (jvmTarget != null) { + buildScriptData + .addImports("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile") + .addOther("tasks.withType {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n") + } + } + + private fun BuildScriptDataBuilder.addImports(vararg import: String): BuildScriptDataBuilder = apply { + val text = VfsUtil.loadText(buildScriptFile) + VfsUtil.saveText(buildScriptFile, import.joinToString(separator = "\n") + "\n\n" + text) + } +} + +class GradleKotlinDSLKotlinJSFrameworkSupportProvider : + GradleKotlinDSLKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) { + + override fun getPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")" + + override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = + getCompileDependencySnippet(KOTLIN_GROUP_ID, MAVEN_JS_STDLIB_ID.removePrefix("kotlin-")) +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/KotlinBuildScriptDataBuilder.kt.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/KotlinBuildScriptDataBuilder.kt.172 new file mode 100644 index 00000000000..950eb9ae738 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/gradle/kdsl/frameworkSupport/KotlinBuildScriptDataBuilder.kt.172 @@ -0,0 +1,93 @@ +/* + * Copyright 2010-2017 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 org.jetbrains.kotlin.gradle.kdsl.frameworkSupport + +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.containers.ContainerUtil + +class KotlinBuildScriptDataBuilder(buildScriptFile: VirtualFile) : BuildScriptDataBuilder(buildScriptFile) { + private val plugins: MutableSet = ContainerUtil.newTreeSet() + private val properties: MutableSet = ContainerUtil.newTreeSet() + private val repositories: MutableSet = ContainerUtil.newTreeSet() + private val dependencies: MutableSet = ContainerUtil.newTreeSet() + + private val buildScriptProperties: MutableSet = ContainerUtil.newTreeSet() + private val buildScriptRepositories: MutableSet = ContainerUtil.newTreeSet() + private val buildScriptDependencies: MutableSet = ContainerUtil.newTreeSet() + private val other: MutableSet = ContainerUtil.newTreeSet() + + override fun addPluginDefinition(definition: String): BuildScriptDataBuilder = apply { plugins.add(definition) } + + override fun addRepositoriesDefinition(definition: String): BuildScriptDataBuilder = apply { repositories.add(definition) } + + override fun addPropertyDefinition(definition: String): BuildScriptDataBuilder = apply { properties.add(definition) } + + override fun addDependencyNotation(notation: String): BuildScriptDataBuilder = apply { dependencies.add(notation) } + + override fun addBuildscriptPropertyDefinition(definition: String): BuildScriptDataBuilder = apply { buildScriptProperties.add(definition) } + + override fun addBuildscriptRepositoriesDefinition(definition: String): BuildScriptDataBuilder = apply { buildScriptRepositories.add(definition) } + + override fun addBuildscriptDependencyNotation(notation: String): BuildScriptDataBuilder = apply { buildScriptDependencies.add(notation) } + + override fun addOther(definition: String): BuildScriptDataBuilder = apply { other.add(definition) } + + override fun buildMainPart(): String = buildString { + + appendlnIfNotNull(buildBuildScriptBlock()) + + appendlnIfNotNull(buildBlock("apply", plugins)) + + if (properties.isNotEmpty()) { + properties.forEach { appendln(it) } + appendln() + } + + appendlnIfNotNull(buildBlock("repositories", repositories)) + + appendlnIfNotNull(buildBlock("dependencies", dependencies)) + + other.forEach { appendln(it) } + } + + private fun buildBuildScriptBlock(): String? = buildString { + if (buildScriptProperties.isEmpty() || buildScriptRepositories.isEmpty() || buildScriptDependencies.isEmpty()) { + return null + } + + appendln("buildscript {") + buildScriptProperties.forEach { appendln(it.withMargin) } + appendln() + appendlnIfNotNull(buildBlock("repositories", buildScriptRepositories)?.withMargin) + appendlnIfNotNull(buildBlock("dependencies", buildScriptDependencies)?.withMargin) + appendln("}") + } + + private fun buildBlock(name: String, lines: Set): String? = buildString { + if (lines.isEmpty()) { + return null + } + + appendln("$name {") + lines.forEach { appendln(it.withMargin) } + appendln("}") + } + + private val String.withMargin: String + get() = lines().joinToString(separator = "\n") { " " + it } + + private fun StringBuilder.appendlnIfNotNull(text: String?) = text?.let { appendln(it) } +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt.172 index f65d45a743f..e69de29bb2d 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt.172 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt.172 @@ -1,113 +0,0 @@ -/* - * Copyright 2010-2017 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 org.jetbrains.kotlin.idea.configuration - -import com.intellij.framework.FrameworkTypeEx -import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider -import com.intellij.openapi.externalSystem.model.project.ProjectId -import com.intellij.openapi.module.Module -import com.intellij.openapi.roots.ModifiableModelsProvider -import com.intellij.openapi.roots.ModifiableRootModel -import org.jetbrains.kotlin.idea.KotlinIcons -import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.GSK_KOTLIN_VERSION_PROPERTY_NAME -import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getCompileDependencySnippet -import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getKotlinGradlePluginClassPathSnippet -import org.jetbrains.kotlin.idea.versions.* -import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder -import org.jetbrains.plugins.gradle.frameworkSupport.KotlinDslGradleFrameworkSupportProvider -import javax.swing.Icon - -abstract class KotlinDslGradleKotlinFrameworkSupportProvider( - val frameworkTypeId: String, - val displayName: String, - val frameworkIcon: Icon -) : KotlinDslGradleFrameworkSupportProvider() { - override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) { - override fun getIcon(): Icon = frameworkIcon - override fun getPresentableName(): String = displayName - override fun createProvider(): FrameworkSupportInModuleProvider = this@KotlinDslGradleKotlinFrameworkSupportProvider - } - - override fun addSupport( - projectId: ProjectId, - module: Module, - rootModel: ModifiableRootModel, - modifiableModelsProvider: ModifiableModelsProvider, - buildScriptData: BuildScriptDataBuilder - ) { - var kotlinVersion = bundledRuntimeVersion() - val additionalRepository = getRepositoryForVersion(kotlinVersion) - if (isSnapshot(bundledRuntimeVersion())) { - kotlinVersion = LAST_SNAPSHOT_VERSION - } - - if (additionalRepository != null) { - val repository = additionalRepository.toKotlinRepositorySnippet() - buildScriptData.addBuildscriptRepositoriesDefinition(repository) - buildScriptData.addRepositoriesDefinition("mavenCentral()") - buildScriptData.addRepositoriesDefinition(repository) - } - - buildScriptData - .addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra") - .addPluginDefinition(getPluginDefinition()) - .addBuildscriptRepositoriesDefinition("mavenCentral()") - .addRepositoriesDefinition("mavenCentral()") - // TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }' - .addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n$GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"") - .addDependencyNotation(getRuntimeLibrary(rootModel)) - .addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet()) - } - - protected abstract fun getRuntimeLibrary(rootModel: ModifiableRootModel): String - - protected abstract fun getPluginDefinition(): String -} - -class KotlinDslGradleKotlinJavaFrameworkSupportProvider : - KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) { - - override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")" - - override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = - getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion())) - - override fun addSupport( - projectId: ProjectId, - module: Module, - rootModel: ModifiableRootModel, - modifiableModelsProvider: ModifiableModelsProvider, - buildScriptData: BuildScriptDataBuilder - ) { - super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData) - val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion()) - if (jvmTarget != null) { - buildScriptData - .addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile") - .addOther("tasks.withType {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n") - } - } -} - -class KotlinDslGradleKotlinJSFrameworkSupportProvider : - KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) { - - override fun getPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")" - - override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = - getCompileDependencySnippet(KOTLIN_GROUP_ID, MAVEN_JS_STDLIB_ID.removePrefix("kotlin-")) -} diff --git a/idea/src/META-INF/gradle.xml.172 b/idea/src/META-INF/gradle.xml.172 index a9ae65b9f52..9a29d971a28 100644 --- a/idea/src/META-INF/gradle.xml.172 +++ b/idea/src/META-INF/gradle.xml.172 @@ -2,8 +2,6 @@ - -