org.gradle.plugins.ide.idea.IdeaPlugin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2010 the original author or authors.
*
* 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.gradle.plugins.ide.idea;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.gradle.api.Action;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.PublishArtifact;
import org.gradle.api.artifacts.component.ProjectComponentIdentifier;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.ConventionMapping;
import org.gradle.api.internal.IConventionAware;
import org.gradle.api.internal.artifacts.ivyservice.projectmodule.ProjectLocalComponentProvider;
import org.gradle.api.internal.artifacts.publish.DefaultPublishArtifact;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.plugins.scala.ScalaBasePlugin;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.internal.component.local.model.LocalComponentArtifactMetadata;
import org.gradle.internal.component.local.model.PublishArtifactLocalArtifactMetadata;
import org.gradle.internal.reflect.Instantiator;
import org.gradle.language.scala.plugins.ScalaLanguagePlugin;
import org.gradle.plugins.ide.api.XmlFileContentMerger;
import org.gradle.plugins.ide.idea.internal.IdeaNameDeduper;
import org.gradle.plugins.ide.idea.internal.IdeaScalaConfigurer;
import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel;
import org.gradle.plugins.ide.idea.model.IdeaModel;
import org.gradle.plugins.ide.idea.model.IdeaModule;
import org.gradle.plugins.ide.idea.model.IdeaModuleIml;
import org.gradle.plugins.ide.idea.model.IdeaProject;
import org.gradle.plugins.ide.idea.model.IdeaWorkspace;
import org.gradle.plugins.ide.idea.model.PathFactory;
import org.gradle.plugins.ide.idea.model.internal.GeneratedIdeaScope;
import org.gradle.plugins.ide.idea.model.internal.IdeaDependenciesProvider;
import org.gradle.plugins.ide.internal.IdePlugin;
import javax.inject.Inject;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import static org.gradle.internal.component.local.model.DefaultProjectComponentIdentifier.newProjectId;
/**
* Adds a GenerateIdeaModule task. When applied to a root project, also adds a GenerateIdeaProject task. For projects that have the Java plugin applied, the tasks receive additional Java-specific
* configuration.
*/
public class IdeaPlugin extends IdePlugin {
private static final Predicate HAS_IDEA_AND_JAVA_PLUGINS = new Predicate() {
@Override
public boolean apply(Project project) {
return project.getPlugins().hasPlugin(IdeaPlugin.class) && project.getPlugins().hasPlugin(JavaBasePlugin.class);
}
};
public static final Function SOURCE_COMPATIBILITY = new Function() {
@Override
public JavaVersion apply(Project p) {
return p.getConvention().getPlugin(JavaPluginConvention.class).getSourceCompatibility();
}
};
public static final Function TARGET_COMPATIBILITY = new Function() {
@Override
public JavaVersion apply(Project p) {
return p.getConvention().getPlugin(JavaPluginConvention.class).getTargetCompatibility();
}
};
private final Instantiator instantiator;
private IdeaModel ideaModel;
private List allJavaProjects;
@Inject
public IdeaPlugin(Instantiator instantiator) {
this.instantiator = instantiator;
}
public IdeaModel getModel() {
return ideaModel;
}
@Override
protected String getLifecycleTaskName() {
return "idea";
}
@Override
protected void onApply(Project project) {
getLifecycleTask().setDescription("Generates IDEA project files (IML, IPR, IWS)");
getCleanTask().setDescription("Cleans IDEA project files (IML, IPR)");
ideaModel = project.getExtensions().create("idea", IdeaModel.class);
configureIdeaWorkspace(project);
configureIdeaProject(project);
configureIdeaModule(project);
configureForJavaPlugin(project);
configureForWarPlugin(project);
configureForScalaPlugin();
postProcess("idea", new Action() {
@Override
public void execute(Gradle gradle) {
performPostEvaluationActions();
}
});
}
public void performPostEvaluationActions() {
makeSureModuleNamesAreUnique();
// This needs to happen after de-duplication
registerImlArtifacts();
}
private void makeSureModuleNamesAreUnique() {
new IdeaNameDeduper().configureRoot(project.getRootProject());
}
private void registerImlArtifacts() {
Set projectsWithIml = Sets.filter(project.getRootProject().getAllprojects(), new Predicate() {
@Override
public boolean apply(Project project) {
return project.getPlugins().hasPlugin(IdeaPlugin.class);
}
});
for (Project project : projectsWithIml) {
ProjectLocalComponentProvider projectComponentProvider = ((ProjectInternal) project).getServices().get(ProjectLocalComponentProvider.class);
ProjectComponentIdentifier projectId = newProjectId(project);
projectComponentProvider.registerAdditionalArtifact(projectId, createImlArtifact(projectId, project));
}
}
private static LocalComponentArtifactMetadata createImlArtifact(ProjectComponentIdentifier projectId, Project project) {
String moduleName = project.getExtensions().getByType(IdeaModel.class).getModule().getName();
File imlFile = new File(project.getProjectDir(), moduleName + ".iml");
Task byName = project.getTasks().getByName("ideaModule");
PublishArtifact publishArtifact = new DefaultPublishArtifact(moduleName, "iml", "iml", null, null, imlFile, byName);
return new PublishArtifactLocalArtifactMetadata(projectId, publishArtifact);
}
private void configureIdeaWorkspace(final Project project) {
if (isRoot(project)) {
GenerateIdeaWorkspace task = project.getTasks().create("ideaWorkspace", GenerateIdeaWorkspace.class);
task.setDescription("Generates an IDEA workspace file (IWS)");
IdeaWorkspace workspace = new IdeaWorkspace();
workspace.setIws(new XmlFileContentMerger(task.getXmlTransformer()));
task.setWorkspace(workspace);
ideaModel.setWorkspace(task.getWorkspace());
task.setOutputFile(new File(project.getProjectDir(), project.getName() + ".iws"));
addWorker(task, false);
}
}
private void configureIdeaProject(final Project project) {
if (isRoot(project)) {
final GenerateIdeaProject task = project.getTasks().create("ideaProject", GenerateIdeaProject.class);
task.setDescription("Generates IDEA project file (IPR)");
XmlFileContentMerger ipr = new XmlFileContentMerger(task.getXmlTransformer());
IdeaProject ideaProject = instantiator.newInstance(IdeaProject.class, project, ipr);
task.setIdeaProject(ideaProject);
ideaModel.setProject(ideaProject);
ideaProject.setOutputFile(new File(project.getProjectDir(), project.getName() + ".ipr"));
ConventionMapping conventionMapping = ((IConventionAware) ideaProject).getConventionMapping();
conventionMapping.map("jdkName", new Callable() {
@Override
public String call() throws Exception {
return JavaVersion.current().toString();
}
});
conventionMapping.map("languageLevel", new Callable() {
@Override
public IdeaLanguageLevel call() throws Exception {
JavaVersion maxSourceCompatibility = getMaxJavaModuleCompatibilityVersionFor(SOURCE_COMPATIBILITY);
return new IdeaLanguageLevel(maxSourceCompatibility);
}
});
conventionMapping.map("targetBytecodeVersion", new Callable() {
@Override
public JavaVersion call() throws Exception {
return getMaxJavaModuleCompatibilityVersionFor(TARGET_COMPATIBILITY);
}
});
ideaProject.setWildcards(Sets.newHashSet("!?*.class", "!?*.scala", "!?*.groovy", "!?*.java"));
conventionMapping.map("modules", new Callable>() {
@Override
public List call() throws Exception {
return Lists.newArrayList(Iterables.transform(Sets.filter(project.getRootProject().getAllprojects(), new Predicate() {
@Override
public boolean apply(Project p) {
return p.getPlugins().hasPlugin(IdeaPlugin.class);
}
}), new Function() {
@Override
public IdeaModule apply(Project p) {
return ideaModelFor(p).getModule();
}
}));
}
});
conventionMapping.map("pathFactory", new Callable() {
@Override
public PathFactory call() throws Exception {
return new PathFactory().addPathVariable("PROJECT_DIR", task.getOutputFile().getParentFile());
}
});
addWorker(task);
}
}
private static IdeaModel ideaModelFor(Project project) {
return project.getExtensions().getByType(IdeaModel.class);
}
private JavaVersion getMaxJavaModuleCompatibilityVersionFor(Function toJavaVersion) {
List allJavaProjects = getAllJavaProjects();
if (allJavaProjects.isEmpty()) {
return JavaVersion.VERSION_1_6;
} else {
return Collections.max(Lists.transform(allJavaProjects, toJavaVersion));
}
}
private List getAllJavaProjects() {
if (allJavaProjects != null) {
// cache result because it is pretty expensive to compute
return allJavaProjects;
}
allJavaProjects = Lists.newArrayList(Iterables.filter(project.getRootProject().getAllprojects(), HAS_IDEA_AND_JAVA_PLUGINS));
return allJavaProjects;
}
private void configureIdeaModule(final Project project) {
final GenerateIdeaModule task = project.getTasks().create("ideaModule", GenerateIdeaModule.class);
task.setDescription("Generates IDEA module files (IML)");
IdeaModuleIml iml = new IdeaModuleIml(task.getXmlTransformer(), project.getProjectDir());
final IdeaModule module = instantiator.newInstance(IdeaModule.class, project, iml);
task.setModule(module);
ideaModel.setModule(module);
ConventionMapping conventionMapping = ((IConventionAware) module).getConventionMapping();
conventionMapping.map("sourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
return Sets.newHashSet();
}
});
conventionMapping.map("name", new Callable() {
@Override
public String call() throws Exception {
return project.getName();
}
});
conventionMapping.map("contentRoot", new Callable() {
@Override
public File call() throws Exception {
return project.getProjectDir();
}
});
conventionMapping.map("testSourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
return Sets.newHashSet();
}
});
conventionMapping.map("excludeDirs", new Callable>() {
@Override
public Set call() throws Exception {
return Sets.newHashSet(project.getBuildDir(), project.file(".gradle"));
}
});
conventionMapping.map("pathFactory", new Callable() {
@Override
public PathFactory call() throws Exception {
final PathFactory factory = new PathFactory();
factory.addPathVariable("MODULE_DIR", task.getOutputFile().getParentFile());
for (Map.Entry entry : module.getPathVariables().entrySet()) {
factory.addPathVariable(entry.getKey(), entry.getValue());
}
return factory;
}
});
addWorker(task);
}
private void configureForJavaPlugin(final Project project) {
project.getPlugins().withType(JavaPlugin.class, new Action() {
@Override
public void execute(JavaPlugin javaPlugin) {
configureIdeaModuleForJava(project);
}
});
}
private void configureForWarPlugin(final Project project) {
project.getPlugins().withType(WarPlugin.class, new Action() {
@Override
public void execute(WarPlugin warPlugin) {
configureIdeaModuleForWar(project);
}
});
}
private void configureIdeaModuleForJava(final Project project) {
project.getTasks().withType(GenerateIdeaModule.class, new Action() {
@Override
public void execute(GenerateIdeaModule ideaModule) {
// Defaults
setupScopes(ideaModule);
// Convention
ConventionMapping convention = ((IConventionAware) ideaModule.getModule()).getConventionMapping();
convention.map("sourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("main").getAllSource().getSrcDirs();
}
});
convention.map("testSourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("test").getAllSource().getSrcDirs();
}
});
convention.map("singleEntryLibraries", new Callable
© 2015 - 2025 Weber Informatics LLC | Privacy Policy