external system aware make draft (IDEA-135128, IDEA-131627)

This commit is contained in:
Vladislav.Soroka
2016-09-21 12:30:57 +03:00
committed by Vladislav.Soroka
parent cffb31a2bb
commit 4a97c1643b
41 changed files with 1551 additions and 99 deletions
@@ -20,8 +20,7 @@ import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
@@ -42,7 +41,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.packaging.impl.compiler.ArtifactsWorkspaceSettings;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.util.containers.ContainerUtil;
@@ -90,7 +88,7 @@ public class BuildArtifactAction extends DumbAwareAction {
selectedIndices.add(0);
selectedArtifacts.clear();
}
for (Artifact artifact : artifacts) {
final ArtifactPopupItem item = new ArtifactPopupItem(artifact, artifact.getName(), artifact.getArtifactType().getIcon());
if (selectedArtifacts.contains(artifact)) {
@@ -98,10 +96,10 @@ public class BuildArtifactAction extends DumbAwareAction {
}
items.add(item);
}
final ProjectSettingsService projectSettingsService = ProjectSettingsService.getInstance(project);
final ArtifactAwareProjectSettingsService settingsService = projectSettingsService instanceof ArtifactAwareProjectSettingsService ? (ArtifactAwareProjectSettingsService)projectSettingsService : null;
final ChooseArtifactStep step = new ChooseArtifactStep(items, artifacts.get(0), project, settingsService);
step.setDefaultOptionIndices(selectedIndices.toNativeArray());
@@ -121,20 +119,21 @@ public class BuildArtifactAction extends DumbAwareAction {
}
private static void doBuild(@NotNull Project project, final @NotNull List<ArtifactPopupItem> items, boolean rebuild) {
final Set<Artifact> artifacts = getArtifacts(items, project);
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, rebuild);
ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
//in external build we can set 'rebuild' flag per target type
CompilerManager.getInstance(project).make(scope, null);
final Artifact[] artifacts = getArtifacts(items, project);
if (rebuild) {
BuildSystemManager.getInstance(project).rebuild(artifacts);
}
else {
BuildSystemManager.getInstance(project).build(artifacts);
}
}
private static Set<Artifact> getArtifacts(final List<ArtifactPopupItem> items, final Project project) {
private static Artifact[] getArtifacts(final List<ArtifactPopupItem> items, final Project project) {
Set<Artifact> artifacts = new LinkedHashSet<>();
for (ArtifactPopupItem item : items) {
artifacts.addAll(item.getArtifacts(project));
}
return artifacts;
return ContainerUtil.toArray(artifacts, new Artifact[artifacts.size()]);
}
private static class BuildArtifactItem extends ArtifactActionItem {
@@ -167,7 +166,7 @@ public class BuildArtifactAction extends DumbAwareAction {
Map<String, String> outputPathContainingSourceRoots = new HashMap<>();
final List<Pair<File, Artifact>> toClean = new ArrayList<>();
Set<Artifact> artifacts = getArtifacts(myArtifactPopupItems, myProject);
Artifact[] artifacts = getArtifacts(myArtifactPopupItems, myProject);
for (Artifact artifact : artifacts) {
String outputPath = artifact.getOutputFilePath();
if (outputPath != null) {
@@ -18,6 +18,7 @@ package com.intellij.compiler.actions;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.fileTypes.FileType;
@@ -37,12 +38,12 @@ public class CompileAction extends CompileActionBase {
protected void doAction(DataContext dataContext, Project project) {
final Module module = dataContext.getData(LangDataKeys.MODULE_CONTEXT);
if (module != null) {
CompilerManager.getInstance(project).compile(module, null);
BuildSystemManager.getInstance(project).rebuild(module);
}
else {
VirtualFile[] files = getCompilableFiles(project, dataContext.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY));
if (files.length > 0) {
CompilerManager.getInstance(project).compile(files, null);
BuildSystemManager.getInstance(project).compile(files);
}
}
@@ -18,13 +18,13 @@ package com.intellij.compiler.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.project.Project;
public class CompileDirtyAction extends CompileActionBase {
protected void doAction(DataContext dataContext, Project project) {
CompilerManager.getInstance(project).make(null);
BuildSystemManager.getInstance(project).buildProjectDirty();
}
public void update(AnActionEvent e){
@@ -19,24 +19,24 @@ import com.intellij.history.LocalHistory;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileStatusNotification;
import com.intellij.openapi.build.BuildContext;
import com.intellij.openapi.build.BuildStatusNotification;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.project.Project;
public class CompileProjectAction extends CompileActionBase {
protected void doAction(DataContext dataContext, final Project project) {
CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() {
public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
BuildSystemManager.getInstance(project).rebuildProject(new BuildStatusNotification() {
@Override
public void finished(boolean aborted, int errors, int warnings, BuildContext buildContext) {
if (aborted || project.isDisposed()) {
return;
}
String text = getTemplatePresentation().getText();
LocalHistory.getInstance().putSystemLabel(project, errors == 0
? CompilerBundle.message("rebuild.lvcs.label.no.errors", text)
: CompilerBundle.message("rebuild.lvcs.label.with.errors", text));
LocalHistory.getInstance().putSystemLabel(
project, CompilerBundle.message(errors == 0 ? "rebuild.lvcs.label.no.errors" : "rebuild.lvcs.label.with.errors", text));
}
});
}
@@ -16,8 +16,8 @@
package com.intellij.compiler.actions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -36,7 +36,7 @@ public class MakeModuleAction extends CompileActionBase {
modules = new Module[]{module};
}
try {
CompilerManager.getInstance(project).make(modules[0].getProject(), modules, null);
BuildSystemManager.getInstance(project).buildDirty(modules);
}
catch (Exception e) {
LOG.error(e);
@@ -0,0 +1,53 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.runners.BuildSystemExecutionEnvironmentProvider;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class BuildSystemExecutionEnvironmentProviderImpl implements BuildSystemExecutionEnvironmentProvider {
@Nullable
@Override
public ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
for (BuildSystemDriver buildSystemDriver : BuildSystemDriver.EP_NAME.getExtensions()) {
if (buildSystemDriver.canRun(executor.getId(), runProfile)) {
return buildSystemDriver.createExecutionEnvironment(
runProfile, executor, target, project, runnerSettings, configurationSettings, settings);
}
}
return null;
}
}
@@ -0,0 +1,152 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.intellij.util.containers.ContainerUtil.list;
import static com.intellij.util.containers.ContainerUtil.map;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class BuildSystemManagerImpl extends BuildSystemManager {
private final BuildSystemDriver myDefaultBuildSystemDriver = new DefaultBuildSystemDriver();
public BuildSystemManagerImpl(@NotNull Project project) {
super(project);
}
@Override
public void buildDirty(@NotNull Module[] modules, @Nullable BuildStatusNotification callback) {
BuildScope buildScope = new BuildScopeImpl(map(list(modules), ModuleBuildTarget::new));
doBuild(buildScope, true, callback);
}
@Override
public void rebuild(@NotNull Module[] modules, @Nullable BuildStatusNotification callback) {
BuildScope buildScope = new BuildScopeImpl(map(list(modules), ModuleBuildTarget::new));
doBuild(buildScope, false, callback);
}
@Override
public void compile(@NotNull VirtualFile[] files, @Nullable BuildStatusNotification callback) {
List<ModuleFilesBuildTarget> buildTargets = Arrays.stream(files)
.collect(Collectors.groupingBy(file -> ProjectFileIndex.SERVICE.getInstance(myProject).getModuleForFile(file, false)))
.entrySet().stream()
.map(entry -> new ModuleFilesBuildTarget(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
BuildScope buildScope = new BuildScopeImpl(buildTargets);
doBuild(buildScope, false, callback);
}
@Override
public void build(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback) {
doBuild(artifacts, callback, true);
}
@Override
public void rebuild(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback) {
doBuild(artifacts, callback, false);
}
@Override
public void buildDirty(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback) {
doBuild(scope, true, callback);
}
@Override
public void rebuild(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback) {
doBuild(scope, false, callback);
}
@Override
public void buildProjectDirty(@Nullable BuildStatusNotification callback) {
doBuild(new ProjectBuildScope(myProject), true, callback);
}
@Override
public void rebuildProject(@Nullable BuildStatusNotification callback) {
doBuild(new ProjectBuildScope(myProject), false, callback);
}
@NotNull
private static BuildSystemDriver[] getBuildDrivers() {
return BuildSystemDriver.EP_NAME.getExtensions();
}
private void doBuild(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback, boolean isIncrementalBuild) {
BuildScope buildScope = new BuildScopeImpl(map(list(artifacts), ArtifactBuildTarget::new));
doBuild(buildScope, isIncrementalBuild, callback);
}
private void doBuild(@NotNull BuildScope scope, boolean isIncrementalBuild, @Nullable BuildStatusNotification callback) {
Map<BuildSystemDriver, ? extends List<? extends BuildTarget>> toBuild =
scope.getTargets().stream().collect(Collectors.groupingBy(buildTarget -> {
for (BuildSystemDriver driver : getBuildDrivers()) {
if (driver.canBuild(buildTarget)) return driver;
}
return myDefaultBuildSystemDriver;
}));
for (Map.Entry<BuildSystemDriver, ? extends List<? extends BuildTarget>> entry : toBuild.entrySet()) {
BuildSystemDriver driver = entry.getKey();
BuildScope buildScope = toBuild.size() == 1 ? scope : new BuildScopeImpl(entry.getValue(), scope.getSessionId());
driver.build(new BuildContextImpl(myProject, buildScope, isIncrementalBuild), callback);
}
}
private static class BuildContextImpl implements BuildContext {
private final BuildScope myBuildScope;
private final boolean myIsIncrementalBuild;
private final Project myProject;
public BuildContextImpl(Project project, BuildScope buildScope, boolean isIncrementalBuild) {
myProject = project;
myBuildScope = buildScope;
myIsIncrementalBuild = isIncrementalBuild;
}
@Override
public Project getProject() {
return myProject;
}
@Override
public BuildScope getScope() {
return myBuildScope;
}
@Override
public boolean isIncrementalBuild() {
return myIsIncrementalBuild;
}
}
}
@@ -0,0 +1,146 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.compiler.impl.ModuleCompileScope;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.impl.ExecutionManagerImpl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompileStatusNotification;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.packaging.impl.compiler.ArtifactsWorkspaceSettings;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class DefaultBuildSystemDriver extends BuildSystemDriver {
@Override
public void build(@NotNull BuildContext buildContext, @Nullable BuildStatusNotification callback) {
CompileStatusNotification compileNotification =
callback == null ? null : (aborted, errors, warnings, compileContext) -> callback.finished(aborted, errors, warnings, buildContext);
if (buildContext.getScope() instanceof ProjectBuildScope) {
buildProject(buildContext, compileNotification);
}
else {
Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap =
buildContext.getScope().getTargets().stream().collect(Collectors.groupingBy(BuildTarget::getClass));
buildModulesTargets(buildContext, compileNotification, targetsMap);
buildFilesTargets(buildContext, compileNotification, targetsMap);
buildArtifactsTargets(buildContext, compileNotification, targetsMap);
}
}
@Override
public boolean canBuild(@NotNull BuildTarget buildTarget) {
return true;
}
@Override
public boolean canRun(@NotNull String executorId, @NotNull RunProfile runProfile) {
return true;
}
@Override
public ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget executionTarget,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
return null;
}
private static void buildProject(BuildContext buildContext, CompileStatusNotification callback) {
Project project = buildContext.getProject();
if (buildContext.isIncrementalBuild()) {
CompilerManager.getInstance(project).make(callback);
}
else {
CompilerManager.getInstance(project).rebuild(callback);
}
}
private static void buildModulesTargets(@NotNull BuildContext buildContext,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap) {
Project project = buildContext.getProject();
Collection<? extends BuildTarget> buildTargets = targetsMap.get(ModuleBuildTarget.class);
if (!ContainerUtil.isEmpty(buildTargets)) {
Module[] modules = ContainerUtil.map2Array(buildTargets, Module.class, target -> ModuleBuildTarget.class.cast(target).getModule());
if (buildContext.isIncrementalBuild()) {
CompilerManager.getInstance(project).make(project, modules, compileNotification);
}
else {
ModuleCompileScope compileScope = new ModuleCompileScope(project, modules, true);
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(compileScope, buildContext.getScope().getSessionId());
CompilerManager.getInstance(project).compile(compileScope, compileNotification);
}
}
}
private static void buildFilesTargets(@NotNull BuildContext buildContext,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap) {
Collection<? extends BuildTarget> filesTargets = targetsMap.get(ModuleFilesBuildTarget.class);
if (!ContainerUtil.isEmpty(filesTargets)) {
VirtualFile[] files = filesTargets.stream()
.flatMap(target -> Stream.of(ModuleFilesBuildTarget.class.cast(target).getFiles()))
.toArray(VirtualFile[]::new);
CompilerManager.getInstance(buildContext.getProject()).compile(files, compileNotification);
}
}
private static void buildArtifactsTargets(@NotNull BuildContext buildContext,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap) {
Collection<? extends BuildTarget> artifactsTargets = targetsMap.get(ArtifactBuildTarget.class);
if (!ContainerUtil.isEmpty(artifactsTargets)) {
Project project = buildContext.getProject();
Collection<Artifact> artifacts = artifactsTargets.stream()
.map(target -> ArtifactBuildTarget.class.cast(target).getArtifact())
.collect(Collectors.toList());
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, !buildContext.isIncrementalBuild());
ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(scope, buildContext.getScope().getSessionId());
//in external build we can set 'rebuild' flag per target type
CompilerManager.getInstance(project).make(scope, compileNotification);
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.ContainerUtil;
/**
* @author Vladislav.Soroka
* @since 7/6/2016
*/
public class ProjectBuildScope extends BuildScopeImpl {
private final Project myProject;
public ProjectBuildScope(final Project project) {
super(ContainerUtil.map(ModuleManager.getInstance(project).getModules(), ModuleBuildTarget::new));
myProject = project;
}
public Project getProject() {
return myProject;
}
}
@@ -29,14 +29,14 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.build.*;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogBuilder;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.packaging.artifacts.*;
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
@@ -175,9 +175,13 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B
}
}
}.execute();
final CompileStatusNotification callback = new CompileStatusNotification() {
public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
final BuildStatusNotification callback = new BuildStatusNotification() {
@Override
public void finished(boolean aborted,
int errors,
int warnings,
BuildContext buildContext) {
result.set(!aborted && errors == 0);
finished.up();
}
@@ -187,11 +191,10 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B
if (myProject.isDisposed()) {
return;
}
final CompilerManager manager = CompilerManager.getInstance(myProject);
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(myProject, artifacts);
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(scope, ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env));
List<ArtifactBuildTarget> artifactBuildTargets = ContainerUtil.map(artifacts, ArtifactBuildTarget::new);
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
finished.down();
manager.make(scope, CompilerFilter.ALL, callback);
BuildSystemManager.getInstance(myProject).buildDirty(new BuildScopeImpl(artifactBuildTargets, sessionId), callback);
}, ModalityState.NON_MODAL);
finished.waitFor();
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.packaging.artifacts.Artifact;
/**
* @author Vladislav.Soroka
* @since 5/14/2016
*/
public class ArtifactBuildTarget implements BuildTarget {
private final Artifact myArtifact;
public ArtifactBuildTarget(Artifact artifact) {
myArtifact = artifact;
}
public Artifact getArtifact() {
return myArtifact;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.project.Project;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public interface BuildContext {
Project getProject();
BuildScope getScope();
boolean isIncrementalBuild();
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public interface BuildScope {
Collection<? extends BuildTarget> getTargets();
void setSessionId(Object sessionId);
Object getSessionId();
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class BuildScopeImpl implements BuildScope {
private final Collection<? extends BuildTarget> myTargets;
@Nullable
private Object mySessionId;
public BuildScopeImpl(Collection<? extends BuildTarget> targets) {
myTargets = targets;
}
public BuildScopeImpl(Collection<? extends BuildTarget> targets, @Nullable Object sessionId) {
myTargets = targets;
mySessionId = sessionId;
}
@Override
public Collection<? extends BuildTarget> getTargets() {
return myTargets;
}
@Override
public void setSessionId(@Nullable Object sessionId) {
mySessionId = sessionId;
}
@Nullable
@Override
public Object getSessionId() {
return mySessionId;
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public interface BuildStatusNotification {
/**
*
* @param aborted true if the build has been cancelled.
* @param errors error count
* @param warnings warning count
* @param buildContext context for the build
*/
void finished(boolean aborted, int errors, int warnings, final BuildContext buildContext);
}
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* TODO
* get compiled files status
*
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public abstract class BuildSystemDriver {
public static final ExtensionPointName<BuildSystemDriver> EP_NAME = ExtensionPointName.create("com.intellij.buildSystemDriver");
public abstract void build(@NotNull BuildContext buildContext, @Nullable BuildStatusNotification callback);
public abstract boolean canBuild(@NotNull BuildTarget buildTarget);
public abstract boolean canRun(@NotNull String executorId, @NotNull RunProfile runProfile);
public abstract ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget executionTarget,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings);
}
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Provides services to build project, modules, files or artifacts.
* <p>
*
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public abstract class BuildSystemManager {
protected final @NotNull Project myProject;
public BuildSystemManager(@NotNull Project project) {
myProject = project;
}
public static BuildSystemManager getInstance(Project project) {
return ServiceManager.getService(project, BuildSystemManager.class);
}
public abstract void buildProjectDirty(@Nullable BuildStatusNotification callback);
public void buildProjectDirty() {
buildProjectDirty(null);
}
public abstract void rebuildProject(@Nullable BuildStatusNotification callback);
public void rebuildProject() {
rebuildProject(null);
}
public abstract void buildDirty(@NotNull Module[] modules, @Nullable BuildStatusNotification callback);
public void buildDirty(@NotNull Module... modules) {
buildDirty(modules, null);
}
public abstract void rebuild(@NotNull Module[] modules, @Nullable BuildStatusNotification callback);
public void rebuild(@NotNull Module... modules) {
rebuild(modules, null);
}
public abstract void compile(@NotNull VirtualFile[] files, @Nullable BuildStatusNotification callback);
public void compile(@NotNull VirtualFile... files) {
compile(files, null);
}
public abstract void build(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback);
public void build(@NotNull Artifact[] artifacts) {
build(artifacts, null);
}
public abstract void rebuild(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback);
public void rebuild(@NotNull Artifact... artifacts) {
rebuild(artifacts, null);
}
public abstract void buildDirty(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback);
public abstract void rebuild(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback);
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public interface BuildTarget {
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.module.Module;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class ModuleBuildTarget implements BuildTarget {
private final Module myModule;
public ModuleBuildTarget(Module module) {
myModule = module;
}
public Module getModule() {
return myModule;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2016 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 com.intellij.openapi.build;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 5/14/2016
*/
public class ModuleFilesBuildTarget extends ModuleBuildTarget {
private final VirtualFile[] myFiles;
public ModuleFilesBuildTarget(Module module, VirtualFile[] files) {
super(module);
myFiles = files;
}
public ModuleFilesBuildTarget(Module module, Collection<VirtualFile> files) {
this(module, ArrayUtil.toObjectArray(files, VirtualFile.class));
}
public VirtualFile[] getFiles() {
return myFiles;
}
}
@@ -1,8 +1,12 @@
package com.intellij.openapi.externalSystem.model.settings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -23,7 +27,7 @@ import java.util.concurrent.atomic.AtomicReference;
* @author Denis Zhdanov
* @since 8/9/11 12:12 PM
*/
public class ExternalSystemExecutionSettings implements Serializable {
public class ExternalSystemExecutionSettings implements Serializable, UserDataHolder {
public static final String REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY = "external.system.remote.process.idle.ttl.ms";
private static final int DEFAULT_REMOTE_PROCESS_TTL_MS = 60000;
@@ -36,6 +40,8 @@ public class ExternalSystemExecutionSettings implements Serializable {
@NotNull private final AtomicReference<ExternalSystemTaskNotificationListener> myNotificationListener =
new AtomicReference<>();
@NotNull private transient UserDataHolderBase myUserData = new UserDataHolderBase();
public ExternalSystemExecutionSettings() {
int ttl = SystemProperties.getIntProperty(REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, DEFAULT_REMOTE_PROCESS_TTL_MS);
setRemoteProcessIdleTtlInMs(ttl);
@@ -60,6 +66,17 @@ public class ExternalSystemExecutionSettings implements Serializable {
myVerboseProcessing.set(verboseProcessing);
}
@Nullable
@Override
public <U> U getUserData(@NotNull Key<U> key) {
return myUserData.getUserData(key);
}
@Override
public <U> void putUserData(@NotNull Key<U> key, U value) {
myUserData.putUserData(key, value);
}
@Override
public int hashCode() {
int result = (int)(myRemoteProcessIdleTtlInMs.get() ^ (myRemoteProcessIdleTtlInMs.get() >>> 32));
@@ -27,10 +27,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.*;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.net.NetUtils;
@@ -106,10 +103,13 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException {
return new MyRunnableState(mySettings, getProject(), DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId()), this, env);
MyRunnableState runnableState =
new MyRunnableState(mySettings, getProject(), DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId()), this, env);
copyUserDataTo(runnableState);
return runnableState;
}
public static class MyRunnableState implements RunProfileState {
public static class MyRunnableState extends UserDataHolderBase implements RunProfileState {
@NotNull private final ExternalSystemTaskExecutionSettings mySettings;
@NotNull private final Project myProject;
@@ -173,6 +173,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
mySettings.getVmOptions(),
mySettings.getScriptParameters(),
debuggerSetup);
copyUserDataTo(task);
final MyProcessHandler processHandler = new MyProcessHandler(task);
final ExternalSystemExecutionConsoleManager<ExternalSystemRunConfiguration, ExecutionConsole, ProcessHandler>
@@ -11,6 +11,7 @@ import com.intellij.openapi.externalSystem.service.notification.*;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -24,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
* @author Denis Zhdanov
* @since 1/24/12 7:03 AM
*/
public abstract class AbstractExternalSystemTask implements ExternalSystemTask {
public abstract class AbstractExternalSystemTask extends UserDataHolderBase implements ExternalSystemTask {
private static final Logger LOG = Logger.getInstance("#" + AbstractExternalSystemTask.class.getName());
@@ -25,10 +25,11 @@ import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade;
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.util.Function;
import com.intellij.openapi.util.Key;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.execution.ParametersListUtil;
import com.intellij.util.keyFMap.KeyFMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,8 +42,6 @@ import java.util.List;
*/
public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask {
@NotNull private static final Function<ExternalTaskPojo, String> MAPPER = task -> task.getName();
@NotNull private final List<ExternalTaskPojo> myTasksToExecute;
@Nullable private final String myVmOptions;
@Nullable private String myScriptParameters;
@@ -112,9 +111,14 @@ public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask {
ExternalSystemExecutionSettings settings = ExternalSystemApiUtil.getExecutionSettings(getIdeProject(),
getExternalProjectPath(),
getExternalSystemId());
KeyFMap keyFMap = getUserMap();
for (Key key : keyFMap.getKeys()) {
settings.putUserData(key, keyFMap.get(key));
}
RemoteExternalSystemFacade facade = manager.getFacade(getIdeProject(), getExternalProjectPath(), getExternalSystemId());
RemoteExternalSystemTaskManager taskManager = facade.getTaskManager();
List<String> taskNames = ContainerUtilRt.map2List(myTasksToExecute, MAPPER);
List<String> taskNames = ContainerUtilRt.map2List(myTasksToExecute, ExternalTaskPojo::getName);
final List<String> vmOptions = parseCmdParameters(myVmOptions);
final List<String> scriptParametersList = parseCmdParameters(myScriptParameters);
@@ -233,7 +233,7 @@ public class ExternalSystemTaskActivator {
targetDone.up();
}
},
ProgressExecutionMode.IN_BACKGROUND_ASYNC);
ProgressExecutionMode.IN_BACKGROUND_ASYNC, false);
targetDone.waitFor();
return result.get();
}
@@ -21,33 +21,20 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTreeModel;
import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.event.InputEvent;
import java.lang.reflect.Field;
import java.util.*;
import java.util.List;
/**
* @author Denis Zhdanov
@@ -55,7 +42,7 @@ import java.util.List;
*/
public class ExternalSystemUiUtil {
public static final int INSETS = 7;
public static final int INSETS = 5;
private static final int BALLOON_FADEOUT_TIME = 5000;
private ExternalSystemUiUtil() {
@@ -91,13 +78,13 @@ public class ExternalSystemUiUtil {
@NotNull
public static GridBag getLabelConstraints(int indentLevel) {
Insets insets = new Insets(INSETS, INSETS + INSETS * indentLevel, 0, INSETS);
Insets insets = JBUI.insets(INSETS, INSETS + INSETS * indentLevel, 0, INSETS);
return new GridBag().anchor(GridBagConstraints.WEST).weightx(0).insets(insets);
}
@NotNull
public static GridBag getFillLineConstraints(int indentLevel) {
Insets insets = new Insets(INSETS, INSETS + INSETS * indentLevel, 0, INSETS);
Insets insets = JBUI.insets(INSETS, INSETS + INSETS * indentLevel, 0, INSETS);
return new GridBag().weightx(1).coverLine().fillCellHorizontally().anchor(GridBagConstraints.WEST).insets(insets);
}
@@ -520,11 +520,24 @@ public class ExternalSystemUtil {
@NotNull final ProjectSystemId externalSystemId,
@Nullable final TaskCallback callback,
@NotNull final ProgressExecutionMode progressExecutionMode) {
runTask(taskSettings, executorId, project, externalSystemId, callback, progressExecutionMode, true);
}
public static void runTask(@NotNull final ExternalSystemTaskExecutionSettings taskSettings,
@NotNull final String executorId,
@NotNull final Project project,
@NotNull final ProjectSystemId externalSystemId,
@Nullable final TaskCallback callback,
@NotNull final ProgressExecutionMode progressExecutionMode,
boolean activateToolWindowBeforeRun) {
final Pair<ProgramRunner, ExecutionEnvironment> pair = createRunner(taskSettings, executorId, project, externalSystemId);
if (pair == null) return;
final ProgramRunner runner = pair.first;
final ExecutionEnvironment environment = pair.second;
RunnerAndConfigurationSettings runnerAndConfigurationSettings = environment.getRunnerAndConfigurationSettings();
assert runnerAndConfigurationSettings != null;
runnerAndConfigurationSettings.setActivateToolWindowBeforeRun(activateToolWindowBeforeRun);
final TaskUnderProgress task = new TaskUnderProgress() {
@Override
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2016 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 com.intellij.execution.runners;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 6/2/2016
*/
public interface BuildSystemExecutionEnvironmentProvider {
@Nullable
ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings);
}
@@ -22,6 +22,7 @@ import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolderBase;
import org.jetbrains.annotations.NotNull;
@@ -165,7 +166,10 @@ public final class ExecutionEnvironmentBuilder {
@NotNull
public ExecutionEnvironment build() {
if (myRunner == null) {
ExecutionEnvironment environment = ServiceManager.getService(myProject, BuildSystemExecutionEnvironmentProvider.class).createExecutionEnvironment(
myRunProfile, myExecutor, myTarget, myProject, myRunnerSettings, myConfigurationSettings, myRunnerAndConfigurationSettings);
if (environment == null && myRunner == null) {
if (myRunnerId == null) {
myRunner = RunnerRegistry.getInstance().getRunner(myExecutor.getId(), myRunProfile);
}
@@ -174,12 +178,15 @@ public final class ExecutionEnvironmentBuilder {
}
}
if (myRunner == null) {
if (environment == null && myRunner == null) {
throw new IllegalStateException("Runner must be specified");
}
ExecutionEnvironment environment = new ExecutionEnvironment(myRunProfile, myExecutor, myTarget, myProject, myRunnerSettings, myConfigurationSettings, myContentToReuse,
myRunnerAndConfigurationSettings, myRunner);
if (environment == null) {
environment = new ExecutionEnvironment(myRunProfile, myExecutor, myTarget, myProject, myRunnerSettings,
myConfigurationSettings, myContentToReuse, myRunnerAndConfigurationSettings, myRunner);
}
if (myAssignNewId) {
environment.assignNewExecutionId();
}
@@ -7,6 +7,7 @@ gradle.settings.text.wrapper.customization.compatibility=Gradle wrapper customiz
gradle.settings.text.use.local.distribution=Use local gradle distribution
gradle.settings.text.use.bundled.distribution=Use bundled gradle distribution: ({0})
gradle.settings.text.create.module.per.sourceset=Create separate module per source set
gradle.settings.text.use.gradle.aware.make=Delegate IDE build/run actions to gradle
gradle.settings.text.home.path=Gradle home:
gradle.settings.text.jvm.path=Gradle JVM:
+2
View File
@@ -53,6 +53,7 @@
<extensionPoint name="frameworkSupport" interface="org.jetbrains.plugins.gradle.frameworkSupport.GradleFrameworkSupportProvider"/>
<extensionPoint name="pluginDescriptions" interface="org.jetbrains.plugins.gradle.codeInsight.GradlePluginDescriptionsExtension"/>
<extensionPoint name="testTasksProvider" interface="org.jetbrains.plugins.gradle.execution.test.runner.GradleTestTasksProvider"/>
<extensionPoint name="artifactBuildTasksProvider" interface="org.jetbrains.plugins.gradle.execution.build.GradleArtifactBuildTasksProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
@@ -77,6 +78,7 @@
<extensions defaultExtensionNs="com.intellij">
<buildSystemDriver implementation="org.jetbrains.plugins.gradle.execution.build.GradleBuildSystemDriver"/>
<postStartupActivity implementation="org.jetbrains.plugins.gradle.service.project.GradleStartupActivity"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler$FactoryImpl"/>
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2016 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.plugins.gradle.execution.build;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.BooleanFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 5/14/2016
*/
public class CachedModuleDataFinder {
private Map<String, DataNode<ModuleData>> cache = ContainerUtil.newHashMap();
@Nullable
public DataNode<ModuleData> findModuleData(final DataNode parentNode, final String projectPath) {
DataNode<ModuleData> node = cache.get(projectPath);
if (node != null) return node;
//noinspection unchecked
return (DataNode<ModuleData>)ExternalSystemApiUtil.findFirstRecursively(parentNode, new BooleanFunction<DataNode<?>>() {
@Override
public boolean fun(DataNode<?> node) {
if ((ProjectKeys.MODULE.equals(node.getKey()) ||
GradleSourceSetData.KEY.equals(node.getKey())) && node.getData() instanceof ModuleData) {
String externalProjectPath = ((ModuleData)node.getData()).getLinkedExternalProjectPath();
//noinspection unchecked
DataNode<ModuleData> myNode = (DataNode<ModuleData>)node;
cache.put(externalProjectPath, myNode);
return StringUtil.equals(projectPath, ((ModuleData)node.getData()).getLinkedExternalProjectPath());
}
return false;
}
});
}
}
@@ -0,0 +1,126 @@
/*
* Copyright 2000-2016 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.plugins.gradle.execution.build;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.task.GradleTaskManager;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.util.Collections;
/**
* TODO take into account applied 'application' gradle plugins or existing JavaExec tasks
*
* @author Vladislav.Soroka
* @since 6/21/2016
*/
public class GradleApplicationEnvironmentBuilder {
@Nullable
public ExecutionEnvironment build(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget executionTarget,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
ApplicationConfiguration applicationConfiguration = (ApplicationConfiguration)runProfile;
PsiClass mainClass = applicationConfiguration.getMainClass();
if(mainClass == null) return null;
Module module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(mainClass.getContainingFile().getVirtualFile());
String externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module);
String projectId = ExternalSystemApiUtil.getExternalProjectId(module);
if (projectId == null || !projectId.startsWith(":")) {
projectId = ":";
} else {
if(!projectId.equals(":")) {
projectId = projectId.substring(0, projectId.lastIndexOf(':'));
}
}
final JavaParameters params = new JavaParameters();
JavaParametersUtil.configureConfiguration(params, applicationConfiguration);
params.getVMParametersList().addParametersString(applicationConfiguration.getVMParameters());
StringBuilder parametersString = new StringBuilder();
for (String parameter : params.getProgramParametersList().getParameters()) {
parametersString.append("args '").append(parameter).append("'\n");
}
StringBuilder vmParametersString = new StringBuilder();
for (String parameter : params.getVMParametersList().getParameters()) {
vmParametersString.append("jvmArgs '").append(parameter).append("'\n");
}
ExternalSystemTaskExecutionSettings taskSettings = new ExternalSystemTaskExecutionSettings();
taskSettings.setExternalSystemIdString(GradleConstants.SYSTEM_ID.getId());
taskSettings.setExternalProjectPath(externalProjectPath);
final String runAppTaskName = "run " + mainClass.getName();
taskSettings.setTaskNames(Collections.singletonList(runAppTaskName));
final Pair<ProgramRunner, ExecutionEnvironment> environmentPair =
ExternalSystemUtil.createRunner(taskSettings, executor.getId(), project, GradleConstants.SYSTEM_ID);
if (environmentPair != null) {
RunnerAndConfigurationSettings runnerAndConfigurationSettings = environmentPair.second.getRunnerAndConfigurationSettings();
assert runnerAndConfigurationSettings != null;
ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)runnerAndConfigurationSettings.getConfiguration();
@Language("Groovy")
String initScript = "projectsEvaluated {\n" +
" rootProject.allprojects {\n" +
" if(project.path == '" + projectId + "' && project.sourceSets) {\n" +
" project.tasks.create(name: '" + runAppTaskName + "', overwrite: true, type: JavaExec) {\n" +
" classpath = project.sourceSets.main.runtimeClasspath\n" +
" main = '" + mainClass.getQualifiedName() + "'\n" +
parametersString.toString() +
vmParametersString.toString() +
" }\n" +
" }\n" +
" }\n" +
"}\n";
runConfiguration.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, initScript);
return environmentPair.second;
}
else {
return null;
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2016 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.plugins.gradle.execution.build;
import com.intellij.openapi.build.BuildContext;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 7/11/2016
*/
public interface GradleArtifactBuildTasksProvider {
ExtensionPointName<GradleArtifactBuildTasksProvider> EP_NAME =
ExtensionPointName.create("org.jetbrains.plugins.gradle.artifactBuildTasksProvider");
boolean isApplicable(@NotNull Artifact artifact);
void addArtifactsTargetsBuildTasks(@NotNull BuildContext buildContext,
@NotNull Consumer<ExternalTaskPojo> cleanTasksConsumer,
@NotNull Consumer<ExternalTaskPojo> buildTasksConsumer,
@NotNull Artifact artifact);
}
@@ -0,0 +1,296 @@
/*
* Copyright 2000-2016 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.plugins.gradle.execution.build;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
import com.intellij.execution.configurations.JavaRunConfigurationModule;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.build.*;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.task.TaskCallback;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
import org.jetbrains.plugins.gradle.settings.GradleSettings;
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* TODO automatically create exploded-war task
* task explodedWar(type: Copy) {
* into "$buildDir/explodedWar"
* with war
* }
*
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public class GradleBuildSystemDriver extends BuildSystemDriver {
@Override
public void build(@NotNull BuildContext buildContext, @Nullable BuildStatusNotification buildCallback) {
String executionName = null;
if (buildContext.getScope() instanceof ProjectBuildScope) {
executionName = buildContext.isIncrementalBuild() ? "Make" : "Rebuild";
}
MultiMap<String, String> buildTasksMap = MultiMap.createLinkedSet();
MultiMap<String, String> cleanTasksMap = MultiMap.createLinkedSet();
Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap =
buildContext.getScope().getTargets().stream().collect(Collectors.groupingBy(BuildTarget::getClass));
addModulesTargetsBuildTasks(buildContext, targetsMap, cleanTasksMap, buildTasksMap);
addFilesTargetsBuildTasks(buildContext, targetsMap, cleanTasksMap, buildTasksMap);
addArtifactsTargetsBuildTasks(buildContext, targetsMap, cleanTasksMap, buildTasksMap);
// TODO send a message if nothing to build
Set<String> rootPaths = buildTasksMap.keySet();
AtomicInteger successCounter = new AtomicInteger();
AtomicInteger errorCounter = new AtomicInteger();
TaskCallback taskCallback = buildCallback == null ? null : new TaskCallback() {
@Override
public void onSuccess() {
handle(true);
}
@Override
public void onFailure() {
handle(false);
}
private void handle(boolean success) {
int successes = success ? successCounter.incrementAndGet() : successCounter.get();
int errors = success ? errorCounter.get() : errorCounter.incrementAndGet();
if (successes + errors == rootPaths.size()) {
buildCallback.finished(false, errors, 0, buildContext);
}
}
};
String gradleVmOptions = GradleSettings.getInstance(buildContext.getProject()).getGradleVmOptions();
for (String rootProjectPath : rootPaths) {
Collection<String> buildTasks = buildTasksMap.get(rootProjectPath);
if (buildTasks.isEmpty()) continue;
Collection<String> cleanTasks = cleanTasksMap.get(rootProjectPath);
ExternalSystemTaskExecutionSettings settings = new ExternalSystemTaskExecutionSettings();
settings.setExecutionName(executionName);
settings.setExternalProjectPath(rootProjectPath);
settings.setTaskNames(ContainerUtil.collect(ContainerUtil.concat(cleanTasks, buildTasks).iterator()));
//settings.setScriptParameters(scriptParameters);
settings.setVmOptions(gradleVmOptions);
settings.setExternalSystemIdString(GradleConstants.SYSTEM_ID.getId());
ExternalSystemUtil.runTask(settings, DefaultRunExecutor.EXECUTOR_ID, buildContext.getProject(), GradleConstants.SYSTEM_ID,
taskCallback, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false);
}
}
@Override
public boolean canBuild(@NotNull BuildTarget buildTarget) {
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false;
if (buildTarget instanceof ModuleBuildTarget) {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, ((ModuleBuildTarget)buildTarget).getModule());
}
if (buildTarget instanceof ArtifactBuildTarget) {
Artifact artifact = ((ArtifactBuildTarget)buildTarget).getArtifact();
for (GradleArtifactBuildTasksProvider buildTasksProvider : GradleArtifactBuildTasksProvider.EP_NAME.getExtensions()) {
if (buildTasksProvider.isApplicable(artifact)) return true;
}
}
return false;
}
@Override
public boolean canRun(@NotNull String executorId, @NotNull RunProfile runProfile) {
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false;
if (runProfile instanceof ApplicationConfiguration) {
JavaRunConfigurationModule module = ((ApplicationConfiguration)runProfile).getConfigurationModule();
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module.getModule());
}
return false;
}
@Override
public ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget executionTarget,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
if (runProfile instanceof ApplicationConfiguration) {
return new GradleApplicationEnvironmentBuilder().build(
runProfile, executor, executionTarget, project, runnerSettings, configurationSettings, settings);
}
return null;
}
private static void addModulesTargetsBuildTasks(@NotNull BuildContext buildContext,
@NotNull Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap,
@NotNull MultiMap<String, String> cleanTasksMap,
@NotNull MultiMap<String, String> buildTasksMap) {
Collection<? extends BuildTarget> buildTargets = targetsMap.get(ModuleBuildTarget.class);
if (!ContainerUtil.isEmpty(buildTargets)) {
Module[] modules = ContainerUtil.map2Array(buildTargets, Module.class, target -> ModuleBuildTarget.class.cast(target).getModule());
addModulesTargetsBuildTasks(buildContext, modules, cleanTasksMap, buildTasksMap);
}
}
private static void addFilesTargetsBuildTasks(BuildContext buildContext,
Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap,
MultiMap<String, String> cleanTasksMap, MultiMap<String, String> buildTasksMap) {
Collection<? extends BuildTarget> buildTargets = targetsMap.get(ModuleFilesBuildTarget.class);
if (!ContainerUtil.isEmpty(buildTargets)) {
// TODO there should be 'gradle' way to build files instead of the whole related modules
Module[] modules =
ContainerUtil.map2Array(buildTargets, Module.class, target -> ModuleFilesBuildTarget.class.cast(target).getModule());
addModulesTargetsBuildTasks(buildContext, modules, cleanTasksMap, buildTasksMap);
}
}
private static void addModulesTargetsBuildTasks(@NotNull BuildContext buildContext,
@NotNull Module[] modules,
@NotNull MultiMap<String, String> cleanTasksMap,
@NotNull MultiMap<String, String> buildTasksMap) {
final CachedModuleDataFinder moduleDataFinder = new CachedModuleDataFinder();
for (Module module : modules) {
final String rootProjectPath = ExternalSystemApiUtil.getExternalRootProjectPath(module);
if (rootProjectPath == null) continue;
final String projectId = ExternalSystemApiUtil.getExternalProjectId(module);
if (projectId == null) continue;
final String externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module);
if (externalProjectPath == null || StringUtil.endsWith(externalProjectPath, "buildSrc")) continue;
ExternalProjectInfo projectData =
ProjectDataManager.getInstance().getExternalProjectData(module.getProject(), GradleConstants.SYSTEM_ID, rootProjectPath);
if (projectData == null) continue;
DataNode<ProjectData> projectStructure = projectData.getExternalProjectStructure();
if (projectStructure == null) continue;
final DataNode<ModuleData> moduleDataNode = moduleDataFinder.findModuleData(projectStructure, externalProjectPath);
if (moduleDataNode == null) continue;
List<String> tasks = ContainerUtil.mapNotNull(ExternalSystemApiUtil.findAll(moduleDataNode, ProjectKeys.TASK),
node -> node.getData().isInherited() ? null : node.getData().getName());
Collection<String> cleanTasks = cleanTasksMap.getModifiable(rootProjectPath);
Collection<String> buildTasks = buildTasksMap.getModifiable(rootProjectPath);
final String moduleType = ExternalSystemApiUtil.getExternalModuleType(module);
final String gradlePath;
if (GradleConstants.GRADLE_SOURCE_SET_MODULE_TYPE_KEY.equals(moduleType)) {
int lastColonIndex = projectId.lastIndexOf(':');
assert lastColonIndex != -1;
int firstColonIndex = projectId.indexOf(':');
gradlePath = projectId.substring(firstColonIndex, lastColonIndex);
String sourceSetName = projectId.substring(lastColonIndex + 1);
String task = "main".equals(sourceSetName) ? "classes" : sourceSetName + "Classes";
if (tasks.contains(task)) {
if (!buildContext.isIncrementalBuild()) {
cleanTasks.add(gradlePath + ":clean" + StringUtil.capitalize(task));
}
buildTasks.add(gradlePath + ":" + task);
}
else if ("main".equals(sourceSetName) || "test".equals(sourceSetName)) {
if (!buildContext.isIncrementalBuild()) {
cleanTasks.add(gradlePath + ":clean");
}
buildTasks.add(gradlePath + ":build");
}
}
else {
GradleProjectSettings projectSettings =
GradleSettings.getInstance(buildContext.getProject()).getLinkedProjectSettings(rootProjectPath);
boolean sourceSetAwareMode = projectSettings != null && projectSettings.isResolveModulePerSourceSet();
if (!sourceSetAwareMode) {
gradlePath = projectId.charAt(0) == ':' ? projectId : "";
if (!buildContext.isIncrementalBuild()) {
if (tasks.contains("classes")) {
cleanTasks.add((StringUtil.equals(rootProjectPath, externalProjectPath) ? ":cleanClasses" : gradlePath + ":cleanClasses"));
}
else {
cleanTasks.add((StringUtil.equals(rootProjectPath, externalProjectPath) ? "clean" : gradlePath + ":clean"));
}
}
if (tasks.contains("classes")) {
buildTasks.add((StringUtil.equals(rootProjectPath, externalProjectPath) ? ":classes" : gradlePath + ":classes"));
}
else {
buildTasks.add((StringUtil.equals(rootProjectPath, externalProjectPath) ? "build" : gradlePath + ":build"));
}
}
}
}
}
private static void addArtifactsTargetsBuildTasks(BuildContext buildContext,
Map<Class<? extends BuildTarget>, List<BuildTarget>> targetsMap,
MultiMap<String, String> cleanTasksMap, MultiMap<String, String> buildTasksMap) {
Collection<? extends BuildTarget> buildTargets = targetsMap.get(ArtifactBuildTarget.class);
if (!ContainerUtil.isEmpty(buildTargets)) {
Artifact[] artifacts =
ContainerUtil.map2Array(buildTargets, Artifact.class, target -> ArtifactBuildTarget.class.cast(target).getArtifact());
for (Artifact artifact : artifacts) {
for (GradleArtifactBuildTasksProvider buildTasksProvider : GradleArtifactBuildTasksProvider.EP_NAME.getExtensions()) {
if (buildTasksProvider.isApplicable(artifact)) {
buildTasksProvider.addArtifactsTargetsBuildTasks(
buildContext,
task -> cleanTasksMap.putValue(task.getLinkedExternalProjectPath(), task.getName()),
task -> buildTasksMap.putValue(task.getLinkedExternalProjectPath(), task.getName()),
artifact
);
}
}
}
}
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemTaskEx
import com.intellij.openapi.externalSystem.task.AbstractExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -54,6 +55,8 @@ import java.util.Map;
public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleExecutionSettings>
implements ExternalSystemTaskManager<GradleExecutionSettings> {
public static final Key<String> INIT_SCRIPT_KEY = Key.create("INIT_SCRIPT_KEY");
private final GradleExecutionHelper myHelper = new GradleExecutionHelper();
private final Map<ExternalSystemTaskId, CancellationTokenSource> myCancellationMap = ContainerUtil.newConcurrentMap();
@@ -100,6 +103,15 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleE
});
}
final String initScript = settings == null ? null : settings.getUserData(INIT_SCRIPT_KEY);
if (StringUtil.isNotEmpty(initScript)) {
ContainerUtil.addAll(
initScripts,
"//-- Additional script",
initScript,
"//");
}
if (!initScripts.isEmpty()) {
try {
File tempFile =
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.gradle.settings.GradleRunnerConfigurable">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="923" height="400"/>
@@ -10,23 +10,29 @@
<children>
<component id="2c82f" class="com.intellij.openapi.ui.ComboBox" binding="myPreferredTestRunner" custom-create="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="5" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="5" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<vspacer id="6ca33">
<constraints>
<grid row="2" column="4" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="3" column="4" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2514a" class="com.intellij.ui.TitledSeparator">
<constraints>
<grid row="0" column="0" row-span="1" col-span="5" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="5" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&lt;html&gt;Run tests using:&lt;/html&gt;"/>
</properties>
</component>
<component id="2cae1" class="com.intellij.ui.components.JBCheckBox" binding="myGradleAwareMakeCheckBox" custom-create="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</form>
@@ -17,11 +17,9 @@ package org.jetbrains.plugins.gradle.settings;
import com.intellij.openapi.options.BaseConfigurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.components.JBCheckBox;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleBundle;
@@ -32,22 +30,16 @@ import java.util.Objects;
* @author Vladislav.Soroka
* @since 11/2/2015
*/
public class GradleRunnerConfigurable extends BaseConfigurable implements SearchableConfigurable {
public class GradleRunnerConfigurable extends BaseConfigurable {
private JPanel myMainPanel;
private JBCheckBox myGradleAwareMakeCheckBox;
private ComboBox myPreferredTestRunner;
private static final TestRunnerItem[] TEST_RUNNER_ITEMS = new TestRunnerItem[]{
new TestRunnerItem(GradleSystemRunningSettings.PreferredTestRunner.PLATFORM_TEST_RUNNER),
new TestRunnerItem(GradleSystemRunningSettings.PreferredTestRunner.GRADLE_TEST_RUNNER),
new TestRunnerItem(GradleSystemRunningSettings.PreferredTestRunner.CHOOSE_PER_TEST)};
private final Project myProject;
public GradleRunnerConfigurable(Project project) {
myProject = project;
}
@Nls
@Override
public String getDisplayName() {
@@ -62,15 +54,19 @@ public class GradleRunnerConfigurable extends BaseConfigurable implements Search
@Override
public void apply() throws ConfigurationException {
GradleSystemRunningSettings.getInstance().setPreferredTestRunner(
((TestRunnerItem)myPreferredTestRunner.getSelectedItem()).value);
boolean gradleMakeEnabled = myGradleAwareMakeCheckBox.isSelected();
GradleSystemRunningSettings settings = GradleSystemRunningSettings.getInstance();
settings.setUseGradleAwareMake(gradleMakeEnabled);
settings.setPreferredTestRunner(((TestRunnerItem)myPreferredTestRunner.getSelectedItem()).value);
}
@Override
public void reset() {
GradleSystemRunningSettings settings = GradleSystemRunningSettings.getInstance();
final TestRunnerItem item = getItem(settings.getPreferredTestRunner());
final TestRunnerItem item = getItem(settings.getLastPreferredTestRunner());
myPreferredTestRunner.setSelectedItem(item);
boolean gradleMakeEnabled = settings.isUseGradleAwareMake();
enableGradleMake(gradleMakeEnabled);
}
@Nullable
@@ -86,6 +82,7 @@ public class GradleRunnerConfigurable extends BaseConfigurable implements Search
GradleSystemRunningSettings.PreferredTestRunner preferredTestRunner =
selectedItem == null ? GradleSystemRunningSettings.PreferredTestRunner.CHOOSE_PER_TEST : selectedItem.value;
uiSettings.setPreferredTestRunner(preferredTestRunner);
uiSettings.setUseGradleAwareMake(myGradleAwareMakeCheckBox.isSelected());
GradleSystemRunningSettings settings = GradleSystemRunningSettings.getInstance();
return !settings.equals(uiSettings);
}
@@ -94,14 +91,15 @@ public class GradleRunnerConfigurable extends BaseConfigurable implements Search
public void disposeUIResources() {
}
@NotNull
@Override
public String getId() {
return "reference.settings.project.gradle.running";
private void createUIComponents() {
myGradleAwareMakeCheckBox = new JBCheckBox(GradleBundle.message("gradle.settings.text.use.gradle.aware.make"));
myGradleAwareMakeCheckBox.addActionListener(e -> enableGradleMake(myGradleAwareMakeCheckBox.isSelected()));
myPreferredTestRunner = new ComboBox<TestRunnerItem>(getItems());
}
private void createUIComponents() {
myPreferredTestRunner = new ComboBox(getItems());
private void enableGradleMake(boolean enable) {
myGradleAwareMakeCheckBox.setSelected(enable);
myPreferredTestRunner.setEnabled(!enable);
}
private static TestRunnerItem getItem(GradleSystemRunningSettings.PreferredTestRunner preferredTestRunner) {
@@ -31,6 +31,7 @@ import java.util.Objects;
@State(name = "GradleSystemRunningSettings", storages = @Storage("gradle.run.settings.xml"))
public class GradleSystemRunningSettings implements PersistentStateComponent<GradleSystemRunningSettings.MyState> {
private boolean myUseGradleAwareMake;
@NotNull private PreferredTestRunner myPreferredTestRunner = PreferredTestRunner.PLATFORM_TEST_RUNNER;
@NotNull
@@ -43,17 +44,24 @@ public class GradleSystemRunningSettings implements PersistentStateComponent<Gra
@Override
public GradleSystemRunningSettings.MyState getState() {
MyState state = new MyState();
state.useGradleAwareMake = myUseGradleAwareMake;
state.preferredTestRunner = myPreferredTestRunner;
return state;
}
@Override
public void loadState(MyState state) {
myUseGradleAwareMake = state.useGradleAwareMake;
myPreferredTestRunner = state.preferredTestRunner;
}
@NotNull
public PreferredTestRunner getPreferredTestRunner() {
return myUseGradleAwareMake ? PreferredTestRunner.GRADLE_TEST_RUNNER : myPreferredTestRunner;
}
@NotNull
PreferredTestRunner getLastPreferredTestRunner() {
return myPreferredTestRunner;
}
@@ -61,21 +69,31 @@ public class GradleSystemRunningSettings implements PersistentStateComponent<Gra
myPreferredTestRunner = preferredTestRunner;
}
public boolean isUseGradleAwareMake() {
return myUseGradleAwareMake;
}
public void setUseGradleAwareMake(boolean useGradleAwareMake) {
this.myUseGradleAwareMake = useGradleAwareMake;
}
public static class MyState {
public PreferredTestRunner preferredTestRunner;
public boolean useGradleAwareMake;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof GradleSystemRunningSettings)) return false;
if (o == null || getClass() != o.getClass()) return false;
GradleSystemRunningSettings settings = (GradleSystemRunningSettings)o;
return Objects.equals(myPreferredTestRunner, settings.myPreferredTestRunner);
return myUseGradleAwareMake == settings.myUseGradleAwareMake &&
myPreferredTestRunner == settings.myPreferredTestRunner;
}
@Override
public int hashCode() {
return Objects.hashCode(myPreferredTestRunner);
return Objects.hashCode(myPreferredTestRunner, myUseGradleAwareMake);
}
public enum PreferredTestRunner {
+2
View File
@@ -197,6 +197,8 @@
<extensionPoint name="testFramework" interface="com.intellij.testIntegration.TestFramework"/>
<extensionPoint name="buildSystemDriver" interface="com.intellij.openapi.build.BuildSystemDriver"/>
<extensionPoint name="unscrambleSupport" interface="com.intellij.unscramble.UnscrambleSupport"/>
<extensionPoint name="javaMainMethodProvider" interface="com.intellij.codeInsight.runner.JavaMainMethodProvider"/>
@@ -172,6 +172,12 @@
<projectService serviceInterface="com.intellij.codeInsight.InferredAnnotationsManager"
serviceImplementation="com.intellij.codeInsight.InferredAnnotationsManagerImpl"/>
<projectService serviceInterface="com.intellij.openapi.build.BuildSystemManager"
serviceImplementation="com.intellij.openapi.build.BuildSystemManagerImpl"/>
<projectService serviceInterface="com.intellij.execution.runners.BuildSystemExecutionEnvironmentProvider"
serviceImplementation="com.intellij.openapi.build.BuildSystemExecutionEnvironmentProviderImpl"/>
<projectService serviceInterface="com.intellij.openapi.compiler.CompilerManager"
serviceImplementation="com.intellij.compiler.CompilerManagerImpl"/>
<projectService serviceInterface="com.intellij.compiler.options.ValidationConfiguration"