diff --git a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/dsl/DependencyHandler.java b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/dsl/DependencyHandler.java
index d06af37ed9531..46755c58ecb08 100644
--- a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/dsl/DependencyHandler.java
+++ b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/dsl/DependencyHandler.java
@@ -17,6 +17,7 @@
import groovy.lang.Closure;
import org.gradle.api.Action;
+import org.gradle.api.Incubating;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.ExternalModuleDependency;
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
@@ -383,6 +384,15 @@ public interface DependencyHandler extends ExtensionAware {
*/
Dependency gradleApi();
+ /**
+ * Creates a dependency on the API of the specified version of Gradle.
+ *
+ * @return The dependency.
+ * @since 7.5
+ */
+ @Incubating
+ Dependency gradleApi(String version);
+
/**
* Creates a dependency on the Gradle test-kit API.
*
diff --git a/subprojects/core/src/integTest/groovy/org/gradle/groovy/scripts/GroovyImportsIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/groovy/scripts/GroovyImportsIntegrationTest.groovy
index 5bb0b875fe40c..c008afea0d6fb 100644
--- a/subprojects/core/src/integTest/groovy/org/gradle/groovy/scripts/GroovyImportsIntegrationTest.groovy
+++ b/subprojects/core/src/integTest/groovy/org/gradle/groovy/scripts/GroovyImportsIntegrationTest.groovy
@@ -38,5 +38,4 @@ import org.apache.commons.math3.util.FastMath
args("--init-script", initScript.toString())
succeeds("help")
}
-
}
diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/GradleApiVersionProvider.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/GradleApiVersionProvider.java
new file mode 100644
index 0000000000000..868e9d6b833b6
--- /dev/null
+++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/GradleApiVersionProvider.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 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.api.internal.artifacts;
+
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.SelfResolvingDependency;
+import org.gradle.api.artifacts.dsl.DependencyHandler;
+import org.gradle.api.artifacts.dsl.RepositoryHandler;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.Set;
+
+public class GradleApiVersionProvider {
+
+ public static final String GRADLE_API_SOURCE_VERSION_PROPERTY = "org.gradle.api.source-version";
+
+ public static Optional getGradleApiSourceVersion() {
+ return Optional.ofNullable(System.getProperty(GRADLE_API_SOURCE_VERSION_PROPERTY));
+ }
+
+ public static void addGradleSourceApiRepository(RepositoryHandler repositoryHandler) {
+ getGradleApiSourceVersion().ifPresent(version -> {
+ String repositoryUrl = System.getProperty("gradle.api.repository.url", "https://repo.gradle.org/gradle/libs-releases");
+ repositoryHandler.maven(repo -> repo.setUrl(repositoryUrl));
+ });
+ }
+
+ public static void addToConfiguration(Configuration configuration, DependencyHandler repositoryHandler) {
+ Dependency gradleApiDependency = getGradleApiSourceVersion()
+ .map(repositoryHandler::gradleApi)
+ .orElseGet(repositoryHandler::gradleApi);
+ configuration.getDependencies().add(gradleApiDependency);
+ }
+
+ public static Collection resolveGradleSourceApi(DependencyResolutionServices dependencyResolutionServices) {
+ return getGradleApiSourceVersion()
+ .map(version -> gradleApisFromRepository(dependencyResolutionServices, version))
+ .orElseGet(() -> gradleApisFromCurrentGradle(dependencyResolutionServices.getDependencyHandler()));
+ }
+
+ private static Set gradleApisFromCurrentGradle(DependencyHandler dependencyHandler) {
+ SelfResolvingDependency gradleApiDependency = (SelfResolvingDependency) dependencyHandler.gradleApi();
+ return gradleApiDependency.resolve();
+
+ }
+ private static Set gradleApisFromRepository(DependencyResolutionServices dependencyResolutionServices, String version) {
+ addGradleSourceApiRepository(dependencyResolutionServices.getResolveRepositoryHandler());
+ Configuration detachedConfiguration = dependencyResolutionServices.getConfigurationContainer().detachedConfiguration(dependencyResolutionServices.getDependencyHandler().gradleApi(version));
+ return detachedConfiguration.resolve();
+ }
+}
diff --git a/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/DefaultScriptCompilationHandler.java b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/DefaultScriptCompilationHandler.java
index f317c1c449012..a8550ede4a8ba 100644
--- a/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/DefaultScriptCompilationHandler.java
+++ b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/DefaultScriptCompilationHandler.java
@@ -39,6 +39,7 @@
import org.gradle.groovy.scripts.Transformer;
import org.gradle.internal.UncheckedException;
import org.gradle.internal.classloader.ClassLoaderUtils;
+import org.gradle.internal.classloader.FilteringClassLoader;
import org.gradle.internal.classloader.ImplementationHashAware;
import org.gradle.internal.classloader.VisitableURLClassLoader;
import org.gradle.internal.classpath.ClassPath;
@@ -107,18 +108,43 @@ public void compileToDir(ScriptSource source, ClassLoader classLoader, File clas
}
private void compileScript(ScriptSource source, ClassLoader classLoader, CompilerConfiguration configuration, File metadataDir,
- final CompileOperation> extractingTransformer, final Action super ClassNode> customVerifier) {
+ final CompileOperation> extractingTransformer, final Action super ClassNode> customVerifier
+ ) {
final Transformer transformer = extractingTransformer != null ? extractingTransformer.getTransformer() : null;
logger.info("Compiling {} using {}.", source.getDisplayName(), transformer != null ? transformer.getClass().getSimpleName() : "no transformer");
final EmptyScriptDetector emptyScriptDetector = new EmptyScriptDetector();
final PackageStatementDetector packageDetector = new PackageStatementDetector();
+
+ FilteringClassLoader.Spec groovyCompilerClassLoaderSpec = new FilteringClassLoader.Spec();
+ groovyCompilerClassLoaderSpec.allowPackage("org.codehaus.groovy");
+ groovyCompilerClassLoaderSpec.allowPackage("groovy");
+ groovyCompilerClassLoaderSpec.allowPackage("groovyjarjarasm");
+ // Disallow classes from Groovy Jar that reference external classes. Such classes must be loaded from astTransformClassLoader,
+ // or a NoClassDefFoundError will occur. Essentially this is drawing a line between the Groovy compiler and the Groovy
+ // library, albeit only for selected classes that run a high risk of being statically referenced from a transform.
+ groovyCompilerClassLoaderSpec.disallowClass("groovy.util.GroovyTestCase");
+ groovyCompilerClassLoaderSpec.disallowClass("org.codehaus.groovy.transform.NotYetImplementedASTTransformation");
+ groovyCompilerClassLoaderSpec.disallowPackage("groovy.servlet");
+ FilteringClassLoader groovyCompilerClassLoader = new FilteringClassLoader(GroovyClassLoader.class.getClassLoader(), groovyCompilerClassLoaderSpec);
+
+ // AST transforms need their own class loader that shares compiler classes with the compiler itself
+ // can't delegate to compileClasspathLoader because this would result in ASTTransformation interface
+ // (which is implemented by the transform class) being loaded by compileClasspathClassLoader (which is
+ // where the transform class is loaded from)
+ GroovyClassLoader astTransformClassLoader = new GroovyClassLoader(groovyCompilerClassLoader, null);
+
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader, configuration, false) {
@Override
protected CompilationUnit createCompilationUnit(CompilerConfiguration compilerConfiguration,
CodeSource codeSource) {
- CompilationUnit compilationUnit = new CustomCompilationUnit(compilerConfiguration, codeSource, customVerifier, this, simpleNameToFQN);
+ CompilationUnit compilationUnit = new CustomCompilationUnit(compilerConfiguration, codeSource, customVerifier, this, simpleNameToFQN) {
+ @Override
+ public GroovyClassLoader getTransformLoader() {
+ return astTransformClassLoader;
+ }
+ };
if (transformer != null) {
transformer.register(compilationUnit);
diff --git a/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/FileCacheBackedScriptClassCompiler.java b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/FileCacheBackedScriptClassCompiler.java
index 264262fbff0bf..3d77f41de2103 100644
--- a/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/FileCacheBackedScriptClassCompiler.java
+++ b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/FileCacheBackedScriptClassCompiler.java
@@ -50,6 +50,7 @@
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import java.net.URLClassLoader;
import static org.gradle.internal.classpath.CachedClasspathTransformer.StandardTransform.BuildLogic;
@@ -63,16 +64,22 @@ public class FileCacheBackedScriptClassCompiler implements ScriptClassCompiler,
private final GlobalScopedCache cacheRepository;
private final ClassLoaderHierarchyHasher classLoaderHierarchyHasher;
private final CachedClasspathTransformer classpathTransformer;
+ private final GroovyScriptClasspathProvider groovyScriptClasspathProvider;
public FileCacheBackedScriptClassCompiler(
- GlobalScopedCache cacheRepository, ScriptCompilationHandler scriptCompilationHandler,
- ProgressLoggerFactory progressLoggerFactory, ClassLoaderHierarchyHasher classLoaderHierarchyHasher,
- CachedClasspathTransformer classpathTransformer) {
+ GlobalScopedCache cacheRepository,
+ ScriptCompilationHandler scriptCompilationHandler,
+ ProgressLoggerFactory progressLoggerFactory,
+ ClassLoaderHierarchyHasher classLoaderHierarchyHasher,
+ CachedClasspathTransformer classpathTransformer,
+ GroovyScriptClasspathProvider groovyScriptClasspathProvider
+ ) {
this.cacheRepository = cacheRepository;
this.scriptCompilationHandler = scriptCompilationHandler;
this.progressLoggerFactory = progressLoggerFactory;
this.classLoaderHierarchyHasher = classLoaderHierarchyHasher;
this.classpathTransformer = classpathTransformer;
+ this.groovyScriptClasspathProvider = groovyScriptClasspathProvider;
}
@Override
@@ -80,13 +87,16 @@ public CompiledScript compile(final ScriptSource sou
final ClassLoaderScope targetScope,
final CompileOperation operation,
final Class scriptBaseClass,
- final Action super ClassNode> verifier) {
+ final Action super ClassNode> verifier
+ ) {
assert source.getResource().isContentCached();
if (source.getResource().getHasEmptyContent()) {
return emptyCompiledScript(operation);
}
ClassLoader classLoader = targetScope.getExportClassLoader();
+ ClassPath compilationClasspath = groovyScriptClasspathProvider.compilationClassPathOf(targetScope);
+ ClassLoader compileClassLoader = new URLClassLoader(compilationClasspath.getAsURLArray(), ClassLoader.getSystemClassLoader().getParent());
HashCode sourceHashCode = source.getResource().getContentHash();
final String dslId = operation.getId();
HashCode classLoaderHash = classLoaderHierarchyHasher.getClassLoaderHash(classLoader);
@@ -99,6 +109,10 @@ public CompiledScript compile(final ScriptSource sou
hasher.putString(dslId);
hasher.putHash(sourceHashCode);
hasher.putHash(classLoaderHash);
+ for (File jar : compilationClasspath.getAsFiles()) {
+ // TODO: Snapshot the contents here.
+ hasher.putString(jar.getName());
+ }
String key = hasher.hash().toCompactString();
// Caching involves 2 distinct caches, so that 2 scripts with the same (hash, classpath) do not get compiled twice
@@ -111,7 +125,7 @@ public CompiledScript compile(final ScriptSource sou
.withDisplayName(dslId + " generic class cache for " + source.getDisplayName())
.withInitializer(new ProgressReportingInitializer(
progressLoggerFactory,
- new CompileToCrossBuildCacheAction(remapped, classLoader, operation, verifier, scriptBaseClass),
+ new CompileToCrossBuildCacheAction(remapped, compileClassLoader, operation, verifier, scriptBaseClass),
"Compiling " + source.getShortDisplayName()))
.open();
try {
diff --git a/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/GroovyScriptClasspathProvider.java b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/GroovyScriptClasspathProvider.java
new file mode 100644
index 0000000000000..e6111fb8fb36b
--- /dev/null
+++ b/subprojects/core/src/main/java/org/gradle/groovy/scripts/internal/GroovyScriptClasspathProvider.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2022 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.groovy.scripts.internal;
+
+import org.gradle.api.internal.initialization.ClassLoaderScope;
+import org.gradle.internal.classloader.ClassLoaderVisitor;
+import org.gradle.internal.classpath.ClassPath;
+import org.gradle.internal.classpath.DefaultClassPath;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Supplier;
+
+public class GroovyScriptClasspathProvider {
+ private final ConcurrentMap cachedScopeCompilationClasspath = new ConcurrentHashMap<>();
+ private final Map> cachedClasspaths = new HashMap<>();
+ private final Set gradleImplementationClasspath = new LinkedHashSet<>();
+ private ClassPath gradleApi;
+ private ClassPath groovyJars;
+ private final Supplier> gradleApiJarsProvider;
+ private final Supplier> groovyJarsProvider;
+
+ public GroovyScriptClasspathProvider(
+ ClassLoaderScope coreAndPluginsScope,
+ Supplier> gradleApiJarsProvider,
+ Supplier> groovyJarsProvider
+ ) {
+ this.gradleApiJarsProvider = gradleApiJarsProvider;
+ this.groovyJarsProvider = groovyJarsProvider;
+ this.gradleImplementationClasspath.addAll(classpathOf(coreAndPluginsScope.getExportClassLoader()));
+ this.gradleImplementationClasspath.removeIf(file -> !file.getName().startsWith("gradle-"));
+ }
+
+ public ClassPath compilationClassPathOf(ClassLoaderScope scope) {
+ return getGradleApi().plus(exportClassPathFromHierarchyOf(scope));
+ }
+
+ private ClassPath getGradleApi() {
+ if (gradleApi == null) {
+ gradleApi = DefaultClassPath.of(gradleApiJarsProvider.get());
+ }
+ return gradleApi;
+ }
+
+ private ClassPath getGroovy() {
+ if (groovyJars == null) {
+ groovyJars = DefaultClassPath.of(groovyJarsProvider.get());
+ }
+ return groovyJars;
+ }
+
+ private ClassPath exportClassPathFromHierarchyOf(ClassLoaderScope scope) {
+ Set exportedClasspath = new LinkedHashSet<>(classpathOf(scope.getExportClassLoader()));
+ exportedClasspath.removeAll(gradleImplementationClasspath);
+ return DefaultClassPath.of(exportedClasspath);
+ }
+
+ private Set classpathOf(ClassLoader classLoader) {
+ Set classpath = cachedClasspaths.get(classLoader);
+ if (classpath == null) {
+ Set classpathFiles = new LinkedHashSet<>();
+ new ClassLoaderVisitor() {
+ @Override
+ public void visitClassPath(URL[] classPath) {
+ for (URL url : classPath) {
+ if (url.getProtocol().equals("file")) {
+ classpathFiles.add(new File(toUri(url)));
+ }
+ }
+ }
+
+ @Override
+ public void visitParent(ClassLoader parent) {
+ classpathFiles.addAll(classpathOf(parent));
+ }
+
+ private URI toUri(URL url) {
+ try {
+ return url.toURI();
+ } catch (URISyntaxException e) {
+ try {
+ return new URL(
+ url.getProtocol(),
+ url.getHost(),
+ url.getPort(),
+ url.getFile().replace(" ", "%20")
+ ).toURI();
+ } catch (URISyntaxException | MalformedURLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+ }.visit(classLoader);
+ cachedClasspaths.put(classLoader, classpathFiles);
+ classpath = classpathFiles;
+ }
+ return classpath;
+ }
+}
diff --git a/subprojects/core/src/main/java/org/gradle/internal/service/scopes/BuildScopeServices.java b/subprojects/core/src/main/java/org/gradle/internal/service/scopes/BuildScopeServices.java
index 53682561019d6..ad1c9f17ab702 100644
--- a/subprojects/core/src/main/java/org/gradle/internal/service/scopes/BuildScopeServices.java
+++ b/subprojects/core/src/main/java/org/gradle/internal/service/scopes/BuildScopeServices.java
@@ -18,6 +18,7 @@
import org.gradle.StartParameter;
import org.gradle.api.Project;
+import org.gradle.api.artifacts.SelfResolvingDependency;
import org.gradle.api.internal.BuildDefinition;
import org.gradle.api.internal.ClassPathRegistry;
import org.gradle.api.internal.DefaultClassPathProvider;
@@ -29,8 +30,12 @@
import org.gradle.api.internal.StartParameterInternal;
import org.gradle.api.internal.artifacts.DefaultModule;
import org.gradle.api.internal.artifacts.DependencyManagementServices;
+import org.gradle.api.internal.artifacts.DependencyResolutionServices;
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider;
import org.gradle.api.internal.artifacts.Module;
import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider;
+import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory;
+import org.gradle.api.internal.artifacts.dsl.dependencies.UnknownProjectFinder;
import org.gradle.api.internal.classpath.ModuleRegistry;
import org.gradle.api.internal.classpath.PluginModuleRegistry;
import org.gradle.api.internal.component.ComponentTypeRegistry;
@@ -43,6 +48,7 @@
import org.gradle.api.internal.file.temp.TemporaryFileProvider;
import org.gradle.api.internal.initialization.DefaultScriptClassPathResolver;
import org.gradle.api.internal.initialization.DefaultScriptHandlerFactory;
+import org.gradle.api.internal.initialization.RootScriptDomainObjectContext;
import org.gradle.api.internal.initialization.ScriptClassPathInitializer;
import org.gradle.api.internal.initialization.ScriptClassPathResolver;
import org.gradle.api.internal.initialization.ScriptHandlerFactory;
@@ -117,6 +123,7 @@
import org.gradle.groovy.scripts.internal.DefaultScriptCompilationHandler;
import org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory;
import org.gradle.groovy.scripts.internal.FileCacheBackedScriptClassCompiler;
+import org.gradle.groovy.scripts.internal.GroovyScriptClasspathProvider;
import org.gradle.groovy.scripts.internal.ScriptRunnerFactory;
import org.gradle.initialization.BuildLoader;
import org.gradle.initialization.BuildOperationFiringSettingsPreparer;
@@ -416,6 +423,27 @@ protected ITaskFactory createITaskFactory(Instantiator instantiator, TaskClassIn
new TaskFactory());
}
+ protected GroovyScriptClasspathProvider createGroovyScriptClasspathProvider(
+ ClassLoaderScopeRegistry classLoaderScopeRegistry,
+ DependencyManagementServices dependencyManagementServices,
+ FileResolver fileResolver,
+ FileCollectionFactory fileCollectionFactory,
+ DependencyMetaDataProvider dependencyMetaDataProvider,
+ DependencyFactory dependencyFactory
+ ) {
+ DependencyResolutionServices resolutionServices = dependencyManagementServices.create(
+ fileResolver,
+ fileCollectionFactory,
+ dependencyMetaDataProvider,
+ new UnknownProjectFinder("Some unknown project"),
+ RootScriptDomainObjectContext.PLUGINS
+ );
+ return new GroovyScriptClasspathProvider(
+ classLoaderScopeRegistry.getCoreAndPluginsScope(),
+ () -> GradleApiVersionProvider.resolveGradleSourceApi(resolutionServices),
+ () -> ((SelfResolvingDependency) dependencyFactory.createDependency(DependencyFactory.ClassPathNotation.LOCAL_GROOVY)).resolve());
+ }
+
protected ScriptCompilerFactory createScriptCompileFactory(
FileCacheBackedScriptClassCompiler scriptCompiler,
CrossBuildInMemoryCachingScriptClassCache cache,
@@ -433,14 +461,16 @@ protected FileCacheBackedScriptClassCompiler createFileCacheBackedScriptClassCom
ClassLoaderHierarchyHasher classLoaderHierarchyHasher,
DefaultScriptCompilationHandler scriptCompilationHandler,
CachedClasspathTransformer classpathTransformer,
- ProgressLoggerFactory progressLoggerFactory
+ ProgressLoggerFactory progressLoggerFactory,
+ GroovyScriptClasspathProvider groovyScriptClasspathProvider
) {
return new FileCacheBackedScriptClassCompiler(
cacheRepository,
new BuildOperationBackedScriptCompilationHandler(scriptCompilationHandler, buildOperationExecutor),
progressLoggerFactory,
classLoaderHierarchyHasher,
- classpathTransformer);
+ classpathTransformer,
+ groovyScriptClasspathProvider);
}
protected ScriptPluginFactory createScriptPluginFactory(InstantiatorFactory instantiatorFactory, BuildOperationExecutor buildOperationExecutor, UserCodeApplicationContext userCodeApplicationContext) {
diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java
index 419a26b5fdd84..c068cf075bee6 100644
--- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java
+++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java
@@ -266,6 +266,11 @@ public Dependency gradleApi() {
return dependencyFactory.createDependency(DependencyFactory.ClassPathNotation.GRADLE_API);
}
+ @Override
+ public Dependency gradleApi(String version) {
+ return dependencyFactory.createDependency("org.gradle:gradle-api:" + version);
+ }
+
@Override
public Dependency gradleTestKit() {
return dependencyFactory.createDependency(DependencyFactory.ClassPathNotation.GRADLE_TEST_KIT);
diff --git a/subprojects/kotlin-dsl-plugins/src/main/kotlin/org/gradle/kotlin/dsl/plugins/precompiled/PrecompiledScriptPlugins.kt b/subprojects/kotlin-dsl-plugins/src/main/kotlin/org/gradle/kotlin/dsl/plugins/precompiled/PrecompiledScriptPlugins.kt
index dd3d8fbbf119f..2cc4fc063988c 100644
--- a/subprojects/kotlin-dsl-plugins/src/main/kotlin/org/gradle/kotlin/dsl/plugins/precompiled/PrecompiledScriptPlugins.kt
+++ b/subprojects/kotlin-dsl-plugins/src/main/kotlin/org/gradle/kotlin/dsl/plugins/precompiled/PrecompiledScriptPlugins.kt
@@ -19,6 +19,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.SourceDirectorySet
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.TaskProvider
@@ -44,8 +45,9 @@ class PrecompiledScriptPlugins : Plugin {
dependencies {
"kotlinCompilerPluginClasspath"(gradleKotlinDslJarsOf(project))
- "kotlinCompilerPluginClasspath"(gradleApi())
}
+ GradleApiVersionProvider.addToConfiguration(configurations.getByName("kotlinCompilerPluginClasspath"), dependencies)
+ GradleApiVersionProvider.addGradleSourceApiRepository(repositories)
}
}
diff --git a/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/DefaultPrecompiledScriptPluginsSupport.kt b/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/DefaultPrecompiledScriptPluginsSupport.kt
index 95ead239d8ac3..5bdf4d1f6a4d4 100644
--- a/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/DefaultPrecompiledScriptPluginsSupport.kt
+++ b/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/DefaultPrecompiledScriptPluginsSupport.kt
@@ -23,6 +23,7 @@ import org.gradle.api.file.Directory
import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.initialization.Settings
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
import org.gradle.api.internal.plugins.DefaultPluginManager
import org.gradle.api.invocation.Gradle
import org.gradle.api.model.ObjectFactory
@@ -55,6 +56,7 @@ import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.plugin.devel.GradlePluginDevelopmentExtension
import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
import org.gradle.tooling.model.kotlin.dsl.KotlinDslModelsParameters
+import org.gradle.util.GradleVersion
import java.io.File
import java.util.function.Consumer
import javax.inject.Inject
@@ -230,7 +232,7 @@ fun Project.enableScriptCompilationOf(
val (generatePrecompiledScriptPluginAccessors, _) =
codeGenerationTask(
- "accessors",
+ "accessors${GradleApiVersionProvider.getGradleApiSourceVersion().orElse(GradleVersion.current().baseVersion.version)}",
"generatePrecompiledScriptPluginAccessors",
kotlinSourceDirectorySet
) {
@@ -246,6 +248,9 @@ fun Project.enableScriptCompilationOf(
.map(java.lang.Boolean::parseBoolean)
.orElse(false)
)
+ gradleApiVersion.set(providers
+ .systemProperty(GradleApiVersionProvider.GRADLE_API_SOURCE_VERSION_PROPERTY)
+ .orElse(GradleVersion.current().version))
plugins = scriptPlugins
}
diff --git a/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/tasks/GeneratePrecompiledScriptPluginAccessors.kt b/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/tasks/GeneratePrecompiledScriptPluginAccessors.kt
index c2843b99dc841..4e579e0d5554d 100644
--- a/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/tasks/GeneratePrecompiledScriptPluginAccessors.kt
+++ b/subprojects/kotlin-dsl-provider-plugins/src/main/kotlin/org/gradle/kotlin/dsl/provider/plugins/precompiled/tasks/GeneratePrecompiledScriptPluginAccessors.kt
@@ -122,6 +122,9 @@ abstract class GeneratePrecompiledScriptPluginAccessors @Inject internal constru
@get:Input
abstract val strict: Property
+ @get:Input
+ abstract val gradleApiVersion: Property
+
init {
outputs.doNotCacheIf(
"Generated accessors can only be cached in strict mode."
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragment.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragment.kt
index 586d2c113dc9f..1eac1309fcc28 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragment.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragment.kt
@@ -20,6 +20,7 @@ import kotlinx.metadata.jvm.JvmMethodSignature
import kotlinx.metadata.jvm.KotlinClassMetadata
import org.gradle.internal.classanalysis.AsmConstants.ASM_LEVEL
+import org.gradle.util.GradleVersion
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.ClassWriter
@@ -30,7 +31,8 @@ data class AccessorFragment(
val source: String,
val bytecode: BytecodeWriter,
val metadata: MetadataWriter,
- val signature: JvmMethodSignature
+ val signature: JvmMethodSignature,
+ val supportedSince: GradleVersion? = null
)
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragments.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragments.kt
index ee39ed45b3cbf..54d10ca02417a 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragments.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorFragments.kt
@@ -19,6 +19,7 @@ package org.gradle.kotlin.dsl.accessors
import kotlinx.metadata.KmVariance
import kotlinx.metadata.jvm.JvmMethodSignature
import kotlinx.metadata.jvm.KotlinClassMetadata
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
import org.gradle.api.reflect.TypeOf
import org.gradle.internal.deprecation.ConfigurationDeprecationType
import org.gradle.internal.hash.Hashing.hashString
@@ -49,6 +50,7 @@ import org.gradle.kotlin.dsl.support.bytecode.visitSignature
import org.gradle.kotlin.dsl.support.bytecode.with
import org.gradle.kotlin.dsl.support.bytecode.writeFunctionOf
import org.gradle.kotlin.dsl.support.bytecode.writePropertyOf
+import org.gradle.util.GradleVersion
import org.jetbrains.org.objectweb.asm.MethodVisitor
@@ -71,6 +73,9 @@ fun fragmentsForConfiguration(accessor: Accessor.ForConfiguration): Fragments =
val (functionFlags, deprecationBlock) =
if (config.hasDeclarationDeprecations()) publicFunctionWithAnnotationsFlags to config.getDeclarationDeprecationBlock()
else publicFunctionFlags to ""
+ val sourceApiGradleVersion = GradleVersion.version(
+ GradleApiVersionProvider.getGradleApiSourceVersion().orElse(GradleVersion.current().version)
+ ).baseVersion
className to sequenceOf(
AccessorFragment(
@@ -265,7 +270,8 @@ fun fragmentsForConfiguration(accessor: Accessor.ForConfiguration): Fragments =
signature = JvmMethodSignature(
propertyName,
"(Lorg/gradle/api/artifacts/dsl/DependencyHandler;Lorg/gradle/api/provider/ProviderConvertible;Lorg/gradle/api/Action;)V"
- )
+ ),
+ supportedSince = GradleVersion.version("7.4")
),
AccessorFragment(
source = name.run {
@@ -598,7 +604,7 @@ fun fragmentsForConfiguration(accessor: Accessor.ForConfiguration): Fragments =
""
)
)
- )
+ ).filter { it.supportedSince?.let { it <= sourceApiGradleVersion } ?: true }
}
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorsClassPath.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorsClassPath.kt
index e65978c4bf397..5455166d3818d 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorsClassPath.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/AccessorsClassPath.kt
@@ -17,6 +17,7 @@
package org.gradle.kotlin.dsl.accessors
import org.gradle.api.Project
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
import org.gradle.api.internal.file.FileCollectionFactory
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.tasks.ClasspathNormalizer
@@ -45,6 +46,7 @@ import org.gradle.kotlin.dsl.concurrent.withAsynchronousIO
import org.gradle.kotlin.dsl.support.ClassBytesRepository
import org.gradle.kotlin.dsl.support.appendReproducibleNewLine
import org.gradle.kotlin.dsl.support.useToRun
+import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf.Visibility
import org.jetbrains.kotlin.metadata.deserialization.Flags
@@ -118,6 +120,7 @@ class GenerateProjectAccessors(
const val CLASSPATH_INPUT_PROPERTY = "classpath"
const val SOURCES_OUTPUT_PROPERTY = "sources"
const val CLASSES_OUTPUT_PROPERTY = "classes"
+ const val SOURCE_GRADLE_API_VERSION = "sourceGradleApiVersion"
}
override fun execute(executionRequest: UnitOfWork.ExecutionRequest): UnitOfWork.WorkOutput {
@@ -145,6 +148,7 @@ class GenerateProjectAccessors(
override fun identify(identityInputs: Map, identityFileInputs: Map): UnitOfWork.Identity {
val hasher = Hashing.newHasher()
requireNotNull(identityInputs[PROJECT_SCHEMA_INPUT_PROPERTY]).appendToHasher(hasher)
+ requireNotNull(identityInputs[SOURCE_GRADLE_API_VERSION]).appendToHasher(hasher)
hasher.putHash(requireNotNull(identityFileInputs[CLASSPATH_INPUT_PROPERTY]).hash)
val identityHash = hasher.hash().toString()
return UnitOfWork.Identity { identityHash }
@@ -158,6 +162,7 @@ class GenerateProjectAccessors(
override fun visitIdentityInputs(visitor: InputVisitor) {
visitor.visitInputProperty(PROJECT_SCHEMA_INPUT_PROPERTY) { hashCodeFor(projectSchema) }
+ visitor.visitInputProperty(SOURCE_GRADLE_API_VERSION) { GradleApiVersionProvider.getGradleApiSourceVersion().orElse(GradleVersion.current().version) }
visitor.visitInputFileProperty(
CLASSPATH_INPUT_PROPERTY,
NON_INCREMENTAL,
@@ -601,6 +606,10 @@ fun IO.writeAccessorsTo(
}
}
+val sourceGradleApiVersion
+ get() = GradleApiVersionProvider.getGradleApiSourceVersion().orElse(GradleVersion.current().version)
+val supportsProviderConvertible
+ get() = GradleVersion.version(sourceGradleApiVersion).baseVersion >= GradleVersion.version("7.4")
internal
fun fileHeaderWithImportsFor(accessorsPackage: String = kotlinDslPackageName) = """
@@ -623,7 +632,7 @@ import org.gradle.api.artifacts.dsl.ArtifactHandler
import org.gradle.api.artifacts.dsl.DependencyConstraintHandler
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.provider.Provider
-import org.gradle.api.provider.ProviderConvertible
+${if (supportsProviderConvertible) "import org.gradle.api.provider.ProviderConvertible" else ""}
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/tasks/PrintAccessors.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/tasks/PrintAccessors.kt
index 42e6d33208d15..eed45f169705b 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/tasks/PrintAccessors.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/accessors/tasks/PrintAccessors.kt
@@ -18,6 +18,10 @@ package org.gradle.kotlin.dsl.accessors.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.Project
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.serialization.Cached
@@ -43,6 +47,14 @@ abstract class PrintAccessors : DefaultTask() {
protected
abstract val projectSchemaProvider: ProjectSchemaProvider
+ @get:Input
+ @get:Optional
+ abstract val sourceGradleApiVersion: Property
+
+ init {
+ sourceGradleApiVersion.set(GradleApiVersionProvider.getGradleApiSourceVersion().orElse(null))
+ }
+
private
val schema = Cached.of { schemaOf(project) }
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/BuildServices.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/BuildServices.kt
index e4e0bbcca0186..4c96122b0de2b 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/BuildServices.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/BuildServices.kt
@@ -17,12 +17,17 @@
package org.gradle.kotlin.dsl.provider
import org.gradle.api.internal.ClassPathRegistry
+import org.gradle.api.internal.artifacts.DependencyManagementServices
+import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider
import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory
+import org.gradle.api.internal.artifacts.dsl.dependencies.UnknownProjectFinder
import org.gradle.api.internal.cache.StringInterner
import org.gradle.api.internal.changedetection.state.ResourceSnapshotterCacheService
import org.gradle.api.internal.classpath.ModuleRegistry
import org.gradle.api.internal.file.FileCollectionFactory
+import org.gradle.api.internal.file.FileResolver
import org.gradle.api.internal.file.temp.TemporaryFileProvider
+import org.gradle.api.internal.initialization.RootScriptDomainObjectContext
import org.gradle.api.internal.initialization.loadercache.DefaultClasspathHasher
import org.gradle.cache.internal.GeneratedGradleJarCache
import org.gradle.groovy.scripts.internal.ScriptSourceHasher
@@ -57,6 +62,10 @@ object BuildServices {
classPathRegistry: ClassPathRegistry,
classLoaderScopeRegistry: ClassLoaderScopeRegistry,
dependencyFactory: DependencyFactory,
+ dependencyManagementServices: DependencyManagementServices,
+ fileResolver: FileResolver,
+ fileCollectionFactory: FileCollectionFactory,
+ dependencyMetaDataProvider: DependencyMetaDataProvider,
jarCache: GeneratedGradleJarCache,
temporaryFileProvider: TemporaryFileProvider,
progressLoggerFactory: ProgressLoggerFactory
@@ -66,7 +75,13 @@ object BuildServices {
moduleRegistry,
classPathRegistry,
classLoaderScopeRegistry.coreAndPluginsScope,
- gradleApiJarsProviderFor(dependencyFactory),
+ gradleApiJarsProviderFor(dependencyManagementServices.create(
+ fileResolver,
+ fileCollectionFactory,
+ dependencyMetaDataProvider,
+ UnknownProjectFinder("Some unknown project"),
+ RootScriptDomainObjectContext.PLUGINS
+ )),
versionedJarCacheFor(jarCache),
temporaryFileProvider,
StandardJarGenerationProgressMonitorProvider(progressLoggerFactory)
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/KotlinScriptClassPathProvider.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/KotlinScriptClassPathProvider.kt
index 3930326540098..9f81a9b61e13c 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/KotlinScriptClassPathProvider.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/provider/KotlinScriptClassPathProvider.kt
@@ -16,40 +16,32 @@
package org.gradle.kotlin.dsl.provider
+import com.google.common.annotations.VisibleForTesting
import org.gradle.api.Project
-
-import org.gradle.api.artifacts.Dependency
-import org.gradle.api.artifacts.SelfResolvingDependency
import org.gradle.api.file.FileCollection
-
import org.gradle.api.internal.ClassPathRegistry
+import org.gradle.api.internal.artifacts.DependencyResolutionServices
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider
import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory
import org.gradle.api.internal.classpath.ModuleRegistry
import org.gradle.api.internal.file.FileCollectionFactory
+import org.gradle.api.internal.file.temp.TemporaryFileProvider
import org.gradle.api.internal.initialization.ClassLoaderScope
-
import org.gradle.internal.classloader.ClassLoaderVisitor
import org.gradle.internal.classpath.ClassPath
import org.gradle.internal.classpath.DefaultClassPath
-
+import org.gradle.kotlin.dsl.*
import org.gradle.kotlin.dsl.codegen.generateApiExtensionsJar
+import org.gradle.kotlin.dsl.support.ProgressMonitor
import org.gradle.kotlin.dsl.support.gradleApiMetadataModuleName
import org.gradle.kotlin.dsl.support.isGradleKotlinDslJar
import org.gradle.kotlin.dsl.support.isGradleKotlinDslJarName
-import org.gradle.kotlin.dsl.support.ProgressMonitor
import org.gradle.kotlin.dsl.support.serviceOf
-
import org.gradle.util.internal.GFileUtils.moveFile
-
-import com.google.common.annotations.VisibleForTesting
-import org.gradle.api.internal.file.temp.TemporaryFileProvider
-
import java.io.File
-
import java.net.URI
import java.net.URISyntaxException
import java.net.URL
-
import java.util.concurrent.ConcurrentHashMap
@@ -213,13 +205,10 @@ class KotlinScriptClassPathProvider(
internal
-fun gradleApiJarsProviderFor(dependencyFactory: DependencyFactory): JarsProvider =
- { (dependencyFactory.gradleApi() as SelfResolvingDependency).resolve() }
-
-
-private
-fun DependencyFactory.gradleApi(): Dependency =
- createDependency(gradleApiNotation)
+fun gradleApiJarsProviderFor(dependencyResolutionServices: DependencyResolutionServices): JarsProvider =
+ {
+ GradleApiVersionProvider.resolveGradleSourceApi(dependencyResolutionServices)
+ }
private
diff --git a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/support/delegates/DependencyHandlerDelegate.kt b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/support/delegates/DependencyHandlerDelegate.kt
index 298413c7ada34..753b9467f3c20 100644
--- a/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/support/delegates/DependencyHandlerDelegate.kt
+++ b/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/support/delegates/DependencyHandlerDelegate.kt
@@ -87,6 +87,9 @@ abstract class DependencyHandlerDelegate : DependencyHandler {
override fun gradleApi(): Dependency =
delegate.gradleApi()
+ override fun gradleApi(version: String): Dependency =
+ delegate.gradleApi(version)
+
override fun gradleTestKit(): Dependency =
delegate.gradleTestKit()
diff --git a/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java b/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java
index a4308dd74c513..334eb6ecc97ca 100644
--- a/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java
+++ b/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java
@@ -29,6 +29,7 @@
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider;
import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactory;
import org.gradle.api.internal.artifacts.ivyservice.projectmodule.ProjectPublicationRegistry;
import org.gradle.api.internal.plugins.PluginDescriptor;
@@ -152,7 +153,8 @@ private void registerPlugins(Project project, GradlePluginDevelopmentExtension e
private void applyDependencies(Project project) {
DependencyHandler dependencies = project.getDependencies();
- dependencies.add(API_CONFIGURATION, dependencies.gradleApi());
+ GradleApiVersionProvider.addToConfiguration(project.getConfigurations().getByName(API_CONFIGURATION), dependencies);
+ GradleApiVersionProvider.addGradleSourceApiRepository(project.getRepositories());
}
private void configureJarTask(Project project, GradlePluginDevelopmentExtension extension) {
diff --git a/subprojects/plugins/src/main/java/org/gradle/initialization/buildsrc/GroovyBuildSrcProjectConfigurationAction.java b/subprojects/plugins/src/main/java/org/gradle/initialization/buildsrc/GroovyBuildSrcProjectConfigurationAction.java
index c095c3c25498e..23babaf39ee61 100644
--- a/subprojects/plugins/src/main/java/org/gradle/initialization/buildsrc/GroovyBuildSrcProjectConfigurationAction.java
+++ b/subprojects/plugins/src/main/java/org/gradle/initialization/buildsrc/GroovyBuildSrcProjectConfigurationAction.java
@@ -17,6 +17,7 @@
package org.gradle.initialization.buildsrc;
import org.gradle.api.artifacts.dsl.DependencyHandler;
+import org.gradle.api.internal.artifacts.GradleApiVersionProvider;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.api.plugins.GroovyPlugin;
import org.gradle.api.plugins.JavaLibraryPlugin;
@@ -30,7 +31,8 @@ public void execute(ProjectInternal project) {
project.getPluginManager().apply(GroovyPlugin.class);
DependencyHandler dependencies = project.getDependencies();
- dependencies.add(JavaPlugin.API_CONFIGURATION_NAME, dependencies.gradleApi());
+ GradleApiVersionProvider.addToConfiguration(project.getConfigurations().getByName(JavaPlugin.API_CONFIGURATION_NAME), dependencies);
+ GradleApiVersionProvider.addGradleSourceApiRepository(project.getRepositories());
dependencies.add(JavaPlugin.API_CONFIGURATION_NAME, dependencies.localGroovy());
}
}