diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingHelpGroup.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingHelpGroup.java new file mode 100644 index 000000000000..771af57550bf --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingHelpGroup.java @@ -0,0 +1,27 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.execution; + +import com.intellij.ide.actions.runAnything.activity.RunAnythingProvider; +import com.intellij.ide.actions.runAnything.groups.RunAnythingHelpGroup; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author ibessonov + */ +public class MavenRunAnythingHelpGroup extends RunAnythingHelpGroup { + + @NotNull + @Override + public String getTitle() { + return "Maven"; + } + + @NotNull + @Override + public Collection getProviders() { + return ContainerUtil.immutableSingletonList(RunAnythingProvider.EP_NAME.findExtension(MavenRunAnythingProvider.class)); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProvider.java new file mode 100644 index 000000000000..c1efc32d3946 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProvider.java @@ -0,0 +1,212 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.execution; + +import com.intellij.ide.actions.runAnything.activity.RunAnythingProviderBase; +import com.intellij.ide.actions.runAnything.items.RunAnythingHelpItem; +import com.intellij.ide.actions.runAnything.items.RunAnythingItem; +import com.intellij.ide.actions.runAnything.items.RunAnythingItemBase; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.execution.ParametersListUtil; +import icons.MavenIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.model.MavenConstants; +import org.jetbrains.idea.maven.model.MavenExplicitProfiles; +import org.jetbrains.idea.maven.model.MavenPlugin; +import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.idea.maven.project.MavenProjectsManager; +import org.jetbrains.idea.maven.utils.MavenArtifactUtil; +import org.jetbrains.idea.maven.utils.MavenPluginInfo; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import static com.intellij.ide.actions.runAnything.RunAnythingUtil.fetchProject; +import static com.intellij.openapi.util.text.StringUtil.*; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; + +/** + * @author ibessonov + */ +public class MavenRunAnythingProvider extends RunAnythingProviderBase { + + @NotNull + @Override + public RunAnythingItem getMainListItem(@NotNull DataContext dataContext, @NotNull String value) { + return new RunAnythingItemBase(getCommand(value), getIcon(value)); + } + + @NotNull + @Override + public Collection getValues(@NotNull DataContext dataContext, @NotNull String pattern) { + Project project = fetchProject(dataContext); + MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project); + if (!projectsManager.isMavenizedProject()) { + return emptyList(); + } + + if (!pattern.startsWith(getHelpCommand())) { + return emptyList(); + } + + List mavenProjects = projectsManager.getProjects(); + boolean onlyOneMavenProject = mavenProjects.size() == 1; + + List values = new ArrayList<>(); + List params = split(pattern, " ").stream().skip(1).map(String::trim).collect(toList()); + if (!onlyOneMavenProject && (params.isEmpty() || params.size() == 1 && !pattern.endsWith(" "))) { + + // list maven modules + for (MavenProject mavenProject : mavenProjects) { + Module module = projectsManager.findModule(mavenProject); + if (module != null) { + values.add(getHelpCommand() + " " + module.getName()); + } + } + if (params.isEmpty()) { + return values; + } + } + + HashSet goals = new HashSet<>(params.subList(onlyOneMavenProject ? 0 : 1, params.size())); + Module module = onlyOneMavenProject ? projectsManager.findModule(mavenProjects.get(0)) + : ModuleManager.getInstance(project).findModuleByName(params.get(0)); + if (module != null) { + MavenProject mavenProject = projectsManager.findProject(module); + if (mavenProject != null) { + String prefix = notNullize(substringBeforeLast(pattern, " "), getHelpCommand()).trim() + " "; + if (!onlyOneMavenProject && prefix.trim().equals(getHelpCommand())) { + prefix = prefix + module.getName() + " "; + } + + // list basic phases + for (String phase : MavenConstants.BASIC_PHASES) { + if (!goals.contains(phase)) { + values.add(prefix + phase); + } + } + + // list plugin-specific goals + for (MavenPlugin mavenPlugin : mavenProject.getDeclaredPlugins()) { + MavenPluginInfo pluginInfo = MavenArtifactUtil.readPluginInfo(projectsManager.getLocalRepository(), mavenPlugin.getMavenId()); + if (pluginInfo == null) continue; + + for (MavenPluginInfo.Mojo mojo : pluginInfo.getMojos()) { + if (!goals.contains(mojo.getGoal())) { + values.add(prefix + mojo.getDisplayName()); + } + } + } + } + } + return values; + } + + @Nullable + @Override + public String findMatchingValue(@NotNull DataContext dataContext, @NotNull String pattern) { + return pattern.startsWith(getHelpCommand()) ? getCommand(pattern) : null; + } + + @NotNull + @Override + public String getCommand(@NotNull String value) { + return value; + } + + @NotNull + @Override + public String getHelpCommand() { + return "maven"; + } + + @Nullable + @Override + public Icon getHelpIcon() { + return MavenIcons.MavenLogo; + } + + + @NotNull + @Override + public String getCompletionGroupTitle() { + return "Maven goals"; + } + + @Nullable + @Override + public RunAnythingHelpItem getHelpItem(@NotNull DataContext dataContext) { + String placeholder = getHelpCommandPlaceholder(dataContext); + String commandPrefix = getHelpCommand(); + return new RunAnythingHelpItem(placeholder, commandPrefix, getHelpDescription(), getHelpIcon()); + } + + @NotNull + @Override + public String getHelpCommandPlaceholder() { + return getHelpCommandPlaceholder(null); + } + + public String getHelpCommandPlaceholder(@Nullable DataContext dataContext) { + if (dataContext != null) { + Project project = fetchProject(dataContext); + MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project); + if (projectsManager.isMavenizedProject()) { + if (projectsManager.getProjects().size() > 1) { + return "maven "; + } + else { + return "maven "; + } + } + } + return "maven "; + } + + @Override + public void execute(@NotNull DataContext dataContext, @NotNull String value) { + Project project = fetchProject(dataContext); + MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project); + if (!projectsManager.isMavenizedProject()) { + return; + } + + List mavenProjects = projectsManager.getProjects(); + boolean onlyOneMavenProject = mavenProjects.size() == 1; + + List goals = new ArrayList<>(ParametersListUtil.parse(trimStart(value, getHelpCommand()).trim())); + if (!goals.isEmpty()) { + + MavenProject mavenProject = null; + if (onlyOneMavenProject) { + mavenProject = mavenProjects.get(0); + } + else { + String moduleName = goals.remove(0); + Module module = ModuleManager.getInstance(project).findModuleByName(moduleName); + if (module != null) { + mavenProject = projectsManager.findProject(module); + } + } + + if (mavenProject != null) { + MavenExplicitProfiles explicitProfiles = projectsManager.getExplicitProfiles(); + MavenRunnerParameters params = new MavenRunnerParameters(true, + mavenProject.getDirectory(), + mavenProject.getFile().getName(), + goals, + explicitProfiles.getEnabledProfiles(), + explicitProfiles.getDisabledProfiles()); + + MavenRunner.getInstance(project).run(params, null, null); + } + } + } +} diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 252b5c7aab2a..9ded887c8d41 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -189,6 +189,8 @@ + + diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProviderTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProviderTest.java new file mode 100644 index 000000000000..32162ffbe238 --- /dev/null +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunAnythingProviderTest.java @@ -0,0 +1,106 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.execution; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.impl.SimpleDataContext; +import org.jetbrains.idea.maven.MavenImportingTestCase; +import org.jetbrains.idea.maven.model.MavenConstants; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import static com.intellij.openapi.util.text.StringUtil.substringBefore; +import static com.intellij.openapi.util.text.StringUtil.trimStart; +import static java.util.stream.Collectors.groupingBy; +import static org.junit.Assert.assertNotEquals; + +/** + * @author ibessonov + */ +public class MavenRunAnythingProviderTest extends MavenImportingTestCase { + + private DataContext myDataContext; + private MavenRunAnythingProvider myProvider; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + myDataContext = SimpleDataContext.getProjectContext(myProject); + myProvider = new MavenRunAnythingProvider(); + } + + public void testRegularProject() { + assertEmpty(myProvider.getValues(myDataContext, "maven")); + } + + public void testSingleMavenProject() { + importProject("test" + + "project" + + "1"); + + Collection values = myProvider.getValues(myDataContext, "maven"); + assertEquals(40, values.size()); + + Map> groupedValues = values.stream().map(value -> trimStart(value, "maven ")).collect( + groupingBy(value -> value.contains(":") ? substringBefore(value, ":") : "") + ); + assertSameElements(groupedValues.keySet(), "", "clean", "compiler", "surefire", "resources", "jar", "install", "deploy", "site"); + + assertSameElements(groupedValues.get(""), MavenConstants.BASIC_PHASES); + assertSameElements(groupedValues.get("clean"), "clean:clean", "clean:help"); + assertSameElements(groupedValues.get("compiler"), "compiler:testCompile", "compiler:compile", "compiler:help"); + // and so on + } + + public void testMavenProjectWithModules() { + createModulePom("m1", "test" + + "m1" + + "1" + + "" + + " " + + " " + + " org.apache.maven.plugins" + + " maven-war-plugin" + + " 3.2.2" + + " " + + " " + + ""); + + importProject("test" + + "project" + + "1" + + "" + + " m1" + + ""); + resolvePlugins(); + + Collection values = myProvider.getValues(myDataContext, "maven"); + assertSameElements(values, "maven project", "maven m1"); + + values = myProvider.getValues(myDataContext, "maven something"); + assertSameElements(values, "maven project", "maven m1"); + + + Collection projectValues = myProvider.getValues(myDataContext, "maven project"); + assertTrue(projectValues.stream().allMatch(value -> value.startsWith("maven project") || value.equals("maven m1"))); + + projectValues = myProvider.getValues(myDataContext, "maven project "); + assertTrue(projectValues.stream().allMatch(value -> value.startsWith("maven project"))); + + + Collection moduleValues = myProvider.getValues(myDataContext, "maven m1"); + assertTrue(moduleValues.stream().allMatch(value -> value.startsWith("maven m1") || value.equals("maven project"))); + + moduleValues = myProvider.getValues(myDataContext, "maven m1 "); + assertTrue(moduleValues.stream().allMatch(value -> value.startsWith("maven m1"))); + + + assertNotEquals(new HashSet<>(projectValues), new HashSet<>(moduleValues)); + + assertContain((List)moduleValues, "maven m1 war:help", "maven m1 war:inplace", "maven m1 war:exploded", "maven m1 war:war"); + assertDoNotContain((List)projectValues, "maven project war:war"); + } +}