Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tooling: configurable environment variables #1029

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -23,6 +23,7 @@
import org.gradle.tooling.provider.model.ToolingModelBuilder;

import java.io.File;
import java.util.HashMap;
import java.util.List;

/**
Expand Down
Expand Up @@ -162,7 +162,7 @@ private Runnable runBuildAndCloseServices(StartParameter startParameter, DaemonP
private BuildActionParameters createBuildActionParamters(StartParameter startParameter, DaemonParameters daemonParameters) {
return new DefaultBuildActionParameters(
daemonParameters.getEffectiveSystemProperties(),
System.getenv(),
daemonParameters.getEnvironmentVariables(),
SystemProperties.getInstance().getCurrentDir(),
startParameter.getLogLevel(),
daemonParameters.isEnabled(), startParameter.isContinuous(), daemonParameters.isInteractive(), ClassPath.EMPTY);
Expand Down
Expand Up @@ -45,6 +45,7 @@ public class DaemonParameters {

private int periodicCheckInterval = DEFAULT_PERIODIC_CHECK_INTERVAL_MILLIS;
private final DaemonJvmOptions jvmOptions = new DaemonJvmOptions(new IdentityFileResolver());
private Map<String, String> envVariables;
private boolean enabled = true;
private boolean hasJvmArgs;
private boolean foreground;
Expand All @@ -61,6 +62,7 @@ public DaemonParameters(BuildLayoutParameters layout, Map<String, String> extraS
jvmOptions.systemProperties(extraSystemProperties);
baseDir = new File(layout.getGradleUserHomeDir(), "daemon");
gradleUserHomeDir = layout.getGradleUserHomeDir();
envVariables = new HashMap<String, String>(System.getenv());
}

public boolean isInteractive() {
Expand Down Expand Up @@ -147,6 +149,10 @@ public void setJvmArgs(Iterable<String> jvmArgs) {
jvmOptions.setAllJvmArgs(jvmArgs);
}

public void setEnvironmentVariables(Map<String, String> envVariables) {
this.envVariables = envVariables == null ? new HashMap<String, String>(System.getenv()) : envVariables;
}

public void setDebug(boolean debug) {
jvmOptions.setDebug(debug);
}
Expand Down Expand Up @@ -183,4 +189,8 @@ public boolean isStatus() {
public void setStatus(boolean status) {
this.status = status;
}

public Map<String, String> getEnvironmentVariables() {
return envVariables;
}
}
Expand Up @@ -54,7 +54,7 @@ public Object execute(BuildAction action, BuildRequestContext buildRequestContex
ClassPath classPath = DefaultClassPath.of(parameters.getInjectedPluginClasspath(Collections.<File>emptyList()));

BuildActionParameters actionParameters = new DefaultBuildActionParameters(daemonParameters.getEffectiveSystemProperties(),
System.getenv(), SystemProperties.getInstance().getCurrentDir(), parameters.getBuildLogLevel(), daemonParameters.isEnabled(), continuous, false, classPath);
daemonParameters.getEnvironmentVariables(), SystemProperties.getInstance().getCurrentDir(), parameters.getBuildLogLevel(), daemonParameters.isEnabled(), continuous, false, classPath);
try {
return executer.execute(action, buildRequestContext, actionParameters, contextServices);
} catch (ReportedException e) {
Expand Down
Expand Up @@ -41,9 +41,9 @@
import org.gradle.launcher.exec.BuildActionParameters;
import org.gradle.process.internal.streams.SafeStreams;
import org.gradle.tooling.internal.build.DefaultBuildEnvironment;
import org.gradle.tooling.internal.gradle.DefaultBuildIdentifier;
import org.gradle.tooling.internal.consumer.parameters.FailsafeBuildProgressListenerAdapter;
import org.gradle.tooling.internal.consumer.versioning.ModelMapping;
import org.gradle.tooling.internal.gradle.DefaultBuildIdentifier;
import org.gradle.tooling.internal.protocol.InternalBuildAction;
import org.gradle.tooling.internal.protocol.InternalBuildEnvironment;
import org.gradle.tooling.internal.protocol.InternalBuildProgressListener;
Expand All @@ -54,6 +54,7 @@
import org.gradle.tooling.internal.provider.serialization.PayloadSerializer;
import org.gradle.tooling.internal.provider.serialization.SerializedPayload;
import org.gradle.tooling.internal.provider.test.ProviderInternalTestExecutionRequest;
import org.gradle.tooling.model.UnsupportedMethodException;
import org.gradle.util.GradleVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -187,6 +188,16 @@ private Parameters initParams(ProviderOperationParameters operationParameters) {
if (jvmArguments != null) {
daemonParams.setJvmArgs(jvmArguments);
}
Map<String, String> envVariables = null;
try {
envVariables = operationParameters.getEnvironmentVariables();
} catch (UnsupportedMethodException e) {
LOGGER.debug("Environment variables customization is not supported by target Gradle instance", e);
}
if (envVariables != null) {
daemonParams.setEnvironmentVariables(envVariables);
}

File javaHome = operationParameters.getJavaHome();
if (javaHome != null) {
daemonParams.setJvm(Jvm.forHome(javaHome));
Expand Down
Expand Up @@ -25,6 +25,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -55,6 +56,12 @@ public interface ProviderOperationParameters {
@Nullable
List<String> getJvmArguments();

/**
* @return When null, use the provider's default environment variables. When empty, use no environment variables.
*/
@Nullable
Map<String, String> getEnvironmentVariables();

/**
* @since 1.0-milestone-3
*/
Expand Down
Expand Up @@ -45,5 +45,6 @@ class DaemonBuildActionExecuterTest extends Specification {
e.cause == failure
1 * client.execute(action, buildRequestContext, !null, contextServices) >> { throw new ReportedException(failure) }
_ * daemonParameters.effectiveSystemProperties >> [:]
1 * daemonParameters.getEnvironmentVariables() >> System.getenv()
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.gradle.integtests.tooling.r35

import org.gradle.integtests.tooling.fixture.TargetGradleVersion
import org.gradle.integtests.tooling.fixture.ToolingApiSpecification
import org.gradle.integtests.tooling.fixture.ToolingApiVersion
import org.gradle.tooling.ProjectConnection
import org.gradle.tooling.UnsupportedVersionException
import org.gradle.tooling.model.build.BuildEnvironment

class BuildEnvironmentCrossVersionSpec extends ToolingApiSpecification {

@ToolingApiVersion(">=3.5")
@TargetGradleVersion(">=3.5")
def "provide setEnvironmentVariables on LongRunningOperation"() {
given:
toolingApi.requireDaemons() //cannot be run in embedded mode

buildFile << """
task printEnv() {
doLast {
println "<" + System.getenv() + ">"
}
}"""

when:
ByteArrayOutputStream out = new ByteArrayOutputStream();
withConnection { ProjectConnection connection ->
connection.newBuild().setEnvironmentVariables(["var": "val"]).setStandardOutput(out).forTasks('printEnv').run()
}

then:
out.toString().contains("<${["var": "val"]}>")
}

@ToolingApiVersion(">=3.5")
@TargetGradleVersion("<3.5")
def "long running operation should fail when environment vars specified but not supported by target"() {
when:
withConnection {
def model = it.model(BuildEnvironment.class)
model.setEnvironmentVariables(["var": "val"]).get()
}

then:
UnsupportedVersionException e = thrown()
e.message == "The version of Gradle you are using (${targetDist.version.version}) does not support the environment variables customization feature. Support for this is available in Gradle 3.5 and all later versions."
}
}
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Set;

/**
Expand Down Expand Up @@ -95,6 +96,13 @@ public interface ConfigurableLauncher<T extends ConfigurableLauncher> extends Lo
@Override
T setJvmArguments(Iterable<String> jvmArguments);

/**
* {@inheritDoc}
* @since 3.5
*/
@Override
T setEnvironmentVariables(Map<String, String> envVariables);

/**
* {@inheritDoc}
* @since 1.0-milestone-3
Expand Down
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Set;

/**
Expand Down Expand Up @@ -174,6 +175,20 @@ public interface LongRunningOperation {
*/
LongRunningOperation withArguments(@Nullable Iterable<String> arguments);

/**
* Specifies the environment variables to use for this operation.
* <p>
* {@link org.gradle.tooling.model.build.BuildEnvironment} model contains information such as Java or Gradle environment.
* If you want to get hold of this information you can ask tooling API to build this model.
* <p>
* If not configured or null is passed, then the reasonable default will be used.
*
* @param envVariables environment variables
* @return this
* @since 3.5
*/
LongRunningOperation setEnvironmentVariables(@Nullable Map<String, String> envVariables);

/**
* Adds a progress listener which will receive progress events as the operation runs.
*
Expand Down
Expand Up @@ -75,5 +75,4 @@ public List<String> getJvmArguments() {
}
};
}

}
Expand Up @@ -32,6 +32,7 @@
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class AbstractLongRunningOperation<T extends AbstractLongRunningOperation<T>> implements LongRunningOperation {
Expand Down Expand Up @@ -113,6 +114,12 @@ public T setJvmArguments(Iterable<String> jvmArguments) {
return getThis();
}

@Override
public T setEnvironmentVariables(Map<String, String> envVariables) {
operationParamsBuilder.setEnvironmentVariables(envVariables);
return getThis();
}

@Override
public T addProgressListener(ProgressListener listener) {
operationParamsBuilder.addProgressListener(listener);
Expand Down
@@ -0,0 +1,68 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.tooling.internal.consumer.connection;

import org.gradle.tooling.BuildAction;
import org.gradle.tooling.internal.consumer.TestExecutionRequest;
import org.gradle.tooling.internal.consumer.parameters.ConsumerOperationParameters;
import org.gradle.tooling.internal.consumer.versioning.VersionDetails;
import org.gradle.tooling.model.internal.Exceptions;

public class ParameterValidatingConsumerConnection implements ConsumerConnection {
private final VersionDetails targetVersionDetails;
private final ConsumerConnection delegate;

public ParameterValidatingConsumerConnection(VersionDetails targetVersionDetails, ConsumerConnection connection) {
this.targetVersionDetails = targetVersionDetails;
this.delegate = connection;
}

@Override
public void stop() {
delegate.stop();
}

@Override
public String getDisplayName() {
return delegate.getDisplayName();
}

@Override
public <T> T run(Class<T> type, ConsumerOperationParameters operationParameters) throws UnsupportedOperationException, IllegalStateException {
validateParameters(operationParameters);
return delegate.run(type, operationParameters);
}

@Override
public <T> T run(BuildAction<T> action, ConsumerOperationParameters operationParameters) throws UnsupportedOperationException, IllegalStateException {
validateParameters(operationParameters);
return delegate.run(action, operationParameters);
}

@Override
public void runTests(TestExecutionRequest testExecutionRequest, ConsumerOperationParameters operationParameters) {
validateParameters(operationParameters);
delegate.runTests(testExecutionRequest, operationParameters);
}

private void validateParameters(ConsumerOperationParameters operationParameters) {
if (!targetVersionDetails.supportsEnvironmentVariablesCustomization()) {
if (operationParameters.getEnvironmentVariables() != null) {
throw Exceptions.unsupportedFeature("environment variables customization feature", targetVersionDetails.getVersion(), "3.5");
}
}
}
}
Expand Up @@ -36,6 +36,7 @@
import org.gradle.tooling.internal.consumer.connection.ModelBuilderBackedConsumerConnection;
import org.gradle.tooling.internal.consumer.connection.NoToolingApiConnection;
import org.gradle.tooling.internal.consumer.connection.NonCancellableConsumerConnectionAdapter;
import org.gradle.tooling.internal.consumer.connection.ParameterValidatingConsumerConnection;
import org.gradle.tooling.internal.consumer.connection.ShutdownAwareConsumerConnection;
import org.gradle.tooling.internal.consumer.connection.TestExecutionConsumerConnection;
import org.gradle.tooling.internal.consumer.connection.UnsupportedOlderVersionConnection;
Expand Down Expand Up @@ -99,9 +100,9 @@ public ConsumerConnection create(Distribution distribution, ProgressLoggerFactor
}
adaptedConnection.configure(connectionParameters);
if (!adaptedConnection.getVersionDetails().supportsCancellation()) {
return new NonCancellableConsumerConnectionAdapter(adaptedConnection);
return new ParameterValidatingConsumerConnection(adaptedConnection.getVersionDetails(), new NonCancellableConsumerConnectionAdapter(adaptedConnection));
}
return adaptedConnection;
return new ParameterValidatingConsumerConnection(adaptedConnection.getVersionDetails(), adaptedConnection);
} catch (UnsupportedVersionException e) {
throw e;
} catch (Throwable t) {
Expand Down