From 3e60f258774b82b7c20ae9cd6e995690bca85a92 Mon Sep 17 00:00:00 2001 From: Louis Jacomet Date: Fri, 21 Feb 2020 20:09:05 +0100 Subject: [PATCH] Revert "Duplicate project name detection" This reverts commits 404c6cf303d to ffb51fb92f1 and commit a0a662cbe49019adb08f996ae3df5a23aa222bbe. Fixes #12315 --- ...BuildDependencyGraphIntegrationTest.groovy | 37 ++- .../DefaultProjectModuleFactory.java | 189 ------------ .../artifacts/ProjectBackedModule.java | 61 +++- .../artifacts/ProjectModuleFactory.java | 22 -- .../service/scopes/BuildScopeServices.java | 6 - .../service/scopes/ProjectScopeServices.java | 14 +- .../artifacts/ProjectBackedModuleTest.groovy | 6 +- .../project/DefaultProjectTest.groovy | 8 +- ...ectDependencyResolveIntegrationTest.groovy | 80 ----- ...faultComponentIdentifierFactoryTest.groovy | 9 +- .../OutgoingVariantsReportTask.java | 21 +- .../IvyPublishMultiProjectIntegTest.groovy | 282 ----------------- .../DefaultIvyPublicationIdentity.java | 82 +---- .../publish/ivy/plugins/IvyPublishPlugin.java | 4 +- .../MavenPublishMultiProjectIntegTest.groovy | 289 +----------------- .../maven/plugins/MavenPublishPlugin.java | 90 +----- 16 files changed, 122 insertions(+), 1078 deletions(-) delete mode 100644 subprojects/core/src/main/java/org/gradle/api/internal/artifacts/DefaultProjectModuleFactory.java delete mode 100644 subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectModuleFactory.java diff --git a/subprojects/composite-builds/src/integTest/groovy/org/gradle/integtests/composite/CompositeBuildDependencyGraphIntegrationTest.groovy b/subprojects/composite-builds/src/integTest/groovy/org/gradle/integtests/composite/CompositeBuildDependencyGraphIntegrationTest.groovy index d049efc8be5d..be49110ef9f1 100644 --- a/subprojects/composite-builds/src/integTest/groovy/org/gradle/integtests/composite/CompositeBuildDependencyGraphIntegrationTest.groovy +++ b/subprojects/composite-builds/src/integTest/groovy/org/gradle/integtests/composite/CompositeBuildDependencyGraphIntegrationTest.groovy @@ -606,6 +606,33 @@ afterEvaluate { failure.assertHasCause("Module version 'org.test:b1:1.0' is not unique in composite: can be provided by [project :buildB:b1, project :buildC:b1].") } + def "reports failure to resolve dependencies when substitution is ambiguous within single participant"() { + given: + buildB + def buildC = multiProjectBuild("buildC", ['c1', 'c2']); + buildC.settingsFile << """ + include ':nested:c1' +""" + buildC.buildFile << """ + allprojects { + apply plugin: 'java' + } +""" + includedBuilds << buildC + + buildA.buildFile << """ + dependencies { + implementation "org.test:c1:1.0" + } +""" + + when: + checkDependenciesFails() + + then: + failure.assertHasCause("Module version 'org.test:c1:1.0' is not unique in composite: can be provided by [project :buildC:c1, project :buildC:nested:c1].") + } + def "reports failure to resolve dependencies when transitive dependency substitution is ambiguous"() { given: transitiveDependencyIsAmbiguous("'org.test:b1:2.0'") @@ -720,22 +747,22 @@ afterEvaluate { maven { url '$mavenRepo.uri' } } - configurations { - buildInputs + configurations { + buildInputs create('default') } - + dependencies { buildInputs "org.test:test:1.2" } - + task buildOutputs { inputs.files configurations.buildInputs doLast { configurations.buildInputs.each { } } } - + artifacts { "default" file: file("out.jar"), builtBy: buildOutputs } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/DefaultProjectModuleFactory.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/DefaultProjectModuleFactory.java deleted file mode 100644 index af389bfdff43..000000000000 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/DefaultProjectModuleFactory.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2020 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 com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.gradle.api.Project; -import org.gradle.api.internal.project.ProjectIdentifier; -import org.gradle.api.internal.project.ProjectRegistry; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class DefaultProjectModuleFactory implements ProjectModuleFactory { - public static final String DUPLICATE_DETECTION_SYSPROP = "org.gradle.dependency.duplicate.project.detection"; - - private static final Splitter SPLITTER = Splitter.on(':') - .omitEmptyStrings(); - - private final Map projectToModule = Maps.newConcurrentMap(); - private final Set projectsWithSameName; - private final boolean detectDuplicates; - - public static boolean isDuplicateDetectionEnabled() { - return Boolean.parseBoolean(System.getProperty(DUPLICATE_DETECTION_SYSPROP, "true")); - } - - public DefaultProjectModuleFactory(ProjectRegistry registry) { - Map uniqueNames = registry.getAllProjects().stream() - .map(ProjectIdentifier::getName) - .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - ImmutableSet.Builder builder = new ImmutableSet.Builder<>(); - uniqueNames.entrySet() - .stream() - .filter(e -> e.getValue() > 1) - .map(Map.Entry::getKey) - .forEach(builder::add); - projectsWithSameName = builder.build(); - detectDuplicates = isDuplicateDetectionEnabled(); - } - - private List findDuplicates(Project project) { - Set projects = project.getRootProject().getAllprojects(); - String current = toGroupAndArtifact(project); - List duplicates = null; - for (Project projectIdentifier : projects) { - if (project != projectIdentifier) { - String ga = toGroupAndArtifact(projectIdentifier); - if (current.equals(ga)) { - if (duplicates == null) { - duplicates = Lists.newArrayList(); - } - duplicates.add(projectIdentifier); - } - } - } - return duplicates == null ? Collections.emptyList() : duplicates; - } - - private static String toGroupAndArtifact(Project projectIdentifier) { - return projectIdentifier.getGroup() + ":" + projectIdentifier.getName(); - } - - @Override - public Module getModule(Project project) { - return projectToModule.computeIfAbsent(project, this::createId); - } - - private Module createId(Project project) { - return new DynamicDeduplicatingModuleProjectIdentifier(project); - } - - private abstract class AbstractProjectBackedModule implements ProjectBackedModule { - - private final Project project; - - @Override - public Project getProject() { - return project; - } - - public AbstractProjectBackedModule(Project project) { - this.project = project; - } - - @Override - public List getProjectsWithSameCoordinates() { - List ids = findDuplicates(project); - if (ids.isEmpty()) { - return Collections.emptyList(); - } - return ids.stream() - .filter(id -> id != project) - .collect(Collectors.toList()); - } - - @Override - public String getGroup() { - return String.valueOf(project.getGroup()); - } - - @Override - public String getVersion() { - return project.getVersion().toString(); - } - - @Override - public String getStatus() { - return project.getStatus().toString(); - } - - @Override - public String getProjectPath() { - return project.getPath(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AbstractProjectBackedModule that = (AbstractProjectBackedModule) o; - - if (!project.equals(that.project)) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return project.hashCode(); - } - } - - private class DynamicDeduplicatingModuleProjectIdentifier extends AbstractProjectBackedModule { - private final Project project; - private volatile String lazyName; - - private DynamicDeduplicatingModuleProjectIdentifier(Project project) { - super(project); - this.project = project; - } - - @Override - public String getName() { - if (lazyName == null) { - computeName(); - } - return lazyName; - } - - private void computeName() { - String name = project.getName(); - if (detectDuplicates && projectsWithSameName.contains(name)) { - List strings = SPLITTER.splitToList(project.getPath()); - if (strings.size() > 1) { - lazyName = String.join("-", strings.subList(0, strings.size() - 1)) + "-" + name; - return; - } - } - lazyName = name; - } - } -} diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectBackedModule.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectBackedModule.java index 871d53e9a879..555503b38b58 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectBackedModule.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectBackedModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2012 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. @@ -13,13 +13,64 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.gradle.api.internal.artifacts; import org.gradle.api.Project; -import java.util.List; +public class ProjectBackedModule implements Module { + + private final Project project; + + public ProjectBackedModule(Project project) { + this.project = project; + } + + @Override + public String getGroup() { + return project.getGroup().toString(); + } + + @Override + public String getName() { + return project.getName(); + } + + @Override + public String getVersion() { + return project.getVersion().toString(); + } + + @Override + public String getStatus() { + return project.getStatus().toString(); + } + + @Override + public String getProjectPath() { + return project.getPath(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ProjectBackedModule that = (ProjectBackedModule) o; + + if (project != null ? !project.equals(that.project) : that.project != null) { + return false; + } + + return true; + } -public interface ProjectBackedModule extends Module { - Project getProject(); - List getProjectsWithSameCoordinates(); + @Override + public int hashCode() { + return project != null ? project.hashCode() : 0; + } } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectModuleFactory.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectModuleFactory.java deleted file mode 100644 index c4e1765f361e..000000000000 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/ProjectModuleFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 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.Project; - -public interface ProjectModuleFactory { - Module getModule(Project project); -} 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 57eee9382348..6a2c718be17e 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 @@ -26,10 +26,8 @@ import org.gradle.api.internal.DocumentationRegistry; import org.gradle.api.internal.StartParameterInternal; import org.gradle.api.internal.artifacts.DefaultModule; -import org.gradle.api.internal.artifacts.DefaultProjectModuleFactory; import org.gradle.api.internal.artifacts.DependencyManagementServices; import org.gradle.api.internal.artifacts.Module; -import org.gradle.api.internal.artifacts.ProjectModuleFactory; import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider; import org.gradle.api.internal.classpath.ModuleRegistry; import org.gradle.api.internal.classpath.PluginModuleRegistry; @@ -587,8 +585,4 @@ protected BuildScanUserInputHandler createBuildScanUserInputHandler(UserInputHan protected BuildInvocationDetails createBuildInvocationDetails(BuildStartedTime buildStartedTime) { return new DefaultBuildInvocationDetails(buildStartedTime); } - - protected ProjectModuleFactory createProjectModuleIdentifierFactory(DefaultProjectRegistry projectRegistry) { - return new DefaultProjectModuleFactory(projectRegistry); - } } diff --git a/subprojects/core/src/main/java/org/gradle/internal/service/scopes/ProjectScopeServices.java b/subprojects/core/src/main/java/org/gradle/internal/service/scopes/ProjectScopeServices.java index 277b53428d1b..fa86354f5a3d 100644 --- a/subprojects/core/src/main/java/org/gradle/internal/service/scopes/ProjectScopeServices.java +++ b/subprojects/core/src/main/java/org/gradle/internal/service/scopes/ProjectScopeServices.java @@ -23,7 +23,7 @@ import org.gradle.api.internal.MutationGuards; import org.gradle.api.internal.artifacts.DependencyManagementServices; import org.gradle.api.internal.artifacts.Module; -import org.gradle.api.internal.artifacts.ProjectModuleFactory; +import org.gradle.api.internal.artifacts.ProjectBackedModule; import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider; import org.gradle.api.internal.artifacts.dsl.dependencies.ProjectFinder; import org.gradle.api.internal.collections.DefaultDomainObjectCollectionFactory; @@ -263,8 +263,8 @@ public boolean isScript() { } } - protected DependencyMetaDataProvider createDependencyMetaDataProvider(ProjectModuleFactory projectModuleIdentifierFactory) { - return new ProjectBackedModuleMetaDataProvider(projectModuleIdentifierFactory); + protected DependencyMetaDataProvider createDependencyMetaDataProvider() { + return new ProjectBackedModuleMetaDataProvider(); } protected ServiceRegistryFactory createServiceRegistryFactory(final ServiceRegistry services) { @@ -282,15 +282,9 @@ protected TypeConverter createTypeConverter(PathToFileResolver fileResolver) { } private class ProjectBackedModuleMetaDataProvider implements DependencyMetaDataProvider { - private final ProjectModuleFactory projectModuleIdentifierFactory; - - public ProjectBackedModuleMetaDataProvider(ProjectModuleFactory projectModuleIdentifierFactory) { - this.projectModuleIdentifierFactory = projectModuleIdentifierFactory; - } - @Override public Module getModule() { - return projectModuleIdentifierFactory.getModule(project); + return new ProjectBackedModule(project); } } diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/artifacts/ProjectBackedModuleTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/artifacts/ProjectBackedModuleTest.groovy index 74304954849d..a893554f5b3e 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/artifacts/ProjectBackedModuleTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/artifacts/ProjectBackedModuleTest.groovy @@ -16,17 +16,13 @@ package org.gradle.api.internal.artifacts -import org.gradle.api.internal.project.ProjectRegistry import org.gradle.test.fixtures.AbstractProjectBuilderSpec class ProjectBackedModuleTest extends AbstractProjectBuilderSpec { - ProjectModuleFactory factory = new DefaultProjectModuleFactory(Mock(ProjectRegistry) { - getAllProjects() >> [] - }) def "module exposes project properties"() { given: - def module = factory.getModule(project) + def module = new ProjectBackedModule(project) expect: module.name == project.name diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy index e5a075ba6f5c..f0d2662c9476 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy @@ -39,9 +39,8 @@ import org.gradle.api.internal.CollectionCallbackActionDecorator import org.gradle.api.internal.FactoryNamedDomainObjectContainer import org.gradle.api.internal.GradleInternal import org.gradle.api.internal.ProcessOperations -import org.gradle.api.internal.artifacts.DefaultProjectModuleFactory import org.gradle.api.internal.artifacts.Module -import org.gradle.api.internal.artifacts.ProjectModuleFactory +import org.gradle.api.internal.artifacts.ProjectBackedModule import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider import org.gradle.api.internal.collections.DomainObjectCollectionFactory import org.gradle.api.internal.file.DefaultProjectLayout @@ -155,9 +154,6 @@ class DefaultProjectTest extends Specification { CrossProjectConfigurator crossProjectConfigurator = new BuildOperationCrossProjectConfigurator(buildOperationExecutor) ClassLoaderScope baseClassLoaderScope = new RootClassLoaderScope("root", getClass().classLoader, getClass().classLoader, new DummyClassLoaderCache(), Stub(ClassLoaderScopeRegistryListener)) ClassLoaderScope rootProjectClassLoaderScope = baseClassLoaderScope.createChild("root-project") - ProjectModuleFactory moduleFactory = new DefaultProjectModuleFactory(Mock(ProjectRegistry) { - getAllProjects() >> [] - }) def setup() { rootDir = new File("/path/root").absoluteFile @@ -957,7 +953,7 @@ def scriptMethod(Closure closure) { def getModule() { when: - Module moduleDummyResolve = moduleFactory.getModule(project) + Module moduleDummyResolve = new ProjectBackedModule(project) dependencyMetaDataProviderMock.getModule() >> moduleDummyResolve then: project.getModule() == moduleDummyResolve diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ProjectDependencyResolveIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ProjectDependencyResolveIntegrationTest.groovy index 8d757efaf678..3872eab6a15a 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ProjectDependencyResolveIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ProjectDependencyResolveIntegrationTest.groovy @@ -16,7 +16,6 @@ package org.gradle.integtests.resolve import groovy.transform.NotYetImplemented -import org.gradle.api.JavaVersion import org.gradle.integtests.fixtures.AbstractIntegrationSpec import org.gradle.integtests.fixtures.FluidDependenciesResolveRunner import org.gradle.integtests.fixtures.resolve.ResolveTestFixture @@ -670,83 +669,4 @@ project(':b') { executedAndNotSkipped ":a:A1jar", ":a:A2jar", ":a:A3jar" } - @Issue("https://github.com/gradle/gradle/issues/847") - def "projects with the same name should be considered different when building the graph"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - group 'org.test' - version '1.0' - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - } - """ - - def resolve = new ResolveTestFixture(buildFile, "compileClasspath") - resolve.prepare() - - when: - succeeds 'a:core:checkDeps' - - then: - resolve.expectGraph { - root(":a:core", "org.test:a-core:1.0") { - project(":b:core", "org.test:b-core:1.0") { - variant("apiElements", [ - 'org.gradle.category': 'library', - 'org.gradle.dependency.bundling': 'external', - 'org.gradle.jvm.version': JavaVersion.current().majorVersion, - 'org.gradle.usage': 'java-api', - 'org.gradle.libraryelements': 'jar']) - artifact(name: 'main', noType: true) - } - } - } - } - - @Issue("https://github.com/gradle/gradle/issues/847") - def "can opt-out detection of circular dependencies with projects of same name"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - group 'org.test' - version '1.0' - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - } - """ - - def resolve = new ResolveTestFixture(buildFile, "compileClasspath") - resolve.prepare() - - when: - fails 'a:core:checkDeps', '-Dorg.gradle.dependency.duplicate.project.detection=false' - - then: - failure.assertHasDescription """Circular dependency between the following tasks: -:a:core:compileJava -\\--- :a:core:compileJava (*)""" - } } diff --git a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/component/DefaultComponentIdentifierFactoryTest.groovy b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/component/DefaultComponentIdentifierFactoryTest.groovy index ac267f67d523..f944b6bfb1db 100644 --- a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/component/DefaultComponentIdentifierFactoryTest.groovy +++ b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/component/DefaultComponentIdentifierFactoryTest.groovy @@ -21,11 +21,9 @@ import org.gradle.api.internal.artifacts.DefaultBuildIdentifier import org.gradle.api.internal.artifacts.DefaultModule import org.gradle.api.internal.artifacts.DefaultModuleIdentifier import org.gradle.api.internal.artifacts.DefaultProjectComponentIdentifier -import org.gradle.api.internal.artifacts.DefaultProjectModuleFactory -import org.gradle.api.internal.artifacts.ProjectModuleFactory +import org.gradle.api.internal.artifacts.ProjectBackedModule import org.gradle.api.internal.attributes.ImmutableAttributes import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.internal.project.ProjectRegistry import org.gradle.internal.build.BuildState import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier import org.gradle.internal.component.local.model.DefaultProjectComponentSelector @@ -35,15 +33,12 @@ import spock.lang.Specification class DefaultComponentIdentifierFactoryTest extends Specification { def buildIdentity = Mock(BuildState) def componentIdentifierFactory = new DefaultComponentIdentifierFactory(buildIdentity) - ProjectModuleFactory moduleFactory = new DefaultProjectModuleFactory(Mock(ProjectRegistry) { - getAllProjects() >> [] - }) def "can create project component identifier"() { given: def project = Mock(ProjectInternal) def expectedId = Stub(ProjectComponentIdentifier) - def module = moduleFactory.getModule(project) + def module = new ProjectBackedModule(project) when: def componentIdentifier = componentIdentifierFactory.createComponentIdentifier(module) diff --git a/subprojects/diagnostics/src/main/java/org/gradle/api/tasks/diagnostics/OutgoingVariantsReportTask.java b/subprojects/diagnostics/src/main/java/org/gradle/api/tasks/diagnostics/OutgoingVariantsReportTask.java index bae911cb5184..e5a652857f91 100644 --- a/subprojects/diagnostics/src/main/java/org/gradle/api/tasks/diagnostics/OutgoingVariantsReportTask.java +++ b/subprojects/diagnostics/src/main/java/org/gradle/api/tasks/diagnostics/OutgoingVariantsReportTask.java @@ -26,12 +26,10 @@ import org.gradle.api.attributes.Attribute; import org.gradle.api.attributes.AttributeContainer; import org.gradle.api.capabilities.Capability; -import org.gradle.api.internal.artifacts.Module; -import org.gradle.api.internal.artifacts.ProjectModuleFactory; +import org.gradle.api.internal.artifacts.ProjectBackedModule; import org.gradle.api.internal.artifacts.configurations.ConfigurationInternal; import org.gradle.api.internal.attributes.AttributeContainerInternal; import org.gradle.api.internal.file.FileResolver; -import org.gradle.api.internal.project.ProjectInternal; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Optional; @@ -94,21 +92,12 @@ void buildReport() { reportNoMatchingVariant(configurations, output); } else { Legend legend = new Legend(); - ProjectModuleFactory factory = getProjectModuleFactory(); - Module projectBackedModule = factory.getModule(getProject()); - configurations.forEach(cnf -> { - reportVariant((ConfigurationInternal) cnf, projectBackedModule, output, legend); - }); + configurations.forEach(cnf -> reportVariant((ConfigurationInternal) cnf, new ProjectBackedModule(getProject()), output, legend)); legend.print(output); } } - // private and using internal API to avoid binary compatibility breakage - private ProjectModuleFactory getProjectModuleFactory() { - return ((ProjectInternal)getProject()).getServices().get(ProjectModuleFactory.class); - } - - private void reportVariant(ConfigurationInternal cnf, Module projectBackedModule, StyledTextOutput output, Legend legend) { + private void reportVariant(ConfigurationInternal cnf, ProjectBackedModule projectBackedModule, StyledTextOutput output, Legend legend) { // makes sure the configuration is complete before reporting cnf.preventFromFurtherMutation(); Formatter tree = new Formatter(output); @@ -196,7 +185,7 @@ private boolean formatAttributes(AttributeContainer attributes, Formatter tree) return false; } - private void formatCapabilities(Collection capabilities, Module projectBackedModule, Formatter tree) { + private void formatCapabilities(Collection capabilities, ProjectBackedModule projectBackedModule, Formatter tree) { tree.section("Capabilities", () -> { if (capabilities.isEmpty()) { tree.text(String.format("%s:%s:%s (default capability)", projectBackedModule.getGroup(), projectBackedModule.getName(), projectBackedModule.getVersion())); @@ -206,7 +195,7 @@ private void formatCapabilities(Collection capabilities, M }); } - private boolean formatAttributesAndCapabilities(ConfigurationInternal configuration, Module projectBackedModule, Formatter tree) { + private boolean formatAttributesAndCapabilities(ConfigurationInternal configuration, ProjectBackedModule projectBackedModule, Formatter tree) { AttributeContainerInternal attributes = configuration.getAttributes(); if (!attributes.isEmpty()) { Collection capabilities = configuration.getOutgoing().getCapabilities(); diff --git a/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishMultiProjectIntegTest.groovy b/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishMultiProjectIntegTest.groovy index 72206b9230e6..2496013c9c99 100644 --- a/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishMultiProjectIntegTest.groovy +++ b/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishMultiProjectIntegTest.groovy @@ -17,7 +17,6 @@ package org.gradle.api.publish.ivy import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution -import spock.lang.Issue class IvyPublishMultiProjectIntegTest extends AbstractIvyPublishIntegTest { def project1 = javaLibrary(ivyRepo.module("org.gradle.test", "project1", "1.0")) @@ -342,285 +341,4 @@ project(":project2") { $append """ } - - @Issue("https://github.com/gradle/gradle/issues/847") - def "fails publishing projects which share the same GAV coordinates"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'ivy-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - ivy { url "${ivyRepo.uri}" } - } - publications { - ivy(IvyPublication) { - from components.java - } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - } - """ - - when: - fails 'publishIvyPublicationToIvyRepo' - - then: - failure.assertHasCause "Project :b:core has the same (organisation, module name) as :a:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "fails publishing projects if they share the same GAV coordinates unless detection is disabled"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'ivy-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - ivy { url "${ivyRepo.uri}" } - } - publications { - ivy(IvyPublication) { - from components.java - } - } - } - } - - """ - - when: - succeeds 'publishIvyPublicationToIvyRepo', '-Dorg.gradle.dependency.duplicate.project.detection=false' - def project1 = javaLibrary(ivyRepo.module("org.gradle.test", "core", "1.0")) - - then: - // this tests the current behavior, which is obviously wrong here as the user - // didn't overwrite the publication coordinates - project1.assertPublishedAsJavaModule() - project1.parsedIvy.module == 'core' - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "can avoid publishing warning with projects with the same name by setting an explicit artifact id"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'ivy-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - ivy { url "${ivyRepo.uri}" } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - publishing.publications { - ivy(IvyPublication) { - organisation = 'org.gradle.test' - module = 'some-a' - from components.java - } - } - } - - project(':b:core') { - publishing.publications { - ivy(IvyPublication) { - organisation = 'org.gradle.test' - module = 'some-b' - from components.java - } - } - } - """ - - when: - succeeds 'publishIvyPublicationToIvyRepo' - def project1 = javaLibrary(ivyRepo.module("org.gradle.test", "some-a", "1.0")) - def project2 = javaLibrary(ivyRepo.module("org.gradle.test", "some-b", "1.0")) - - then: - project1.assertPublishedAsJavaModule() - project2.assertPublishedAsJavaModule() - - project1.parsedIvy.module == 'some-a' - project2.parsedIvy.module == 'some-b' - - project1.parsedIvy.assertConfigurationDependsOn("runtime", "org.gradle.test:some-b:1.0") - - project1.parsedModuleMetadata.component.module == 'some-a' - project2.parsedModuleMetadata.component.module == 'some-b' - - project1.parsedModuleMetadata.variant("runtimeElements") { - dependency("org.gradle.test", "some-b", "1.0") - noMoreDependencies() - } - - and: - outputDoesNotContain "Project :a:core has the same (organisation, module name) as :b:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - outputDoesNotContain "Project :b:core has the same (organisation, module name) as :a:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "can avoid publishing warning with projects with the same name by setting an explicit group id"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'ivy-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - ivy { url "${ivyRepo.uri}" } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - publishing.publications { - ivy(IvyPublication) { - organisation = 'org.gradle.test2' - module = 'core' - from components.java - } - } - } - - project(':b:core') { - publishing.publications { - ivy(IvyPublication) { - organisation = 'org.gradle.test' - module = 'core' - from components.java - } - } - } - """ - - when: - succeeds 'publishIvyPublicationToIvyRepo' - def project1 = javaLibrary(ivyRepo.module("org.gradle.test2", "core", "1.0")) - def project2 = javaLibrary(ivyRepo.module("org.gradle.test", "core", "1.0")) - - then: - project1.assertPublishedAsJavaModule() - project2.assertPublishedAsJavaModule() - - project1.parsedIvy.organisation == 'org.gradle.test2' - project2.parsedIvy.organisation == 'org.gradle.test' - - project1.parsedIvy.assertConfigurationDependsOn("runtime", "org.gradle.test:core:1.0") - - project1.parsedModuleMetadata.component.group == 'org.gradle.test2' - project2.parsedModuleMetadata.component.group == 'org.gradle.test' - - project1.parsedModuleMetadata.variant("runtimeElements") { - dependency("org.gradle.test", "core", "1.0") - noMoreDependencies() - } - - and: - outputDoesNotContain "Project :a:core has the same (organisation, module name) as :b:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - outputDoesNotContain "Project :b:core has the same (organisation, module name) as :a:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/12281") - def "shouldn't change publication coordinates if GAV are different"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include(':a:module') - project(':a:module').projectDir = file('module1') - include(':b:module') - project(':b:module').projectDir = file('module2') - include(':c:module') - project(':c:module').projectDir = file('module3') - """ - - buildFile << """ - subprojects { - apply plugin: 'java' - apply plugin: 'ivy-publish' - - publishing { - repositories { - ivy { url "${ivyRepo.uri}" } - } - publications { - ivy(IvyPublication) { - version = '1.1' - from components.java - } - } - } -}""" - - file("module1/build.gradle") << "group = 'the.group'" - file("module2/build.gradle") << "group = 'the.group'" - file("module3/build.gradle") << "group = 'the.other.group'" - - when: - succeeds ':c:module:publishIvyPublicationToIvyRepo' - def module = javaLibrary(ivyRepo.module("the.other.group", "module", "1.1")) - - then: - module.assertPublishedAsJavaModule() - module.parsedIvy.organisation == 'the.other.group' - module.parsedModuleMetadata.component.group == 'the.other.group' - } } diff --git a/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publication/DefaultIvyPublicationIdentity.java b/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publication/DefaultIvyPublicationIdentity.java index 312d93a98508..ed46257a3626 100644 --- a/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publication/DefaultIvyPublicationIdentity.java +++ b/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publication/DefaultIvyPublicationIdentity.java @@ -16,18 +16,9 @@ package org.gradle.api.publish.ivy.internal.publication; -import org.gradle.api.InvalidUserCodeException; -import org.gradle.api.Project; -import org.gradle.api.internal.artifacts.DefaultProjectModuleFactory; import org.gradle.api.internal.artifacts.Module; -import org.gradle.api.internal.artifacts.ProjectBackedModule; import org.gradle.api.publish.ivy.internal.publisher.IvyPublicationIdentity; -import javax.annotation.Nullable; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; - public class DefaultIvyPublicationIdentity implements IvyPublicationIdentity { private Module delegate; private String organisation; @@ -35,7 +26,7 @@ public class DefaultIvyPublicationIdentity implements IvyPublicationIdentity { private String revision; public DefaultIvyPublicationIdentity(Module delegate) { - this.delegate = safeProjectCoordinatesProvider(delegate); + this.delegate = delegate; } public DefaultIvyPublicationIdentity(String organisation, String module, String revision) { @@ -73,75 +64,4 @@ public String getRevision() { public void setRevision(String revision) { this.revision = revision; } - - private Module safeProjectCoordinatesProvider(Module module) { - if (module instanceof ProjectBackedModule) { - return new LazyProjectModuleProvider((ProjectBackedModule) module); - } - return module; - } - - private static final class LazyProjectModuleProvider implements Module { - private final ProjectBackedModule projectBackedModule; - private final AtomicBoolean warned = new AtomicBoolean(); - private final AtomicBoolean hasDuplicates = new AtomicBoolean(); - - private LazyProjectModuleProvider(ProjectBackedModule module) { - this.projectBackedModule = module; - } - - @Nullable - @Override - public String getProjectPath() { - return projectBackedModule.getProjectPath(); - } - - @Override - public String getGroup() { - maybeWarnAboutDuplicates(); - return projectBackedModule.getGroup(); - } - - @Override - public String getName() { - maybeWarnAboutDuplicates(); - if (hasDuplicates.get()) { - return projectBackedModule.getName(); - } else { - // the project name is used for publication, even if internally - // for dependency resolution we use the "de-duplicated" name - return projectBackedModule.getProject().getName(); - } - } - - @Override - public String getVersion() { - return projectBackedModule.getVersion(); - } - - @Override - public String getStatus() { - return projectBackedModule.getStatus(); - } - - private void maybeWarnAboutDuplicates() { - if (!warned.getAndSet(true)) { - Project project = projectBackedModule.getProject(); - List projectsWithSameId = projectBackedModule.getProjectsWithSameCoordinates(); - boolean duplicates = !projectsWithSameId.isEmpty() && DefaultProjectModuleFactory.isDuplicateDetectionEnabled(); - hasDuplicates.set(duplicates); - if (duplicates) { - StringBuilder sb = new StringBuilder(); - sb.append("Project ") - .append(project.getPath()) - .append(" has the same (organisation, module name) as ") - .append(projectsWithSameId.stream().map(Project::getPath).collect(Collectors.joining(" and "))) - .append(". You should set both the organisation and module name of the publication") - .append(" or opt out by adding the " + DefaultProjectModuleFactory.DUPLICATE_DETECTION_SYSPROP + " system property to 'false'."); - throw new InvalidUserCodeException(sb.toString()); - } - } - } - } - } diff --git a/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins/IvyPublishPlugin.java b/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins/IvyPublishPlugin.java index ff73eb199bea..1af58a068f26 100644 --- a/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins/IvyPublishPlugin.java +++ b/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins/IvyPublishPlugin.java @@ -88,8 +88,7 @@ public void apply(final Project project) { objectFactory, fileResolver, project.getPluginManager(), - project.getExtensions() - )); + project.getExtensions())); createTasksLater(project, extension, project.getLayout().getBuildDirectory()); }); } @@ -203,4 +202,5 @@ private void configureDefaultConfigurationsUsedWhenMappingToResolvedVersions(Ver }); } } + } diff --git a/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishMultiProjectIntegTest.groovy b/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishMultiProjectIntegTest.groovy index 1c21be96d963..73178d557256 100644 --- a/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishMultiProjectIntegTest.groovy +++ b/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishMultiProjectIntegTest.groovy @@ -294,7 +294,7 @@ project(":project2") { subprojects { apply plugin: 'java' apply plugin: 'maven' - + group = "org.gradle.test" version = "1.0" @@ -303,7 +303,7 @@ project(":project2") { println project.name + " RESOLUTION" } } - + subprojects { if (name.startsWith("consumer")) { dependencies { @@ -313,7 +313,7 @@ project(":project2") { } } } - + def verify = tasks.register("verify") { dependsOn ((0..${parallelProjectCount}).collect { ":consumer" + it + ":install" }) doLast { @@ -548,287 +548,4 @@ project(":project2") { $append """ } - - @Issue("https://github.com/gradle/gradle/issues/847") - def "fails publishing projects if they share the same GAV coordinates"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'maven-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - maven { url "${mavenRepo.uri}" } - } - publications { - maven(MavenPublication) { - from components.java - } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - } - """ - - when: - fails 'publishMavenPublicationToMavenRepo' - - then: - failure.assertHasCause "Project :a:core has the same (groupId, artifactId) as :b:core. You should set both the groupId and artifactId of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "fails publishing projects if they share the same GAV coordinates unless detection is disabled"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'maven-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - maven { url "${mavenRepo.uri}" } - } - publications { - maven(MavenPublication) { - from components.java - } - } - } - } - - """ - - when: - succeeds 'publishMavenPublicationToMavenRepo', '-Dorg.gradle.dependency.duplicate.project.detection=false' - def project1 = javaLibrary(mavenRepo.module("org.gradle.test", "core", "1.0")) - - then: - // this tests the current behavior, which is obviously wrong here as the user - // didn't overwrite the publication coordinates - project1.assertPublishedAsJavaModule() - project1.parsedPom.artifactId == 'core' - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "can avoid publishing warning with projects with the same name by setting an explicit artifact id"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'maven-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - maven { url "${mavenRepo.uri}" } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - publishing.publications { - maven(MavenPublication) { - groupId = 'org.gradle.test' - artifactId = 'some-a' - from components.java - } - } - } - - project(':b:core') { - publishing.publications { - maven(MavenPublication) { - groupId = 'org.gradle.test' - artifactId = 'some-b' - from components.java - } - } - } - """ - - when: - succeeds 'publishMavenPublicationToMavenRepo' - def project1 = javaLibrary(mavenRepo.module("org.gradle.test", "some-a", "1.0")) - def project2 = javaLibrary(mavenRepo.module("org.gradle.test", "some-b", "1.0")) - - then: - project1.assertPublishedAsJavaModule() - project2.assertPublishedAsJavaModule() - - project1.parsedPom.artifactId == 'some-a' - project2.parsedPom.artifactId == 'some-b' - - project1.parsedPom.scope("runtime") { - assertDependsOn("org.gradle.test:some-b:1.0") - } - - project1.parsedModuleMetadata.component.module == 'some-a' - project2.parsedModuleMetadata.component.module == 'some-b' - - project1.parsedModuleMetadata.variant("runtimeElements") { - dependency("org.gradle.test", "some-b", "1.0") - noMoreDependencies() - } - - and: - outputDoesNotContain "Project :a:core has the same (groupId, artifactId) as :b:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/847") - def "can avoid publishing warning with projects with the same name by setting an explicit group id"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include 'a:core' - include 'b:core' - """ - - buildFile << """ - allprojects { - apply plugin: 'java-library' - apply plugin: 'maven-publish' - group 'org.gradle.test' - version '1.0' - - publishing { - repositories { - maven { url "${mavenRepo.uri}" } - } - } - } - - project(':a:core') { - dependencies { - implementation project(':b:core') - } - publishing.publications { - maven(MavenPublication) { - groupId = 'org.gradle.test2' - artifactId = 'core' - from components.java - } - } - } - - project(':b:core') { - publishing.publications { - maven(MavenPublication) { - groupId = 'org.gradle.test' - artifactId = 'core' - from components.java - } - } - } - """ - - when: - succeeds 'publishMavenPublicationToMavenRepo' - def project1 = javaLibrary(mavenRepo.module("org.gradle.test2", "core", "1.0")) - def project2 = javaLibrary(mavenRepo.module("org.gradle.test", "core", "1.0")) - - then: - project1.assertPublishedAsJavaModule() - project2.assertPublishedAsJavaModule() - - project1.parsedPom.groupId == 'org.gradle.test2' - project2.parsedPom.groupId == 'org.gradle.test' - - project1.parsedPom.scope("runtime") { - assertDependsOn("org.gradle.test:core:1.0") - } - - project1.parsedModuleMetadata.component.group == 'org.gradle.test2' - project2.parsedModuleMetadata.component.group == 'org.gradle.test' - - project1.parsedModuleMetadata.variant("runtimeElements") { - dependency("org.gradle.test", "core", "1.0") - noMoreDependencies() - } - - and: - outputDoesNotContain "Project :a:core has the same (groupId, artifactId) as :b:core. You should set both the organisation and module name of the publication or opt out by adding the org.gradle.dependency.duplicate.project.detection system property to 'false'." - } - - @ToBeFixedForInstantExecution - @Issue("https://github.com/gradle/gradle/issues/12281") - def "shouldn't change publication coordinates if GAV are different"() { - given: - settingsFile << """ - rootProject.name='duplicates' - include(':a:module') - project(':a:module').projectDir = file('module1') - include(':b:module') - project(':b:module').projectDir = file('module2') - include(':c:module') - project(':c:module').projectDir = file('module3') - """ - - buildFile << """ - subprojects { - apply plugin: 'java' - apply plugin: 'maven-publish' - - publishing { - repositories { - maven { url "${mavenRepo.uri}" } - } - publications { - maven(MavenPublication) { - version = '1.1' - from components.java - } - } - } -}""" - - file("module1/build.gradle") << "group = 'the.group'" - file("module2/build.gradle") << "group = 'the.group'" - file("module3/build.gradle") << "group = 'the.other.group'" - - when: - succeeds ':c:module:publishMavenPublicationToMavenRepo' - def module = javaLibrary(mavenRepo.module("the.other.group", "module", "1.1")) - - then: - module.assertPublishedAsJavaModule() - module.parsedPom.groupId == 'the.other.group' - module.parsedModuleMetadata.component.group == 'the.other.group' - } - } diff --git a/subprojects/maven/src/main/java/org/gradle/api/publish/maven/plugins/MavenPublishPlugin.java b/subprojects/maven/src/main/java/org/gradle/api/publish/maven/plugins/MavenPublishPlugin.java index 19caf86a9f97..8b9ab5282766 100644 --- a/subprojects/maven/src/main/java/org/gradle/api/publish/maven/plugins/MavenPublishPlugin.java +++ b/subprojects/maven/src/main/java/org/gradle/api/publish/maven/plugins/MavenPublishPlugin.java @@ -16,7 +16,6 @@ package org.gradle.api.publish.maven.plugins; -import org.gradle.api.InvalidUserCodeException; import org.gradle.api.NamedDomainObjectFactory; import org.gradle.api.NamedDomainObjectList; import org.gradle.api.NamedDomainObjectSet; @@ -26,9 +25,7 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.gradle.api.attributes.Usage; import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.internal.artifacts.DefaultProjectModuleFactory; import org.gradle.api.internal.artifacts.Module; -import org.gradle.api.internal.artifacts.ProjectBackedModule; import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider; import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileResolver; @@ -38,7 +35,6 @@ import org.gradle.api.plugins.PluginManager; import org.gradle.api.provider.ProviderFactory; import org.gradle.api.publish.PublishingExtension; -import org.gradle.api.publish.internal.versionmapping.DefaultVersionMappingStrategy; import org.gradle.api.publish.internal.versionmapping.VersionMappingStrategyInternal; import org.gradle.api.publish.maven.MavenArtifact; import org.gradle.api.publish.maven.MavenPublication; @@ -47,6 +43,7 @@ import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal; import org.gradle.api.publish.maven.internal.publication.WritableMavenProjectIdentity; import org.gradle.api.publish.maven.internal.publisher.MutableMavenProjectIdentity; +import org.gradle.api.publish.internal.versionmapping.DefaultVersionMappingStrategy; import org.gradle.api.publish.maven.tasks.GenerateMavenPom; import org.gradle.api.publish.maven.tasks.PublishToMavenLocal; import org.gradle.api.publish.maven.tasks.PublishToMavenRepository; @@ -61,10 +58,7 @@ import org.gradle.internal.typeconversion.NotationParser; import javax.inject.Inject; -import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; import static org.apache.commons.lang.StringUtils.capitalize; @@ -107,12 +101,11 @@ public void apply(final Project project) { project.getExtensions().configure(PublishingExtension.class, extension -> { extension.getPublications().registerFactory(MavenPublication.class, new MavenPublicationFactory( - dependencyMetaDataProvider, - instantiatorFactory.decorateLenient(), - fileResolver, - project.getPluginManager(), - project.getExtensions() - )); + dependencyMetaDataProvider, + instantiatorFactory.decorateLenient(), + fileResolver, + project.getPluginManager(), + project.getExtensions())); realizePublishingTasksLater(project, extension); }); } @@ -186,7 +179,7 @@ private void createGeneratePomTask(TaskContainer tasks, final MavenPublicationIn // are mapped to some attributes, which can be used in the version mapping strategy. // This is only required for POM publication, because the variants have _implicit_ attributes that we want explicit for matching generatePomTask.withCompileScopeAttributes(immutableAttributesFactory.of(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_API))) - .withRuntimeScopeAttributes(immutableAttributesFactory.of(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME))); + .withRuntimeScopeAttributes(immutableAttributesFactory.of(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME))); }); }); publication.setPomGenerator(generatorTask); @@ -231,11 +224,11 @@ public MavenPublication create(final String name) { VersionMappingStrategyInternal versionMappingStrategy = objectFactory.newInstance(DefaultVersionMappingStrategy.class); configureDefaultConfigurationsUsedWhenMappingToResolvedVersions(versionMappingStrategy); return objectFactory.newInstance( - DefaultMavenPublication.class, - name, - projectIdentity, - artifactNotationParser, - versionMappingStrategy + DefaultMavenPublication.class, + name, + projectIdentity, + artifactNotationParser, + versionMappingStrategy ); } @@ -255,66 +248,11 @@ private void configureDefaultConfigurationsUsedWhenMappingToResolvedVersions(Ver private MutableMavenProjectIdentity createProjectIdentity() { final Module module = dependencyMetaDataProvider.getModule(); MutableMavenProjectIdentity projectIdentity = new WritableMavenProjectIdentity(objectFactory); - if (module instanceof ProjectBackedModule) { - LazyProjectNameProvider lazyProjectNameProvider = safeProjectCoordinatesProvider(module); - projectIdentity.getGroupId().set(providerFactory.provider(lazyProjectNameProvider::getGroup)); - projectIdentity.getArtifactId().set(providerFactory.provider(lazyProjectNameProvider::getName)); - } else { - projectIdentity.getGroupId().set(providerFactory.provider(module::getGroup)); - projectIdentity.getArtifactId().set(providerFactory.provider(module::getName)); - } + projectIdentity.getGroupId().set(providerFactory.provider(module::getGroup)); + projectIdentity.getArtifactId().set(providerFactory.provider(module::getName)); projectIdentity.getVersion().set(providerFactory.provider(module::getVersion)); return projectIdentity; } - - private LazyProjectNameProvider safeProjectCoordinatesProvider(Module module) { - return new LazyProjectNameProvider((ProjectBackedModule) module); - } - } - - private static final class LazyProjectNameProvider { - private final ProjectBackedModule projectBackedModule; - private final AtomicBoolean warned = new AtomicBoolean(); - private final AtomicBoolean hasDuplicates = new AtomicBoolean(); - - private LazyProjectNameProvider(ProjectBackedModule module) { - this.projectBackedModule = module; - } - - public String getGroup() { - maybeWarnAboutDuplicates(); - return projectBackedModule.getGroup(); - } - - public String getName() { - maybeWarnAboutDuplicates(); - if (hasDuplicates.get()) { - return projectBackedModule.getName(); - } else { - // the project name is used for publication, even if internally - // for dependency resolution we use the "de-duplicated" name - return projectBackedModule.getProject().getName(); - } - } - - private void maybeWarnAboutDuplicates() { - if (!warned.getAndSet(true)) { - Project project = projectBackedModule.getProject(); - List projectsWithSameId = projectBackedModule.getProjectsWithSameCoordinates(); - boolean duplicates = !projectsWithSameId.isEmpty() && DefaultProjectModuleFactory.isDuplicateDetectionEnabled(); - hasDuplicates.set(duplicates); - if (duplicates) { - StringBuilder sb = new StringBuilder(); - sb.append("Project ") - .append(project.getPath()) - .append(" has the same (groupId, artifactId) as ") - .append(projectsWithSameId.stream().map(Project::getPath).collect(Collectors.joining(" and "))) - .append(". You should set both the groupId and artifactId of the publication") - .append(" or opt out by adding the " + DefaultProjectModuleFactory.DUPLICATE_DETECTION_SYSPROP + " system property to 'false'."); - throw new InvalidUserCodeException(sb.toString()); - } - } - } } }