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.component.BuildIdentifier;
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.project.ProjectInternal;
import org.gradle.api.internal.project.ProjectStateRegistry;
import org.gradle.api.internal.tasks.TaskDependencyContainer;
import org.gradle.api.internal.tasks.TaskDependencyResolveContext;
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.api.tasks.TaskProvider;
import org.gradle.internal.reflect.Instantiator;
import org.gradle.internal.xml.XmlTransformer;
import org.gradle.language.scala.plugins.ScalaLanguagePlugin;
import org.gradle.plugins.ide.api.XmlFileContentMerger;
import org.gradle.plugins.ide.idea.internal.IdeaModuleMetadata;
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.IdeArtifactRegistry;
import org.gradle.plugins.ide.internal.IdePlugin;
import org.gradle.plugins.ide.internal.configurer.UniqueProjectNameProvider;
import javax.inject.Inject;
import java.io.File;
import java.util.Arrays;
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;
/**
* 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 static final String IDEA_MODULE_TASK_NAME = "ideaModule";
private static final String IDEA_PROJECT_TASK_NAME = "ideaProject";
private static final String IDEA_WORKSPACE_TASK_NAME = "ideaWorkspace";
private final Instantiator instantiator;
private IdeaModel ideaModel;
private List allJavaProjects;
private final UniqueProjectNameProvider uniqueProjectNameProvider;
private final IdeArtifactRegistry artifactRegistry;
private final ProjectStateRegistry projectPathRegistry;
@Inject
public IdeaPlugin(Instantiator instantiator, UniqueProjectNameProvider uniqueProjectNameProvider, IdeArtifactRegistry artifactRegistry, ProjectStateRegistry projectPathRegistry) {
this.instantiator = instantiator;
this.uniqueProjectNameProvider = uniqueProjectNameProvider;
this.artifactRegistry = artifactRegistry;
this.projectPathRegistry = projectPathRegistry;
}
public IdeaModel getModel() {
return ideaModel;
}
@Override
protected String getLifecycleTaskName() {
return "idea";
}
@Override
protected void onApply(final Project project) {
getLifecycleTask().configure(withDescription("Generates IDEA project files (IML, IPR, IWS)"));
getCleanTask().configure(withDescription("Cleans IDEA project files (IML, IPR)"));
ideaModel = project.getExtensions().create("idea", IdeaModel.class);
configureIdeaWorkspace(project);
configureIdeaProject(project);
configureIdeaModule((ProjectInternal) project);
configureForJavaPlugin(project);
configureForWarPlugin(project);
configureForScalaPlugin();
linkCompositeBuildDependencies((ProjectInternal) project);
}
private void configureIdeaWorkspace(final Project project) {
if (isRoot()) {
final IdeaWorkspace workspace = project.getObjects().newInstance(IdeaWorkspace.class);
workspace.setIws(new XmlFileContentMerger(new XmlTransformer()));
ideaModel.setWorkspace(workspace);
final TaskProvider task = project.getTasks().register(IDEA_WORKSPACE_TASK_NAME, GenerateIdeaWorkspace.class, workspace);
task.configure(new Action() {
@Override
public void execute(GenerateIdeaWorkspace task) {
task.setDescription("Generates an IDEA workspace file (IWS)");
task.setOutputFile(new File(project.getProjectDir(), project.getName() + ".iws"));
}
});
addWorker(task, IDEA_WORKSPACE_TASK_NAME, false);
}
}
private void configureIdeaProject(final Project project) {
if (isRoot()) {
XmlFileContentMerger ipr = new XmlFileContentMerger(new XmlTransformer());
final IdeaProject ideaProject = instantiator.newInstance(IdeaProject.class, project, ipr);
final TaskProvider projectTask = project.getTasks().register(IDEA_PROJECT_TASK_NAME, GenerateIdeaProject.class, ideaProject);
projectTask.configure(new Action() {
@Override
public void execute(GenerateIdeaProject projectTask) {
projectTask.setDescription("Generates IDEA project file (IPR)");
}
});
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() {
return JavaVersion.current().toString();
}
});
conventionMapping.map("languageLevel", new Callable() {
@Override
public IdeaLanguageLevel call() {
JavaVersion maxSourceCompatibility = getMaxJavaModuleCompatibilityVersionFor(SOURCE_COMPATIBILITY);
return new IdeaLanguageLevel(maxSourceCompatibility);
}
});
conventionMapping.map("targetBytecodeVersion", new Callable() {
@Override
public JavaVersion call() {
return getMaxJavaModuleCompatibilityVersionFor(TARGET_COMPATIBILITY);
}
});
ideaProject.getWildcards().addAll(Arrays.asList("!?*.class", "!?*.scala", "!?*.groovy", "!?*.java"));
conventionMapping.map("modules", new Callable>() {
@Override
public List call() {
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() {
return new PathFactory().addPathVariable("PROJECT_DIR", projectTask.get().getOutputFile().getParentFile());
}
});
addWorker(projectTask, IDEA_PROJECT_TASK_NAME);
addWorkspace(ideaProject);
}
}
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 ProjectInternal project) {
IdeaModuleIml iml = new IdeaModuleIml(new XmlTransformer(), project.getProjectDir());
final IdeaModule module = instantiator.newInstance(IdeaModule.class, project, iml);
final TaskProvider task = project.getTasks().register(IDEA_MODULE_TASK_NAME, GenerateIdeaModule.class, module);
task.configure(new Action() {
@Override
public void execute(GenerateIdeaModule task) {
task.setDescription("Generates IDEA module files (IML)");
}
});
ideaModel.setModule(module);
final String defaultModuleName = uniqueProjectNameProvider.getUniqueName(project);
module.setName(defaultModuleName);
ConventionMapping conventionMapping = ((IConventionAware) module).getConventionMapping();
conventionMapping.map("sourceDirs", new Callable>() {
@Override
public Set call() {
return Sets.newLinkedHashSet();
}
});
conventionMapping.map("contentRoot", new Callable() {
@Override
public File call() {
return project.getProjectDir();
}
});
conventionMapping.map("testSourceDirs", new Callable>() {
@Override
public Set call() {
return Sets.newLinkedHashSet();
}
});
conventionMapping.map("resourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
return Sets.newLinkedHashSet();
}
});
conventionMapping.map("testResourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
return Sets.newLinkedHashSet();
}
});
conventionMapping.map("excludeDirs", new Callable>() {
@Override
public Set call() {
Set defaultExcludes = Sets.newLinkedHashSet();
defaultExcludes.add(project.file(".gradle"));
defaultExcludes.add(project.getBuildDir());
return defaultExcludes;
}
});
conventionMapping.map("pathFactory", new Callable() {
@Override
public PathFactory call() {
final PathFactory factory = new PathFactory();
factory.addPathVariable("MODULE_DIR", task.get().getOutputFile().getParentFile());
for (Map.Entry entry : module.getPathVariables().entrySet()) {
factory.addPathVariable(entry.getKey(), entry.getValue());
}
return factory;
}
});
artifactRegistry.registerIdeProject(new IdeaModuleMetadata(module, task));
addWorker(task, IDEA_MODULE_TASK_NAME);
}
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).configureEach(new Action() {
@Override
public void execute(GenerateIdeaModule ideaModule) {
// Dependencies
ideaModule.dependsOn(new Callable() {
@Override
public FileCollection call() {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("main").getOutput().getDirs().plus(sourceSets.getByName("test").getOutput().getDirs());
}
});
}
});
// Defaults
setupScopes(project);
// Convention
ConventionMapping convention = ((IConventionAware) ideaModel.getModule()).getConventionMapping();
convention.map("sourceDirs", new Callable>() {
@Override
public Set call() {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("main").getAllJava().getSrcDirs();
}
});
convention.map("testSourceDirs", new Callable>() {
@Override
public Set call() {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("test").getAllJava().getSrcDirs();
}
});
convention.map("resourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("main").getResources().getSrcDirs();
}
});
convention.map("testResourceDirs", new Callable>() {
@Override
public Set call() throws Exception {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName("test").getResources().getSrcDirs();
}
});
convention.map("singleEntryLibraries", new Callable
© 2015 - 2025 Weber Informatics LLC | Privacy Policy