diff --git a/src/main/java/org/gradle/profiler/BuildToolCommandLineScenarioDefinition.java b/src/main/java/org/gradle/profiler/BuildToolCommandLineScenarioDefinition.java
index 07cf74fa..bd954886 100644
--- a/src/main/java/org/gradle/profiler/BuildToolCommandLineScenarioDefinition.java
+++ b/src/main/java/org/gradle/profiler/BuildToolCommandLineScenarioDefinition.java
@@ -53,7 +53,7 @@ public File getToolHome() {
@Override
public boolean createsMultipleProcesses() {
- return false;
+ return true;
}
@Override
diff --git a/src/main/java/org/gradle/profiler/CompositeProfiler.java b/src/main/java/org/gradle/profiler/CompositeProfiler.java
index c6df0b89..d5a4a052 100644
--- a/src/main/java/org/gradle/profiler/CompositeProfiler.java
+++ b/src/main/java/org/gradle/profiler/CompositeProfiler.java
@@ -13,6 +13,11 @@ class CompositeProfiler extends Profiler {
this.delegates = delegates;
}
+ @Override
+ public boolean requiresGradle() {
+ return delegates.stream().anyMatch(Profiler::requiresGradle);
+ }
+
@Override
public String toString() {
return delegates.stream().map(Object::toString).collect(Collectors.joining(", "));
diff --git a/src/main/java/org/gradle/profiler/InstrumentingProfiler.java b/src/main/java/org/gradle/profiler/InstrumentingProfiler.java
index def89933..6630ccfa 100644
--- a/src/main/java/org/gradle/profiler/InstrumentingProfiler.java
+++ b/src/main/java/org/gradle/profiler/InstrumentingProfiler.java
@@ -18,6 +18,12 @@
*
The profiler may support starting recording multiple times for a given JVM. The implementation should indicate this by overriding {@link #canRestartRecording(ScenarioSettings)}.
*/
public abstract class InstrumentingProfiler extends Profiler {
+
+ @Override
+ public boolean requiresGradle() {
+ return false;
+ }
+
/**
* Calculates the JVM args for all builds, including warm-ups.
*
@@ -67,7 +73,7 @@ public JvmArgsCalculator newInstrumentedBuildsJvmArgsCalculator(ScenarioSettings
*/
@Override
public ProfilerController newController(String pid, ScenarioSettings settings) {
- SnapshotCapturingProfilerController controller = doNewController(settings);
+ SnapshotCapturingProfilerController controller = newSnapshottingController(settings);
if (settings.getScenario().getInvoker().isDoesNotUseDaemon()) {
return new SessionOnlyController(pid, controller);
}
@@ -109,7 +115,7 @@ protected boolean canRestartRecording(ScenarioSettings settings) {
*/
protected abstract JvmArgsCalculator jvmArgsWithInstrumentation(ScenarioSettings settings, boolean startRecordingOnProcessStart, boolean captureSnapshotOnProcessExit);
- protected abstract SnapshotCapturingProfilerController doNewController(ScenarioSettings settings);
+ public abstract SnapshotCapturingProfilerController newSnapshottingController(ScenarioSettings settings);
public interface SnapshotCapturingProfilerController {
void startRecording(String pid) throws IOException, InterruptedException;
diff --git a/src/main/java/org/gradle/profiler/Profiler.java b/src/main/java/org/gradle/profiler/Profiler.java
index 2f006905..7c0552a9 100644
--- a/src/main/java/org/gradle/profiler/Profiler.java
+++ b/src/main/java/org/gradle/profiler/Profiler.java
@@ -18,15 +18,25 @@
import java.io.File;
import java.util.function.Consumer;
-public class Profiler {
+public abstract class Profiler {
public static final Profiler NONE = new Profiler() {
+ @Override
+ public boolean requiresGradle() {
+ return false;
+ }
+
@Override
public String toString() {
return "none";
}
};
+ /**
+ * Whether this profiler supports only Gradle builds.
+ */
+ public abstract boolean requiresGradle();
+
public void validate(ScenarioSettings settings, Consumer reporter) {
}
diff --git a/src/main/java/org/gradle/profiler/ScenarioDefinition.java b/src/main/java/org/gradle/profiler/ScenarioDefinition.java
index ee317744..d87c42d9 100644
--- a/src/main/java/org/gradle/profiler/ScenarioDefinition.java
+++ b/src/main/java/org/gradle/profiler/ScenarioDefinition.java
@@ -1,8 +1,12 @@
package org.gradle.profiler;
+import org.apache.commons.io.FileUtils;
+
import javax.annotation.Nullable;
import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
+import java.io.UncheckedIOException;
import java.util.List;
import java.util.function.Consumer;
@@ -28,6 +32,11 @@ public ScenarioDefinition(
this.warmUpCount = warmUpCount;
this.buildCount = buildCount;
this.outputDir = outputDir;
+ try {
+ FileUtils.forceMkdir(outputDir);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
public void validate() {
@@ -98,6 +107,7 @@ public void printTo(PrintStream out) {
}
public void visitProblems(InvocationSettings settings, Consumer reporter) {
+ settings.getProfiler().validate(new ScenarioSettings(settings, this), reporter);
}
protected void printDetail(PrintStream out) {
@@ -108,4 +118,8 @@ protected void printDetail(PrintStream out) {
public abstract boolean doesCleanup();
public abstract BuildConfiguration getBuildConfiguration();
+
+ public static String safeFileName(String name) {
+ return name.replace("/", "-");
+ }
}
diff --git a/src/main/java/org/gradle/profiler/ScenarioLoader.java b/src/main/java/org/gradle/profiler/ScenarioLoader.java
index aad08fb7..bea3d10d 100644
--- a/src/main/java/org/gradle/profiler/ScenarioLoader.java
+++ b/src/main/java/org/gradle/profiler/ScenarioLoader.java
@@ -237,7 +237,7 @@ static List loadScenarios(File scenarioFile, InvocationSetti
String title = scenario.hasPath(TITLE) ? scenario.getString(TITLE) : null;
int buildCount = getBuildCount(settings, scenario);
- File scenarioBaseDir = selectedScenarios.size() == 1 ? settings.getOutputDir() : new File(settings.getOutputDir(), GradleScenarioDefinition.safeFileName(scenarioName));
+ File scenarioBaseDir = selectedScenarios.size() == 1 ? settings.getOutputDir() : new File(settings.getOutputDir(), ScenarioDefinition.safeFileName(scenarioName));
if (scenario.hasPath(BAZEL) && settings.isBazel()) {
Config executionInstructions = getConfig(scenarioFile, settings, scenarioName, scenario, BAZEL, BAZEL_KEYS);
@@ -330,8 +330,8 @@ private static List getMutators(Config scenario, String scenarioNa
}
private static Config getConfig(File scenarioFile, InvocationSettings settings, String scenarioName, Config scenario, String toolName, List toolKeys) {
- if (settings.isProfile()) {
- throw new IllegalArgumentException("Can only profile scenario '" + scenarioName + "' when building using Gradle.");
+ if (settings.getProfiler().requiresGradle()) {
+ throw new IllegalArgumentException("Profiler " + settings.getProfiler() + " is not compatible with " + toolName + " scenarios.");
}
Config executionInstructions = scenario.getConfig(toolName);
for (String key : scenario.getObject(toolName).keySet()) {
diff --git a/src/main/java/org/gradle/profiler/asyncprofiler/AsyncProfiler.java b/src/main/java/org/gradle/profiler/asyncprofiler/AsyncProfiler.java
index 051f321f..032cce1f 100644
--- a/src/main/java/org/gradle/profiler/asyncprofiler/AsyncProfiler.java
+++ b/src/main/java/org/gradle/profiler/asyncprofiler/AsyncProfiler.java
@@ -24,7 +24,7 @@ protected JvmArgsCalculator jvmArgsWithInstrumentation(ScenarioSettings settings
}
@Override
- protected SnapshotCapturingProfilerController doNewController(ScenarioSettings settings) {
+ public SnapshotCapturingProfilerController newSnapshottingController(ScenarioSettings settings) {
return new AsyncProfilerController(config, settings);
}
diff --git a/src/main/java/org/gradle/profiler/bazel/BazelScenarioInvoker.java b/src/main/java/org/gradle/profiler/bazel/BazelScenarioInvoker.java
index 1581ef8c..9a630329 100644
--- a/src/main/java/org/gradle/profiler/bazel/BazelScenarioInvoker.java
+++ b/src/main/java/org/gradle/profiler/bazel/BazelScenarioInvoker.java
@@ -12,6 +12,10 @@
public class BazelScenarioInvoker extends BuildToolCommandLineInvoker {
@Override
public void run(BazelScenarioDefinition scenario, InvocationSettings settings, Consumer resultConsumer) {
+ if (settings.isProfile()) {
+ throw new IllegalArgumentException("Profiling is not supported for Buck builds");
+ }
+
List targets = scenario.getTargets();
List commandLine = new ArrayList<>();
diff --git a/src/main/java/org/gradle/profiler/buck/BuckScenarioInvoker.java b/src/main/java/org/gradle/profiler/buck/BuckScenarioInvoker.java
index 8ed25779..45e45b49 100644
--- a/src/main/java/org/gradle/profiler/buck/BuckScenarioInvoker.java
+++ b/src/main/java/org/gradle/profiler/buck/BuckScenarioInvoker.java
@@ -16,6 +16,10 @@
public class BuckScenarioInvoker extends BuildToolCommandLineInvoker {
@Override
public void run(BuckScenarioDefinition scenario, InvocationSettings settings, Consumer resultConsumer) {
+ if (settings.isProfile()) {
+ throw new IllegalArgumentException("Profiling is not supported for Buck builds");
+ }
+
String buckwExe = settings.getProjectDir() + "/buckw";
List targets = new ArrayList<>(scenario.getTargets());
if (scenario.getType() != null) {
diff --git a/src/main/java/org/gradle/profiler/buildscan/BuildScanProfiler.java b/src/main/java/org/gradle/profiler/buildscan/BuildScanProfiler.java
index 5a438a1d..967c89a1 100644
--- a/src/main/java/org/gradle/profiler/buildscan/BuildScanProfiler.java
+++ b/src/main/java/org/gradle/profiler/buildscan/BuildScanProfiler.java
@@ -33,6 +33,11 @@ public static String defaultBuildScanVersion(GradleVersion gradleVersion) {
this.buildScanVersion = buildScanVersion;
}
+ @Override
+ public boolean requiresGradle() {
+ return true;
+ }
+
@Override
public String toString() {
return "buildscan";
diff --git a/src/main/java/org/gradle/profiler/chrometrace/ChromeTraceProfiler.java b/src/main/java/org/gradle/profiler/chrometrace/ChromeTraceProfiler.java
index da490476..d5db686e 100644
--- a/src/main/java/org/gradle/profiler/chrometrace/ChromeTraceProfiler.java
+++ b/src/main/java/org/gradle/profiler/chrometrace/ChromeTraceProfiler.java
@@ -13,6 +13,12 @@ public String toString() {
return "chrome-trace";
}
+ @Override
+ public boolean requiresGradle() {
+ return true;
+ }
+
+
@Override
public void summarizeResultFile(File resultFile, Consumer consumer) {
if (resultFile.getName().endsWith("-trace.json")) {
diff --git a/src/main/java/org/gradle/profiler/gradle/GradleScenarioDefinition.java b/src/main/java/org/gradle/profiler/gradle/GradleScenarioDefinition.java
index 5cb0485f..8977f18a 100644
--- a/src/main/java/org/gradle/profiler/gradle/GradleScenarioDefinition.java
+++ b/src/main/java/org/gradle/profiler/gradle/GradleScenarioDefinition.java
@@ -1,8 +1,11 @@
package org.gradle.profiler.gradle;
-import org.gradle.profiler.*;
+import org.gradle.profiler.BuildAction;
+import org.gradle.profiler.BuildMutator;
+import org.gradle.profiler.GradleBuildConfiguration;
+import org.gradle.profiler.InvocationSettings;
+import org.gradle.profiler.ScenarioDefinition;
import org.gradle.profiler.buildops.BuildOperationUtil;
-import org.gradle.profiler.gradle.GradleBuildInvoker;
import org.gradle.util.GradleVersion;
import java.io.File;
@@ -60,10 +63,6 @@ public String getProfileName() {
return safeFileName(getName()) + "-" + buildConfiguration.getGradleVersion().getVersion();
}
- public static String safeFileName(String name) {
- return name.replace("/", "-");
- }
-
@Override
public String getBuildToolDisplayName() {
return buildConfiguration.getGradleVersion().toString();
@@ -133,7 +132,7 @@ public void visitProblems(InvocationSettings settings, Consumer reporter
if (settings.isMeasureConfigTime() && isBuildServiceUnsupported()) {
reporter.accept("Measuring build configuration is only supported for Gradle 6.1-milestone-3 and later");
}
- settings.getProfiler().validate(new ScenarioSettings(settings, this), reporter);
+ super.visitProblems(settings, reporter);
}
private boolean isBuildServiceUnsupported() {
diff --git a/src/main/java/org/gradle/profiler/heapdump/HeapDumpProfiler.java b/src/main/java/org/gradle/profiler/heapdump/HeapDumpProfiler.java
index a1aa38e5..9232b309 100644
--- a/src/main/java/org/gradle/profiler/heapdump/HeapDumpProfiler.java
+++ b/src/main/java/org/gradle/profiler/heapdump/HeapDumpProfiler.java
@@ -10,6 +10,11 @@
import java.util.function.Consumer;
public class HeapDumpProfiler extends Profiler {
+ @Override
+ public boolean requiresGradle() {
+ return true;
+ }
+
@Override
public GradleArgsCalculator newGradleArgsCalculator(ScenarioSettings settings) {
return new GradleInstrumentation() {
diff --git a/src/main/java/org/gradle/profiler/jfr/JfrProfiler.java b/src/main/java/org/gradle/profiler/jfr/JfrProfiler.java
index be08e85e..9d04b894 100644
--- a/src/main/java/org/gradle/profiler/jfr/JfrProfiler.java
+++ b/src/main/java/org/gradle/profiler/jfr/JfrProfiler.java
@@ -29,7 +29,7 @@ public void summarizeResultFile(File resultFile, Consumer consumer) {
}
@Override
- protected SnapshotCapturingProfilerController doNewController(ScenarioSettings settings) {
+ public SnapshotCapturingProfilerController newSnapshottingController(ScenarioSettings settings) {
return new JFRControl(jfrArgs, settings.computeJfrProfilerOutputLocation());
}
diff --git a/src/main/java/org/gradle/profiler/jprofiler/JProfilerProfiler.java b/src/main/java/org/gradle/profiler/jprofiler/JProfilerProfiler.java
index 3c4ad27a..8498614f 100644
--- a/src/main/java/org/gradle/profiler/jprofiler/JProfilerProfiler.java
+++ b/src/main/java/org/gradle/profiler/jprofiler/JProfilerProfiler.java
@@ -32,7 +32,7 @@ protected boolean canRestartRecording(ScenarioSettings settings) {
}
@Override
- protected SnapshotCapturingProfilerController doNewController(ScenarioSettings settings) {
+ public SnapshotCapturingProfilerController newSnapshottingController(ScenarioSettings settings) {
return new JProfilerController(settings, jProfilerConfig);
}
diff --git a/src/main/java/org/gradle/profiler/maven/MavenScenarioDefinition.java b/src/main/java/org/gradle/profiler/maven/MavenScenarioDefinition.java
index 1619e6f5..b4630cc3 100644
--- a/src/main/java/org/gradle/profiler/maven/MavenScenarioDefinition.java
+++ b/src/main/java/org/gradle/profiler/maven/MavenScenarioDefinition.java
@@ -36,7 +36,7 @@ public String getDisplayName() {
@Override
public String getProfileName() {
- throw new UnsupportedOperationException();
+ return safeFileName(getName()) + "-mvn";
}
@Override
diff --git a/src/main/java/org/gradle/profiler/maven/MavenScenarioInvoker.java b/src/main/java/org/gradle/profiler/maven/MavenScenarioInvoker.java
index dc8851bb..630f2dde 100644
--- a/src/main/java/org/gradle/profiler/maven/MavenScenarioInvoker.java
+++ b/src/main/java/org/gradle/profiler/maven/MavenScenarioInvoker.java
@@ -2,22 +2,50 @@
import com.google.common.collect.ImmutableMap;
import org.gradle.profiler.BuildToolCommandLineInvoker;
+import org.gradle.profiler.InstrumentingProfiler;
+import org.gradle.profiler.InstrumentingProfiler.SnapshotCapturingProfilerController;
import org.gradle.profiler.InvocationSettings;
+import org.gradle.profiler.ScenarioSettings;
import org.gradle.profiler.result.BuildInvocationResult;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.function.Consumer;
public class MavenScenarioInvoker extends BuildToolCommandLineInvoker {
@Override
- public void run(MavenScenarioDefinition scenario, InvocationSettings settings, Consumer resultConsumer) {
+ public void run(MavenScenarioDefinition scenario, InvocationSettings settings, Consumer resultConsumer) throws IOException, InterruptedException {
List commandLine = new ArrayList<>();
commandLine.add(scenario.getExecutablePath());
commandLine.addAll(scenario.getTargets());
scenario.getSystemProperties().forEach((key, value) ->
commandLine.add(String.format("-D%s=%s", key, value)));
- doRun(scenario, settings, resultConsumer, commandLine, ImmutableMap.of());
+
+ Map environment;
+ SnapshotCapturingProfilerController controller;
+ if (settings.getProfiler() instanceof InstrumentingProfiler) {
+ InstrumentingProfiler profiler = (InstrumentingProfiler) settings.getProfiler();
+ ScenarioSettings scenarioSettings = new ScenarioSettings(settings, scenario);
+ List mavenOpts = new ArrayList<>();
+ profiler.newInstrumentedBuildsJvmArgsCalculator(scenarioSettings)
+ .calculateJvmArgs(mavenOpts);
+ environment = ImmutableMap.of(
+ "MAVEN_OPTS", String.join(" ", mavenOpts)
+ );
+
+ controller = profiler.newSnapshottingController(scenarioSettings);
+ } else {
+ environment = ImmutableMap.of();
+ controller = null;
+ }
+
+ doRun(scenario, settings, resultConsumer, commandLine, environment);
+
+ if (controller != null) {
+ controller.stopSession();
+ }
}
}
diff --git a/src/main/java/org/gradle/profiler/yourkit/YourKitProfiler.java b/src/main/java/org/gradle/profiler/yourkit/YourKitProfiler.java
index 0b0ce528..666c8ea5 100644
--- a/src/main/java/org/gradle/profiler/yourkit/YourKitProfiler.java
+++ b/src/main/java/org/gradle/profiler/yourkit/YourKitProfiler.java
@@ -32,7 +32,7 @@ protected boolean canRestartRecording(ScenarioSettings settings) {
}
@Override
- protected SnapshotCapturingProfilerController doNewController(ScenarioSettings settings) {
+ public SnapshotCapturingProfilerController newSnapshottingController(ScenarioSettings settings) {
return new YourKitProfilerController(yourKitConfig);
}