external system aware run/make rework

This commit is contained in:
Vladislav.Soroka
2016-09-21 12:30:57 +03:00
committed by Vladislav.Soroka
parent 8ff83cab8b
commit 0104f1489c
42 changed files with 1180 additions and 925 deletions
@@ -13,27 +13,36 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity.impl;
import com.intellij.execution.configurations.RunConfiguration;
import org.jetbrains.annotations.Nullable;
import com.intellij.activity.Activity;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
* @since 7/13/2016
*/
public interface BuildScope {
Collection<? extends BuildTarget> getTargets();
public abstract class AbstractActivity implements Activity {
@NotNull
private Collection<Activity> myDependencies;
void setSessionId(@Nullable Object sessionId);
public AbstractActivity() {
this(Collections.emptyList());
}
@Nullable
Object getSessionId();
public AbstractActivity(@NotNull Collection<Activity> dependencies) {
myDependencies = dependencies;
}
void setRunConfiguration(@Nullable RunConfiguration configuration);
@NotNull
public Collection<Activity> getDependsOn() {
return myDependencies;
}
@Nullable
RunConfiguration getRunConfiguration();
public void setDependsOn(@NotNull Collection<Activity> dependencies) {
myDependencies = dependencies;
}
}
@@ -0,0 +1,45 @@
/*
* 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.activity.impl;
import com.intellij.activity.Activity;
import com.intellij.activity.BuildActivity;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/13/2016
*/
public abstract class AbstractBuildActivity extends AbstractActivity implements BuildActivity {
private final boolean myIsIncrementalBuild;
public AbstractBuildActivity(boolean isIncrementalBuild) {
this(isIncrementalBuild, Collections.emptyList());
}
public AbstractBuildActivity(boolean isIncrementalBuild, @NotNull List<Activity> dependencies) {
super(dependencies);
myIsIncrementalBuild = isIncrementalBuild;
}
@Override
public boolean isIncrementalBuild() {
return myIsIncrementalBuild;
}
}
@@ -0,0 +1,32 @@
/*
* 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.activity.impl;
import com.intellij.activity.Activity;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 7/14/2016
*/
public class ActivityList extends ArrayList<Activity> implements Activity {
public ActivityList(@NotNull Collection<? extends Activity> c) {
super(c);
}
}
@@ -0,0 +1,184 @@
/*
* 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.activity.impl;
import com.intellij.activity.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
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 ActivityManagerImpl extends ActivityManager {
private final ActivityRunner myDefaultActivityRunner = new InternalActivityRunner();
public ActivityManagerImpl(@NotNull Project project) {
super(project);
}
@Override
public void buildDirty(@NotNull Module[] modules, @Nullable ActivityStatusNotification callback) {
run(createModulesBuildActivity(true, modules), callback);
}
@Override
public void rebuild(@NotNull Module[] modules, @Nullable ActivityStatusNotification callback) {
run(createModulesBuildActivity(false, modules), callback);
}
@Override
public void compile(@NotNull VirtualFile[] files, @Nullable ActivityStatusNotification callback) {
List<ModuleFilesBuildActivity> buildActivities = Arrays.stream(files)
.collect(Collectors.groupingBy(file -> ProjectFileIndex.SERVICE.getInstance(myProject).getModuleForFile(file, false)))
.entrySet().stream()
.map(entry -> new ModuleFilesBuildActivityImpl(entry.getKey(), false, entry.getValue()))
.collect(Collectors.toList());
run(new ActivityList(buildActivities), callback);
}
@Override
public void build(@NotNull Artifact[] artifacts, @Nullable ActivityStatusNotification callback) {
doBuild(artifacts, callback, true);
}
@Override
public void rebuild(@NotNull Artifact[] artifacts, @Nullable ActivityStatusNotification callback) {
doBuild(artifacts, callback, false);
}
@Override
public void buildProjectDirty(@Nullable ActivityStatusNotification callback) {
run(createProjectBuildActivity(true, myProject), callback);
}
@Override
public void rebuildProject(@Nullable ActivityStatusNotification callback) {
run(createProjectBuildActivity(false, myProject), callback);
}
@Override
public Activity createProjectBuildActivity(boolean isIncrementalBuild, Project project) {
return createModulesBuildActivity(isIncrementalBuild, ModuleManager.getInstance(project).getModules());
}
@Override
public Activity createModulesBuildActivity(boolean isIncrementalBuild, Module... modules) {
return modules.length == 1
? new ModuleBuildActivityImpl(modules[0], isIncrementalBuild)
: new ActivityList(map(list(modules), module -> new ModuleBuildActivityImpl(module, isIncrementalBuild)));
}
@Override
public Activity createArtifactsBuildActivity(boolean isIncrementalBuild, Artifact... artifacts) {
return artifacts.length == 1
? new ArtifactBuildActivityImpl(artifacts[0], isIncrementalBuild)
: new ActivityList(map(list(artifacts), artifact -> new ArtifactBuildActivityImpl(artifact, isIncrementalBuild)));
}
@Override
public void run(@NotNull Activity activity, @Nullable ActivityStatusNotification callback) {
run(new ActivityContext(), activity, callback);
}
@Override
public void run(@NotNull ActivityContext context, @NotNull Activity activity, @Nullable ActivityStatusNotification callback) {
List<Pair<ActivityRunner, Collection<? extends Activity>>> toRun = new SmartList<>();
Consumer<Collection<? extends Activity>> activityClassifier = activities -> {
Map<ActivityRunner, ? extends List<? extends Activity>> toBuild =
activities.stream().collect(Collectors.groupingBy(_activity -> {
for (ActivityRunner runner : getActivityRunners()) {
if (runner.canRun(_activity)) return runner;
}
return myDefaultActivityRunner;
}));
for (Map.Entry<ActivityRunner, ? extends List<? extends Activity>> entry : toBuild.entrySet()) {
toRun.add(Pair.create(entry.getKey(), entry.getValue()));
}
};
visitActivities(activity instanceof ActivityList ? (ActivityList)activity : Collections.singleton(activity), activityClassifier);
AtomicInteger inProgressCounter = new AtomicInteger(toRun.size());
AtomicInteger errorsCounter = new AtomicInteger();
AtomicInteger warningsCounter = new AtomicInteger();
AtomicBoolean abortedFlag = new AtomicBoolean(false);
ActivityChunkStatusNotification chunkStatusNotification = callback == null ? null : new ActivityChunkStatusNotification() {
@Override
public void finished(boolean aborted, int errors, int warnings) {
int inProgress = inProgressCounter.decrementAndGet();
int allErrors = errorsCounter.addAndGet(errors);
int allWarnings = warningsCounter.addAndGet(warnings);
if (aborted) {
abortedFlag.set(true);
}
callback.chunkFinished(aborted, errors, warnings, inProgress);
if (inProgress == 0) {
callback.finished(abortedFlag.get(), allErrors, allWarnings);
}
}
};
toRun.forEach(pair -> pair.first.run(myProject, context, chunkStatusNotification, pair.second));
}
private static void visitActivities(@NotNull Collection<? extends Activity> activities,
@NotNull Consumer<Collection<? extends Activity>> consumer) {
for (Activity child : activities) {
Collection<? extends Activity> _activities;
if (child instanceof AbstractActivity) {
_activities = ((AbstractActivity)child).getDependsOn();
}
else if (child instanceof ActivityList) {
_activities = (ActivityList)child;
}
else {
_activities = Collections.singleton(child);
}
visitActivities(_activities, consumer);
}
consumer.consume(activities);
}
@NotNull
private static ActivityRunner[] getActivityRunners() {
return ActivityRunner.EP_NAME.getExtensions();
}
private void doBuild(@NotNull Artifact[] artifacts, @Nullable ActivityStatusNotification callback, boolean isIncrementalBuild) {
run(createArtifactsBuildActivity(isIncrementalBuild, artifacts), callback);
}
}
@@ -13,21 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity.impl;
import com.intellij.activity.ArtifactBuildActivity;
import com.intellij.packaging.artifacts.Artifact;
/**
* @author Vladislav.Soroka
* @since 5/14/2016
*/
public class ArtifactBuildTarget implements BuildTarget {
public class ArtifactBuildActivityImpl extends AbstractBuildActivity implements ArtifactBuildActivity {
private final Artifact myArtifact;
public ArtifactBuildTarget(Artifact artifact) {
public ArtifactBuildActivityImpl(Artifact artifact, boolean isIncrementalBuild) {
super(isIncrementalBuild);
myArtifact = artifact;
}
@Override
public Artifact getArtifact() {
return myArtifact;
}
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity.impl;
import com.intellij.activity.ActivityRunner;
import com.intellij.activity.RunActivity;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
@@ -22,33 +24,33 @@ 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.execution.runners.ExecutionEnvironmentProvider;
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
* @since 5/11/2016
*/
public abstract class BuildSystemDriver {
public class ExecutionEnvironmentProviderImpl implements ExecutionEnvironmentProvider {
public static final ExtensionPointName<BuildSystemDriver> EP_NAME = ExtensionPointName.create("com.intellij.buildSystemDriver");
@Nullable
@Override
public ExecutionEnvironment createActivityExecutionEnvironment(@NotNull Project project,
@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
public abstract void build(@NotNull BuildContext buildContext, @Nullable BuildChunkStatusNotification 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);
RunActivity runActivity = new RunActivityImpl(runProfile, executor, target, runnerSettings, configurationSettings, settings);
for (ActivityRunner activityRunner : ActivityRunner.EP_NAME.getExtensions()) {
if (activityRunner.canRun(runActivity)) {
return activityRunner.createActivityExecutionEnvironment(project, runActivity);
}
}
return null;
}
}
@@ -0,0 +1,180 @@
/*
* 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.activity.impl;
import com.intellij.activity.*;
import com.intellij.execution.configurations.RunConfiguration;
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.SmartList;
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 InternalActivityRunner extends ActivityRunner {
@Override
public void run(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable ActivityChunkStatusNotification callback,
@NotNull Collection<? extends Activity> activities) {
CompileStatusNotification compileNotification =
callback == null ? null : (aborted, errors, warnings, compileContext) -> callback.finished(aborted, errors, warnings);
Map<Class<? extends Activity>, List<Activity>> activityMap = groupBy(activities);
runModulesBuildActivities(project, context, compileNotification, activityMap);
runFilesBuildActivities(project, compileNotification, activityMap);
runArtifactsBuildActivities(project, context, compileNotification, activityMap);
}
@Override
public boolean canRun(@NotNull Activity activity) {
return true;
}
@Override
public ExecutionEnvironment createActivityExecutionEnvironment(@NotNull Project project, @NotNull RunActivity activity) {
return null;
}
public static Map<Class<? extends Activity>, List<Activity>> groupBy(@NotNull Collection<? extends Activity> activities) {
return activities.stream().collect(Collectors.groupingBy(o -> {
if (o instanceof ModuleFilesBuildActivity) return ModuleFilesBuildActivity.class;
if (o instanceof ModuleBuildActivity) return ModuleBuildActivity.class;
if (o instanceof ArtifactBuildActivity) return ArtifactBuildActivity.class;
return o.getClass();
}));
}
private static void runModulesBuildActivities(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends Activity>, List<Activity>> activitiesMap) {
Collection<? extends Activity> buildActivities = activitiesMap.get(ModuleBuildActivity.class);
if (!ContainerUtil.isEmpty(buildActivities)) {
List<Module> toMake = new SmartList<>();
List<Module> toCompile = new SmartList<>();
for (Activity buildActivity : buildActivities) {
ModuleBuildActivity moduleBuildActivity = (ModuleBuildActivity)buildActivity;
if (moduleBuildActivity.isIncrementalBuild()) {
toMake.add(moduleBuildActivity.getModule());
}
else {
toCompile.add(moduleBuildActivity.getModule());
}
}
CompilerManager compilerManager = CompilerManager.getInstance(project);
if (!toMake.isEmpty()) {
CompileScope scope = createScope(project, compilerManager, context, toMake);
// TODO handle multiple notifications
compilerManager.make(scope, compileNotification);
}
if (!toCompile.isEmpty()) {
CompileScope scope = createScope(project, compilerManager, context, toCompile);
// TODO handle multiple notifications
compilerManager.compile(scope, compileNotification);
}
}
}
private static CompileScope createScope(Project project,
CompilerManager compilerManager,
ActivityContext context,
Collection<Module> modules) {
CompileScope scope = compilerManager.createModuleGroupCompileScope(project, modules.toArray(new Module[modules.size()]), true);
RunConfiguration configuration = context.getRunConfiguration();
if (configuration != null) {
scope.putUserData(CompilerManager.RUN_CONFIGURATION_KEY, configuration);
scope.putUserData(CompilerManager.RUN_CONFIGURATION_TYPE_ID_KEY, configuration.getType().getId());
}
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(scope, context.getSessionId());
return scope;
}
private static void runFilesBuildActivities(@NotNull Project project,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends Activity>, List<Activity>> activitiesMap) {
Collection<? extends Activity> filesTargets = activitiesMap.get(ModuleFilesBuildActivity.class);
if (!ContainerUtil.isEmpty(filesTargets)) {
VirtualFile[] files = filesTargets.stream()
.flatMap(target -> Stream.of(ModuleFilesBuildActivity.class.cast(target).getFiles()))
.toArray(VirtualFile[]::new);
CompilerManager.getInstance(project).compile(files, compileNotification);
}
}
private static void runArtifactsBuildActivities(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable CompileStatusNotification compileNotification,
@NotNull Map<Class<? extends Activity>, List<Activity>> activitiesMap) {
Collection<? extends Activity> buildActivities = activitiesMap.get(ArtifactBuildActivity.class);
if (!ContainerUtil.isEmpty(buildActivities)) {
List<Artifact> toMake = new SmartList<>();
List<Artifact> toCompile = new SmartList<>();
for (Activity buildActivity : buildActivities) {
ArtifactBuildActivity artifactBuildActivity = (ArtifactBuildActivity)buildActivity;
if (artifactBuildActivity.isIncrementalBuild()) {
toMake.add(artifactBuildActivity.getArtifact());
}
else {
toCompile.add(artifactBuildActivity.getArtifact());
}
}
buildArtifacts(project, toMake, context.getSessionId(), compileNotification, false);
buildArtifacts(project, toCompile, context.getSessionId(), compileNotification, true);
}
}
private static void buildArtifacts(@NotNull Project project,
@NotNull List<Artifact> artifacts,
@Nullable Object sessionId,
@Nullable CompileStatusNotification compileNotification,
boolean forceArtifactBuild) {
if (!artifacts.isEmpty()) {
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, forceArtifactBuild);
ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(scope, sessionId);
//in external build we can set 'rebuild' flag per target type
CompilerManager.getInstance(project).make(scope, compileNotification);
}
}
}
@@ -13,25 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity.impl;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.activity.ModuleBuildActivity;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 7/6/2016
* @since 5/11/2016
*/
public class ProjectBuildScope extends BuildScopeImpl {
private final Project myProject;
public class ModuleBuildActivityImpl extends AbstractBuildActivity implements ModuleBuildActivity {
@NotNull
private final Module myModule;
public ProjectBuildScope(final Project project) {
super(ContainerUtil.map(ModuleManager.getInstance(project).getModules(), ModuleBuildTarget::new));
myProject = project;
public ModuleBuildActivityImpl(@NotNull Module module, boolean isIncrementalBuild) {
super(isIncrementalBuild);
myModule = module;
}
public Project getProject() {
return myProject;
@NotNull
@Override
public Module getModule() {
return myModule;
}
}
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity.impl;
import com.intellij.activity.ModuleFilesBuildActivity;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
@@ -25,18 +26,19 @@ import java.util.Collection;
* @author Vladislav.Soroka
* @since 5/14/2016
*/
public class ModuleFilesBuildTarget extends ModuleBuildTarget {
public class ModuleFilesBuildActivityImpl extends ModuleBuildActivityImpl implements ModuleFilesBuildActivity {
private final VirtualFile[] myFiles;
public ModuleFilesBuildTarget(Module module, VirtualFile[] files) {
super(module);
public ModuleFilesBuildActivityImpl(Module module, boolean isIncrementalBuild, VirtualFile... files) {
super(module, isIncrementalBuild);
myFiles = files;
}
public ModuleFilesBuildTarget(Module module, Collection<VirtualFile> files) {
this(module, ArrayUtil.toObjectArray(files, VirtualFile.class));
public ModuleFilesBuildActivityImpl(Module module, boolean isIncrementalBuild, Collection<VirtualFile> files) {
this(module, isIncrementalBuild, ArrayUtil.toObjectArray(files, VirtualFile.class));
}
@Override
public VirtualFile[] getFiles() {
return myFiles;
}
@@ -0,0 +1,93 @@
/*
* 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.activity.impl;
import com.intellij.activity.RunActivity;
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 7/13/2016
*/
public class RunActivityImpl extends AbstractActivity implements RunActivity {
@NotNull private final RunProfile myRunProfile;
@Nullable private Executor myExecutor;
@Nullable private ExecutionTarget myTarget;
@Nullable private RunnerSettings myRunnerSettings;
@Nullable private ConfigurationPerRunnerSettings myConfigurationSettings;
@Nullable private RunnerAndConfigurationSettings mySettings;
public RunActivityImpl(@NotNull RunProfile runProfile) {
myRunProfile = runProfile;
}
public RunActivityImpl(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings) {
myRunProfile = runProfile;
myExecutor = executor;
myTarget = target;
myRunnerSettings = runnerSettings;
myConfigurationSettings = configurationSettings;
mySettings = settings;
}
@NotNull
@Override
public RunProfile getRunProfile() {
return myRunProfile;
}
@Nullable
@Override
public Executor getExecutor() {
return myExecutor;
}
@Nullable
@Override
public ExecutionTarget getExecutionTarget() {
return myTarget;
}
@Nullable
@Override
public RunnerSettings getRunnerSettings() {
return myRunnerSettings;
}
@Nullable
@Override
public ConfigurationPerRunnerSettings getConfigurationSettings() {
return myConfigurationSettings;
}
@Nullable
@Override
public RunnerAndConfigurationSettings getSettings() {
return mySettings;
}
}
@@ -20,7 +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.build.BuildSystemManager;
import com.intellij.activity.ActivityManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
@@ -121,10 +121,10 @@ public class BuildArtifactAction extends DumbAwareAction {
private static void doBuild(@NotNull Project project, final @NotNull List<ArtifactPopupItem> items, boolean rebuild) {
final Artifact[] artifacts = getArtifacts(items, project);
if (rebuild) {
BuildSystemManager.getInstance(project).rebuild(artifacts);
ActivityManager.getInstance(project).rebuild(artifacts);
}
else {
BuildSystemManager.getInstance(project).build(artifacts);
ActivityManager.getInstance(project).build(artifacts);
}
}
@@ -18,7 +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.activity.ActivityManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.fileTypes.FileType;
@@ -38,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) {
BuildSystemManager.getInstance(project).rebuild(module);
ActivityManager.getInstance(project).rebuild(module);
}
else {
VirtualFile[] files = getCompilableFiles(project, dataContext.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY));
if (files.length > 0) {
BuildSystemManager.getInstance(project).compile(files);
ActivityManager.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.build.BuildSystemManager;
import com.intellij.activity.ActivityManager;
import com.intellij.openapi.project.Project;
public class CompileDirtyAction extends CompileActionBase {
protected void doAction(DataContext dataContext, Project project) {
BuildSystemManager.getInstance(project).buildProjectDirty();
ActivityManager.getInstance(project).buildProjectDirty();
}
public void update(AnActionEvent e){
@@ -19,14 +19,14 @@ 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.build.BuildStatusNotificationAdapter;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.activity.ActivityStatusNotificationAdapter;
import com.intellij.activity.ActivityManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.project.Project;
public class CompileProjectAction extends CompileActionBase {
protected void doAction(DataContext dataContext, final Project project) {
BuildSystemManager.getInstance(project).rebuildProject(new BuildStatusNotificationAdapter() {
ActivityManager.getInstance(project).rebuildProject(new ActivityStatusNotificationAdapter() {
@Override
public void finished(boolean aborted, int errors, int warnings) {
if (aborted || project.isDisposed()) {
@@ -16,7 +16,7 @@
package com.intellij.compiler.actions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.activity.ActivityManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -36,7 +36,7 @@ public class MakeModuleAction extends CompileActionBase {
modules = new Module[]{module};
}
try {
BuildSystemManager.getInstance(project).buildDirty(modules);
ActivityManager.getInstance(project).buildDirty(modules);
}
catch (Exception e) {
LOG.error(e);
@@ -1,53 +0,0 @@
/*
* 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;
}
}
@@ -1,186 +0,0 @@
/*
* 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.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
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) {
doBuild(createModulesBuildScope(modules), true, callback);
}
@Override
public void rebuild(@NotNull Module[] modules, @Nullable BuildStatusNotification callback) {
doBuild(createModulesBuildScope(modules), 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(createProjectBuildScope(myProject), true, callback);
}
@Override
public void rebuildProject(@Nullable BuildStatusNotification callback) {
doBuild(createProjectBuildScope(myProject), false, callback);
}
@Override
public BuildScope createProjectBuildScope(Project project) {
return new ProjectBuildScope(project);
}
@Override
public BuildScope createModulesBuildScope(Module... modules) {
return new BuildScopeImpl(map(list(modules), ModuleBuildTarget::new));
}
@Override
public BuildScope createArtifactsBuildScope(Artifact... artifacts) {
return new BuildScopeImpl(map(list(artifacts), ArtifactBuildTarget::new));
}
@NotNull
private static BuildSystemDriver[] getBuildDrivers() {
return BuildSystemDriver.EP_NAME.getExtensions();
}
private void doBuild(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback, boolean isIncrementalBuild) {
doBuild(createArtifactsBuildScope(artifacts), 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;
}));
AtomicInteger inProgressCounter = new AtomicInteger(toBuild.size());
AtomicInteger errorsCounter = new AtomicInteger();
AtomicInteger warningsCounter = new AtomicInteger();
AtomicBoolean abortedFlag = new AtomicBoolean(false);
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(), scope.getRunConfiguration());
BuildChunkStatusNotification chunkStatusNotification = callback == null ? null : new BuildChunkStatusNotification() {
@Override
public void finished(boolean aborted, int errors, int warnings, BuildContext buildContext) {
int inProgress = inProgressCounter.decrementAndGet();
int allErrors = errorsCounter.addAndGet(errors);
int allWarnings = warningsCounter.addAndGet(warnings);
if(aborted){
abortedFlag.set(true);
}
callback.chunkFinished(aborted, errors, warnings, inProgress, buildContext);
if (inProgress == 0) {
callback.finished(abortedFlag.get(), allErrors, allWarnings);
}
}
};
driver.build(new BuildContextImpl(myProject, buildScope, isIncrementalBuild), chunkStatusNotification);
}
}
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;
}
}
}
@@ -1,154 +0,0 @@
/*
* 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.RunConfiguration;
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 BuildChunkStatusNotification 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();
CompilerManager compilerManager = CompilerManager.getInstance(project);
if (buildContext.isIncrementalBuild()) {
CompileScope scope = compilerManager.createProjectCompileScope(project);
RunConfiguration configuration = buildContext.getScope().getRunConfiguration();
if (configuration != null) {
scope.putUserData(CompilerManager.RUN_CONFIGURATION_KEY, configuration);
scope.putUserData(CompilerManager.RUN_CONFIGURATION_TYPE_ID_KEY, configuration.getType().getId());
}
compilerManager.make(scope, callback);
}
else {
compilerManager.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);
}
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.packaging.impl.run;
import com.intellij.activity.*;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.RunManagerEx;
@@ -29,7 +30,6 @@ 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.build.*;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogBuilder;
@@ -176,11 +176,9 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B
}
}.execute();
final BuildStatusNotification callback = new BuildStatusNotificationAdapter() {
final ActivityStatusNotification callback = new ActivityStatusNotificationAdapter() {
@Override
public void finished(boolean aborted,
int errors,
int warnings) {
public void finished(boolean aborted, int errors, int warnings) {
result.set(!aborted && errors == 0);
finished.up();
}
@@ -190,10 +188,12 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B
if (myProject.isDisposed()) {
return;
}
List<ArtifactBuildTarget> artifactBuildTargets = ContainerUtil.map(artifacts, ArtifactBuildTarget::new);
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
ActivityManager activityManager = ActivityManager.getInstance(myProject);
Activity artifactsBuildActivity =
activityManager.createArtifactsBuildActivity(true, artifacts.toArray(new Artifact[artifacts.size()]));
finished.down();
BuildSystemManager.getInstance(myProject).buildDirty(new BuildScopeImpl(artifactBuildTargets, sessionId), callback);
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
activityManager.run(new ActivityContext(sessionId), artifactsBuildActivity, callback);
}, ModalityState.NON_MODAL);
finished.waitFor();
@@ -0,0 +1,25 @@
/*
* 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.activity;
/**
* An {@link Activity} represents a single atomic piece of work for IDE workflow, such as 'Make Project' or run configurations.
*
* @author Vladislav.Soroka
* @since 7/13/2016
*/
public interface Activity {
}
@@ -13,20 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public interface BuildChunkStatusNotification {
public interface ActivityChunkStatusNotification {
/**
*
* @param aborted true if the build chunk has been cancelled.
* @param errors error count
* @param warnings warning count
* @param buildContext context for the build chunk
*/
void finished(boolean aborted, int errors, int warnings, final BuildContext buildContext);
void finished(boolean aborted, int errors, int warnings);
}
@@ -13,64 +13,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
import com.intellij.execution.configurations.RunConfiguration;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
* @since 7/15/2016
*/
public class BuildScopeImpl implements BuildScope {
private final Collection<? extends BuildTarget> myTargets;
public class ActivityContext {
@Nullable
private Object mySessionId;
@Nullable
private RunConfiguration myConfiguration;
private RunConfiguration myRunConfiguration;
public BuildScopeImpl(Collection<? extends BuildTarget> targets) {
this(targets, null, null);
public ActivityContext() {
}
public BuildScopeImpl(Collection<? extends BuildTarget> targets, @Nullable Object sessionId) {
this(targets, sessionId, null);
}
public BuildScopeImpl(Collection<? extends BuildTarget> targets,
@Nullable Object sessionId,
@Nullable RunConfiguration configuration) {
myTargets = targets;
public ActivityContext(@Nullable Object sessionId) {
mySessionId = sessionId;
myConfiguration = configuration;
}
@Override
public Collection<? extends BuildTarget> getTargets() {
return myTargets;
public ActivityContext(@Nullable Object sessionId, @Nullable RunConfiguration runConfiguration) {
mySessionId = sessionId;
myRunConfiguration = runConfiguration;
}
@Nullable
public Object getSessionId() {
return mySessionId;
}
@Override
public void setSessionId(@Nullable Object sessionId) {
mySessionId = sessionId;
}
@Nullable
@Override
public Object getSessionId() {
return mySessionId;
}
@Override
public void setRunConfiguration(@Nullable RunConfiguration configuration) {
myConfiguration = configuration;
}
@Nullable
@Override
public RunConfiguration getRunConfiguration() {
return myConfiguration;
return myRunConfiguration;
}
public void setRunConfiguration(@Nullable RunConfiguration runConfiguration) {
myRunConfiguration = runConfiguration;
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
@@ -24,72 +24,73 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Provides services to build project, modules, files or artifacts.
* Provides services to build project, modules, files or artifacts and execute Run Configuration.
* <p>
*
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public abstract class BuildSystemManager {
public abstract class ActivityManager {
protected final @NotNull Project myProject;
public BuildSystemManager(@NotNull Project project) {
public ActivityManager(@NotNull Project project) {
myProject = project;
}
public static BuildSystemManager getInstance(Project project) {
return ServiceManager.getService(project, BuildSystemManager.class);
public static ActivityManager getInstance(Project project) {
return ServiceManager.getService(project, ActivityManager.class);
}
public abstract void buildProjectDirty(@Nullable BuildStatusNotification callback);
public abstract void run(@NotNull Activity activity, @Nullable ActivityStatusNotification callback);
public abstract void run(@NotNull ActivityContext context, @NotNull Activity activity, @Nullable ActivityStatusNotification callback);
public abstract void buildProjectDirty(@Nullable ActivityStatusNotification callback);
public void buildProjectDirty() {
buildProjectDirty(null);
}
public abstract void rebuildProject(@Nullable BuildStatusNotification callback);
public abstract void rebuildProject(@Nullable ActivityStatusNotification callback);
public void rebuildProject() {
rebuildProject(null);
}
public abstract void buildDirty(@NotNull Module[] modules, @Nullable BuildStatusNotification callback);
public abstract void buildDirty(@NotNull Module[] modules, @Nullable ActivityStatusNotification callback);
public void buildDirty(@NotNull Module... modules) {
buildDirty(modules, null);
}
public abstract void rebuild(@NotNull Module[] modules, @Nullable BuildStatusNotification callback);
public abstract void rebuild(@NotNull Module[] modules, @Nullable ActivityStatusNotification callback);
public void rebuild(@NotNull Module... modules) {
rebuild(modules, null);
}
public abstract void compile(@NotNull VirtualFile[] files, @Nullable BuildStatusNotification callback);
public abstract void compile(@NotNull VirtualFile[] files, @Nullable ActivityStatusNotification callback);
public void compile(@NotNull VirtualFile... files) {
compile(files, null);
}
public abstract void build(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback);
public abstract void build(@NotNull Artifact[] artifacts, @Nullable ActivityStatusNotification callback);
public void build(@NotNull Artifact[] artifacts) {
build(artifacts, null);
}
public abstract void rebuild(@NotNull Artifact[] artifacts, @Nullable BuildStatusNotification callback);
public abstract void rebuild(@NotNull Artifact[] artifacts, @Nullable ActivityStatusNotification callback);
public void rebuild(@NotNull Artifact... artifacts) {
rebuild(artifacts, null);
}
public abstract void buildDirty(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback);
public abstract Activity createProjectBuildActivity(boolean isIncrementalBuild, Project project);
public abstract void rebuild(@NotNull BuildScope scope, @Nullable BuildStatusNotification callback);
public abstract Activity createModulesBuildActivity(boolean isIncrementalBuild, Module... modules);
public abstract BuildScope createProjectBuildScope(Project project);
public abstract Activity createArtifactsBuildActivity(boolean isIncrementalBuild, Artifact... artifacts);
public abstract BuildScope createModulesBuildScope(Module... modules);
public abstract BuildScope createArtifactsBuildScope(Artifact... artifacts);
}
@@ -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.activity;
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;
import java.util.Arrays;
import java.util.Collection;
/**
* TODO
* get compiled files status
*
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public abstract class ActivityRunner {
public static final ExtensionPointName<ActivityRunner> EP_NAME = ExtensionPointName.create("com.intellij.activityRunner");
public abstract void run(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable ActivityChunkStatusNotification callback,
@NotNull Collection<? extends Activity> activities);
public void run(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable ActivityChunkStatusNotification callback,
@NotNull Activity... activities) {
run(project, context, callback, Arrays.asList(activities));
}
public abstract boolean canRun(@NotNull Activity activity);
public abstract ExecutionEnvironment createActivityExecutionEnvironment(@NotNull Project project, @NotNull RunActivity activity);
}
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
*/
public interface BuildStatusNotification {
public interface ActivityStatusNotification {
/**
* @param aborted true if the at least one build chunk has been cancelled.
* @param aborted true if the at least one activity chunk has been cancelled.
* @param errors error count
* @param warnings warning count
*/
@@ -30,11 +30,10 @@ public interface BuildStatusNotification {
/**
*
* @param aborted true if the build chunk has been cancelled.
* @param aborted true if the activity chunk has been cancelled.
* @param errors error count
* @param warnings warning count
* @param inProgress not finished build chunks count
* @param buildContext context for the build chunk
* @param inProgress not finished activity chunks count
*/
void chunkFinished(boolean aborted, int errors, int warnings, int inProgress, final BuildContext buildContext);
void chunkFinished(boolean aborted, int errors, int warnings, int inProgress);
}
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
/**
* @author Vladislav.Soroka
* @since 7/12/2016
*/
public class BuildStatusNotificationAdapter implements BuildStatusNotification {
public class ActivityStatusNotificationAdapter implements ActivityStatusNotification {
@Override
public void finished(boolean aborted, int errors, int warnings) {
}
@Override
public void chunkFinished(boolean aborted, int errors, int warnings, int inProgress, BuildContext buildContext) {
public void chunkFinished(boolean aborted, int errors, int warnings, int inProgress) {
}
}
@@ -13,18 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
import com.intellij.openapi.project.Project;
import com.intellij.packaging.artifacts.Artifact;
/**
* @author Vladislav.Soroka
* @since 4/29/2016
* @since 7/18/2016
*/
public interface BuildContext {
Project getProject();
BuildScope getScope();
boolean isIncrementalBuild();
public interface ArtifactBuildActivity extends BuildActivity {
Artifact getArtifact();
}
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public interface BuildTarget {
public interface BuildActivity extends Activity {
boolean isIncrementalBuild();
}
@@ -13,22 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.build;
package com.intellij.activity;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
* @since 7/18/2016
*/
public class ModuleBuildTarget implements BuildTarget {
private final Module myModule;
public ModuleBuildTarget(Module module) {
myModule = module;
}
public Module getModule() {
return myModule;
}
public interface ModuleBuildActivity extends BuildActivity {
@NotNull
Module getModule();
}
@@ -0,0 +1,26 @@
/*
* 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.activity;
import com.intellij.openapi.vfs.VirtualFile;
/**
* @author Vladislav.Soroka
* @since 7/18/2016
*/
public interface ModuleFilesBuildActivity extends ModuleBuildActivity {
VirtualFile[] getFiles();
}
@@ -0,0 +1,50 @@
/*
* 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.activity;
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 5/11/2016
*/
public interface RunActivity extends Activity {
@NotNull
RunProfile getRunProfile();
@Nullable
Executor getExecutor();
@Nullable
ExecutionTarget getExecutionTarget();
@Nullable
RunnerSettings getRunnerSettings();
@Nullable
ConfigurationPerRunnerSettings getConfigurationSettings();
@Nullable
RunnerAndConfigurationSettings getSettings();
}
@@ -15,6 +15,7 @@
*/
package com.intellij.compiler.options;
import com.intellij.activity.*;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.ExecutionBundle;
@@ -27,10 +28,6 @@ import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.build.BuildScope;
import com.intellij.openapi.build.BuildStatusNotification;
import com.intellij.openapi.build.BuildStatusNotificationAdapter;
import com.intellij.openapi.build.BuildSystemManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompilerManager;
@@ -141,7 +138,7 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
final Semaphore done = new Semaphore();
done.down();
final BuildStatusNotification callback = new BuildStatusNotificationAdapter() {
final ActivityStatusNotification callback = new ActivityStatusNotificationAdapter() {
public void finished(boolean aborted, int errors, int warnings) {
if ((errors == 0 || ignoreErrors) && !aborted) {
result.set(Boolean.TRUE);
@@ -151,11 +148,12 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
};
TransactionGuard.submitTransaction(myProject, () -> {
BuildScope scope;
final BuildSystemManager buildSystemManager = BuildSystemManager.getInstance(myProject);
Activity activity;
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
final ActivityManager activityManager = ActivityManager.getInstance(myProject);
if (forceMakeProject) {
// user explicitly requested whole-project make
scope = buildSystemManager.createProjectBuildScope(myProject);
activity = activityManager.createProjectBuildActivity(true, myProject);
}
else {
final Module[] modules = runConfiguration.getModules();
@@ -166,18 +164,15 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
runConfiguration.getClass().getName());
}
}
scope = buildSystemManager.createModulesBuildScope(modules);
activity = activityManager.createModulesBuildActivity(true, modules);
}
else {
scope = buildSystemManager.createProjectBuildScope(myProject);
activity = activityManager.createProjectBuildActivity(true, myProject);
}
}
if (!myProject.isDisposed()) {
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
scope.setSessionId(sessionId);
scope.setRunConfiguration(configuration);
buildSystemManager.buildDirty(scope, callback);
activityManager.run(new ActivityContext(sessionId, configuration), activity, callback);
}
else {
done.up();
@@ -166,8 +166,9 @@ public final class ExecutionEnvironmentBuilder {
@NotNull
public ExecutionEnvironment build() {
ExecutionEnvironment environment = ServiceManager.getService(myProject, BuildSystemExecutionEnvironmentProvider.class).createExecutionEnvironment(
myRunProfile, myExecutor, myTarget, myProject, myRunnerSettings, myConfigurationSettings, myRunnerAndConfigurationSettings);
ExecutionEnvironment environment =
ServiceManager.getService(myProject, ExecutionEnvironmentProvider.class).createActivityExecutionEnvironment(
myProject, myRunProfile, myExecutor, myTarget, myRunnerSettings, myConfigurationSettings, myRunnerAndConfigurationSettings);
if (environment == null && myRunner == null) {
if (myRunnerId == null) {
@@ -29,14 +29,14 @@ import org.jetbrains.annotations.Nullable;
* @author Vladislav.Soroka
* @since 6/2/2016
*/
public interface BuildSystemExecutionEnvironmentProvider {
public interface ExecutionEnvironmentProvider {
@Nullable
ExecutionEnvironment createExecutionEnvironment(@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@NotNull Project project,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings);
ExecutionEnvironment createActivityExecutionEnvironment(@NotNull Project project,
@NotNull RunProfile runProfile,
@NotNull Executor executor,
@NotNull ExecutionTarget target,
@Nullable RunnerSettings runnerSettings,
@Nullable ConfigurationPerRunnerSettings configurationSettings,
@Nullable RunnerAndConfigurationSettings settings);
}
+1 -1
View File
@@ -78,7 +78,7 @@
<extensions defaultExtensionNs="com.intellij">
<buildSystemDriver implementation="org.jetbrains.plugins.gradle.execution.build.GradleBuildSystemDriver"/>
<activityRunner implementation="org.jetbrains.plugins.gradle.execution.build.GradleActivityRunner"/>
<postStartupActivity implementation="org.jetbrains.plugins.gradle.service.project.GradleStartupActivity"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler$FactoryImpl"/>
@@ -16,14 +16,19 @@
package org.jetbrains.plugins.gradle.execution.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.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.BooleanFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.util.Map;
@@ -40,21 +45,38 @@ public class CachedModuleDataFinder {
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 (DataNode<ModuleData>)ExternalSystemApiUtil.findFirstRecursively(parentNode, node1 -> {
if ((ProjectKeys.MODULE.equals(node1.getKey()) ||
GradleSourceSetData.KEY.equals(node1.getKey())) && node1.getData() instanceof ModuleData) {
String externalProjectPath = ((ModuleData)node1.getData()).getLinkedExternalProjectPath();
//noinspection unchecked
DataNode<ModuleData> myNode = (DataNode<ModuleData>)node1;
cache.put(externalProjectPath, myNode);
return StringUtil.equals(projectPath, ((ModuleData)node.getData()).getLinkedExternalProjectPath());
}
return false;
return StringUtil.equals(projectPath, ((ModuleData)node1.getData()).getLinkedExternalProjectPath());
}
return false;
});
}
@Nullable
public DataNode<ModuleData> findModuleData(@NotNull Module module) {
final String rootProjectPath = ExternalSystemApiUtil.getExternalRootProjectPath(module);
if (rootProjectPath == null) return null;
final String projectId = ExternalSystemApiUtil.getExternalProjectId(module);
if (projectId == null) return null;
final String externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module);
if (externalProjectPath == null || StringUtil.endsWith(externalProjectPath, "buildSrc")) return null;
ExternalProjectInfo projectData =
ProjectDataManager.getInstance().getExternalProjectData(module.getProject(), GradleConstants.SYSTEM_ID, rootProjectPath);
if (projectData == null) return null;
DataNode<ProjectData> projectStructure = projectData.getExternalProjectStructure();
if (projectStructure == null) return null;
return findModuleData(projectStructure, externalProjectPath);
}
}
@@ -0,0 +1,248 @@
/*
* 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.activity.*;
import com.intellij.activity.impl.InternalActivityRunner;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.configurations.JavaRunConfigurationModule;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.externalSystem.model.DataNode;
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.service.execution.ProgressExecutionMode;
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.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.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 GradleActivityRunner extends ActivityRunner {
@Override
public void run(@NotNull Project project,
@NotNull ActivityContext context,
@Nullable ActivityChunkStatusNotification callback,
@NotNull Collection<? extends Activity> activities) {
String executionName = "Gradle build";
MultiMap<String, String> buildTasksMap = MultiMap.createLinkedSet();
MultiMap<String, String> cleanTasksMap = MultiMap.createLinkedSet();
Map<Class<? extends Activity>, List<Activity>> activityMap = InternalActivityRunner.groupBy(activities);
addModulesBuildActivityTasks(activityMap.get(ModuleBuildActivity.class), cleanTasksMap, buildTasksMap);
// TODO there should be 'gradle' way to build files instead of related modules entirely
addModulesBuildActivityTasks(activityMap.get(ModuleFilesBuildActivity.class), cleanTasksMap, buildTasksMap);
addArtifactsBuildActivityTasks(activityMap.get(ArtifactBuildActivity.class), 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 = callback == 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()) {
callback.finished(false, errors, 0);
}
}
};
String gradleVmOptions = GradleSettings.getInstance(project).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, project, GradleConstants.SYSTEM_ID,
taskCallback, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false);
}
}
@Override
public boolean canRun(@NotNull Activity activity) {
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false;
if (activity instanceof ModuleBuildActivity) {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, ((ModuleBuildActivity)activity).getModule());
}
if (activity instanceof ArtifactBuildActivity) {
ArtifactBuildActivity artifactBuildActivity = (ArtifactBuildActivity)activity;
for (GradleArtifactBuildTasksProvider buildTasksProvider : GradleArtifactBuildTasksProvider.EP_NAME.getExtensions()) {
if (buildTasksProvider.isApplicable(artifactBuildActivity)) return true;
}
}
if (activity instanceof RunActivity) {
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false;
RunProfile runProfile = ((RunActivity)activity).getRunProfile();
if (runProfile instanceof ApplicationConfiguration) {
JavaRunConfigurationModule module = ((ApplicationConfiguration)runProfile).getConfigurationModule();
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module.getModule());
}
}
return false;
}
@Override
public ExecutionEnvironment createActivityExecutionEnvironment(@NotNull Project project, @NotNull RunActivity activity) {
if (activity.getRunProfile() instanceof ApplicationConfiguration) {
return new GradleApplicationEnvironmentBuilder().build(project, activity);
}
return null;
}
private static void addModulesBuildActivityTasks(@Nullable Collection<? extends Activity> activities,
@NotNull MultiMap<String, String> cleanTasksMap,
@NotNull MultiMap<String, String> buildTasksMap) {
if (ContainerUtil.isEmpty(activities)) return;
final CachedModuleDataFinder moduleDataFinder = new CachedModuleDataFinder();
for (Activity activity : activities) {
if (!(activity instanceof ModuleBuildActivity)) continue;
ModuleBuildActivity moduleBuildActivity = (ModuleBuildActivity)activity;
Module module = moduleBuildActivity.getModule();
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;
final DataNode<ModuleData> moduleDataNode = moduleDataFinder.findModuleData(module);
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 (!moduleBuildActivity.isIncrementalBuild()) {
cleanTasks.add(gradlePath + ":clean" + StringUtil.capitalize(task));
}
buildTasks.add(gradlePath + ":" + task);
}
else if ("main".equals(sourceSetName) || "test".equals(sourceSetName)) {
if (!moduleBuildActivity.isIncrementalBuild()) {
cleanTasks.add(gradlePath + ":clean");
}
buildTasks.add(gradlePath + ":build");
}
}
else {
gradlePath = projectId.charAt(0) == ':' ? projectId : "";
if (!moduleBuildActivity.isIncrementalBuild()) {
if (tasks.contains("classes")) {
cleanTasks.add((StringUtil.equals(rootProjectPath, externalProjectPath) ? ":cleanClasses" : gradlePath + ":cleanClasses"));
}
else if(tasks.contains("clean")){
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 addArtifactsBuildActivityTasks(@Nullable Collection<? extends Activity> activities,
@NotNull MultiMap<String, String> cleanTasksMap,
@NotNull MultiMap<String, String> buildTasksMap) {
if (ContainerUtil.isEmpty(activities)) return;
for (Activity activity : activities) {
if (!(activity instanceof ArtifactBuildActivity)) continue;
ArtifactBuildActivity artifactBuildActivity = (ArtifactBuildActivity)activity;
for (GradleArtifactBuildTasksProvider buildTasksProvider : GradleArtifactBuildTasksProvider.EP_NAME.getExtensions()) {
if (buildTasksProvider.isApplicable(artifactBuildActivity)) {
buildTasksProvider.addArtifactsTargetsBuildTasks(
artifactBuildActivity,
task -> cleanTasksMap.putValue(task.getLinkedExternalProjectPath(), task.getName()),
task -> buildTasksMap.putValue(task.getLinkedExternalProjectPath(), task.getName())
);
}
}
}
}
}
@@ -15,14 +15,11 @@
*/
package org.jetbrains.plugins.gradle.execution.build;
import com.intellij.execution.ExecutionTarget;
import com.intellij.execution.Executor;
import com.intellij.activity.RunActivity;
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.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.util.JavaParametersUtil;
@@ -52,25 +49,25 @@ import java.util.Collections;
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;
public ExecutionEnvironment build(@NotNull Project project, @NotNull RunActivity activity) {
if (!(activity.getRunProfile() instanceof ApplicationConfiguration)) return null;
ApplicationConfiguration applicationConfiguration = (ApplicationConfiguration)activity.getRunProfile();
PsiClass mainClass = applicationConfiguration.getMainClass();
if(mainClass == null) return null;
Module module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(mainClass.getContainingFile().getVirtualFile());
if (module == null) return null;
String externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module);
String projectId = ExternalSystemApiUtil.getExternalProjectId(module);
if (projectId == null || !projectId.startsWith(":")) {
projectId = ":";
String gradleProjectPath = projectId;
int lastPathDelimiterIndex = gradleProjectPath == null ? -1 : gradleProjectPath.lastIndexOf(':');
if (gradleProjectPath == null || !gradleProjectPath.startsWith(":")) {
gradleProjectPath = ":";
} else {
if(!projectId.equals(":")) {
projectId = projectId.substring(0, projectId.lastIndexOf(':'));
if (!gradleProjectPath.equals(":")) {
gradleProjectPath = gradleProjectPath.substring(0, lastPathDelimiterIndex);
}
}
@@ -95,19 +92,21 @@ public class GradleApplicationEnvironmentBuilder {
final String runAppTaskName = "run " + mainClass.getName();
taskSettings.setTaskNames(Collections.singletonList(runAppTaskName));
String executorId = activity.getExecutor() == null ? DefaultRunExecutor.EXECUTOR_ID : activity.getExecutor().getId();
final Pair<ProgramRunner, ExecutionEnvironment> environmentPair =
ExternalSystemUtil.createRunner(taskSettings, executor.getId(), project, GradleConstants.SYSTEM_ID);
ExternalSystemUtil.createRunner(taskSettings, executorId, project, GradleConstants.SYSTEM_ID);
if (environmentPair != null) {
RunnerAndConfigurationSettings runnerAndConfigurationSettings = environmentPair.second.getRunnerAndConfigurationSettings();
assert runnerAndConfigurationSettings != null;
ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)runnerAndConfigurationSettings.getConfiguration();
String sourceSetName = projectId == null || lastPathDelimiterIndex == -1 ? "main" : projectId.substring(lastPathDelimiterIndex + 1);
@Language("Groovy")
String initScript = "projectsEvaluated {\n" +
" rootProject.allprojects {\n" +
" if(project.path == '" + projectId + "' && project.sourceSets) {\n" +
" if(project.path == '" + gradleProjectPath + "' && project.sourceSets) {\n" +
" project.tasks.create(name: '" + runAppTaskName + "', overwrite: true, type: JavaExec) {\n" +
" classpath = project.sourceSets.main.runtimeClasspath\n" +
" classpath = project.sourceSets.'" + sourceSetName + "'.runtimeClasspath\n" +
" main = '" + mainClass.getQualifiedName() + "'\n" +
parametersString.toString() +
vmParametersString.toString() +
@@ -15,10 +15,9 @@
*/
package org.jetbrains.plugins.gradle.execution.build;
import com.intellij.openapi.build.BuildContext;
import com.intellij.activity.ArtifactBuildActivity;
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;
@@ -30,10 +29,9 @@ public interface GradleArtifactBuildTasksProvider {
ExtensionPointName<GradleArtifactBuildTasksProvider> EP_NAME =
ExtensionPointName.create("org.jetbrains.plugins.gradle.artifactBuildTasksProvider");
boolean isApplicable(@NotNull Artifact artifact);
boolean isApplicable(@NotNull ArtifactBuildActivity artifactBuildActivity);
void addArtifactsTargetsBuildTasks(@NotNull BuildContext buildContext,
void addArtifactsTargetsBuildTasks(@NotNull ArtifactBuildActivity artifactBuildActivity,
@NotNull Consumer<ExternalTaskPojo> cleanTasksConsumer,
@NotNull Consumer<ExternalTaskPojo> buildTasksConsumer,
@NotNull Artifact artifact);
@NotNull Consumer<ExternalTaskPojo> buildTasksConsumer);
}
@@ -1,296 +0,0 @@
/*
* 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 BuildChunkStatusNotification 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
);
}
}
}
}
}
}
+1 -1
View File
@@ -197,7 +197,7 @@
<extensionPoint name="testFramework" interface="com.intellij.testIntegration.TestFramework"/>
<extensionPoint name="buildSystemDriver" interface="com.intellij.openapi.build.BuildSystemDriver"/>
<extensionPoint name="activityRunner" interface="com.intellij.activity.ActivityRunner"/>
<extensionPoint name="unscrambleSupport" interface="com.intellij.unscramble.UnscrambleSupport"/>
+4 -4
View File
@@ -172,11 +172,11 @@
<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.activity.ActivityManager"
serviceImplementation="com.intellij.activity.impl.ActivityManagerImpl"/>
<projectService serviceInterface="com.intellij.execution.runners.BuildSystemExecutionEnvironmentProvider"
serviceImplementation="com.intellij.openapi.build.BuildSystemExecutionEnvironmentProviderImpl"/>
<projectService serviceInterface="com.intellij.execution.runners.ExecutionEnvironmentProvider"
serviceImplementation="com.intellij.activity.impl.ExecutionEnvironmentProviderImpl"/>
<projectService serviceInterface="com.intellij.openapi.compiler.CompilerManager"
serviceImplementation="com.intellij.compiler.CompilerManagerImpl"/>