├── .springjavaformatconfig ├── .github ├── dco.yml ├── actions │ ├── publish-to-plugin-portal │ │ ├── settings.gradle │ │ ├── artifacts.spec │ │ ├── build.gradle │ │ └── action.yml │ ├── sync-to-maven-central │ │ ├── artifacts.spec │ │ └── action.yml │ ├── create-github-release │ │ ├── changelog-generator.yml │ │ └── action.yml │ ├── deploy-to-artifactory │ │ └── action.yml │ └── build │ │ └── action.yml └── workflows │ ├── run-codeql-analysis.yml │ └── build-and-deploy-snapshot.yml ├── gradle.properties ├── src ├── test │ ├── resources │ │ ├── maven-repo │ │ │ └── test │ │ │ │ ├── direct-exclude │ │ │ │ └── 1.0 │ │ │ │ │ ├── direct-exclude-1.0.jar │ │ │ │ │ └── direct-exclude-1.0.pom │ │ │ │ ├── malformed-exclude │ │ │ │ └── 1.0 │ │ │ │ │ ├── malformed-exclude-1.0.jar │ │ │ │ │ └── malformed-exclude-1.0.pom │ │ │ │ ├── transitive-exclude │ │ │ │ └── 1.0 │ │ │ │ │ ├── transitive-exclude-1.0.jar │ │ │ │ │ └── transitive-exclude-1.0.pom │ │ │ │ ├── dependency-management-child │ │ │ │ └── 1.0 │ │ │ │ │ ├── dependency-management-child-1.0.jar │ │ │ │ │ └── dependency-management-child-1.0.pom │ │ │ │ ├── unresolvable-transitive-dependency │ │ │ │ └── 1.0 │ │ │ │ │ ├── unresolvable-transitive-dependency-1.0.jar │ │ │ │ │ └── unresolvable-transitive-dependency-1.0.pom │ │ │ │ ├── platform-consumer │ │ │ │ └── 1.0 │ │ │ │ │ ├── platform-consumer-1.0.jar │ │ │ │ │ ├── platform-consumer-1.0.pom │ │ │ │ │ └── platform-consumer-1.0.module │ │ │ │ ├── no-dependency-management-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── no-dependency-management-bom-1.0.pom │ │ │ │ ├── dependency-management-parent │ │ │ │ └── 1.0 │ │ │ │ │ └── dependency-management-parent-1.0.pom │ │ │ │ ├── illegal-system-path │ │ │ │ └── 1.0 │ │ │ │ │ └── illegal-system-path-1.0.pom │ │ │ │ ├── missing-managed-version-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── missing-managed-version-bom-1.0.pom │ │ │ │ ├── bravo-pom-customization-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── bravo-pom-customization-bom-1.0.pom │ │ │ │ ├── dependency-management-grandparent │ │ │ │ └── 1.0 │ │ │ │ │ └── dependency-management-grandparent-1.0.pom │ │ │ │ ├── first-alpha-dependency-management │ │ │ │ └── 1.0 │ │ │ │ │ └── first-alpha-dependency-management-1.0.pom │ │ │ │ ├── second-alpha-dependency-management │ │ │ │ └── 1.0 │ │ │ │ │ └── second-alpha-dependency-management-1.0.pom │ │ │ │ ├── dependency-management-with-classifier-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── dependency-management-with-classifier-bom-1.0.pom │ │ │ │ ├── wildcard-exclude-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── wildcard-exclude-bom-1.0.pom │ │ │ │ ├── direct-exclude-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── direct-exclude-bom-1.0.pom │ │ │ │ ├── transitive-exclude-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── transitive-exclude-bom-1.0.pom │ │ │ │ ├── exclude-unresolvable-dependency │ │ │ │ └── 1.0 │ │ │ │ │ └── exclude-unresolvable-dependency-1.0.pom │ │ │ │ ├── alpha-pom-customization-bom │ │ │ │ └── 1.0 │ │ │ │ │ └── alpha-pom-customization-bom-1.0.pom │ │ │ │ ├── platform-a │ │ │ │ └── 1.0 │ │ │ │ │ ├── platform-a-1.0.pom │ │ │ │ │ └── platform-a-1.0.module │ │ │ │ ├── platform-with-dependencies │ │ │ │ └── 1.0 │ │ │ │ │ ├── platform-with-dependencies-1.0.pom │ │ │ │ │ └── platform-with-dependencies-1.0.module │ │ │ │ ├── platform-b │ │ │ │ └── 1.0 │ │ │ │ │ ├── platform-b-1.0.pom │ │ │ │ │ └── platform-b-1.0.module │ │ │ │ └── platform-with-constrained-transitive-dependency │ │ │ │ └── 1.0 │ │ │ │ ├── platform-with-constrained-transitive-dependency-1.0.pom │ │ │ │ └── platform-with-constrained-transitive-dependency-1.0.module │ │ └── io │ │ │ └── spring │ │ │ └── gradle │ │ │ └── dependencymanagement │ │ │ ├── DMPIT │ │ │ ├── dependencyWithAMissingComponentInItsMapIdentifierProducesAHelpfulError.gradle │ │ │ ├── dependencyWithAMissingComponentInItsStringIdentifierProducesAHelpfulError.gradle │ │ │ ├── whenConfigurationIsNotTransitiveExclusionsAreNotCalculated.gradle │ │ │ ├── artifactsWithAPomAreTolerated.gradle │ │ │ ├── bomThatReferencesJavaHomeCanBeImported.gradle │ │ │ ├── transitiveDependenciesWithACircularReferenceAreTolerated.gradle │ │ │ ├── exclusionThatIsMalformedIsTolerated.gradle │ │ │ ├── exclusionThatAppliesTransitivelyIsHonored.gradle │ │ │ ├── dependenciesWithExtremelyLargePomsAreHandled.gradle │ │ │ ├── dynamicVersionIsNotAddedToDependencyManagement.gradle │ │ │ ├── exclusionDeclaredOnTheDependencyThatHasTheExcludedDependencyIsHonored.gradle │ │ │ ├── exclusionsAreAppliedCorrectlyToDependenciesThatAreReferencedMultipleTimes.gradle │ │ │ ├── importOfABomCanReferenceAProperty.gradle │ │ │ ├── bomWithNoDependencyManagementCanBeImportedAndItsPropertiesUsed.gradle │ │ │ ├── dependenciesDeclaredInAPlatformAreNotAccidentallyExcluded.gradle │ │ │ ├── exclusionsFromAncestorsOfADependencyAreAppliedCorrectly.gradle │ │ │ ├── resolutionSucceedsWhenDependencyReliesOnConstraintsFromPlatformDependencies.gradle │ │ │ ├── managedDependencyCanBeConfiguredUsingAGString.gradle │ │ │ ├── resolutionSucceedsWhenDependencyReliesOnDependencyManagementFromItsAncestors.gradle │ │ │ ├── directProjectDependenciesTakePrecedenceOverDependencyManagement.gradle │ │ │ ├── bomImportOrderIsReflectedInManagedVersions.gradle │ │ │ ├── importOfABomCanUsePropertyMethodToReferenceAProperty.gradle │ │ │ ├── importedBomCanBeUsedToApplyDependencyManagement.gradle │ │ │ ├── dependencyWithAnOtherwiseExcludedTransitiveDependencyOverridesTheExclude.gradle │ │ │ ├── pomExclusionsCanBeDisabled.gradle │ │ │ ├── propertyInABomCanBeOverriddenWhenItIsImported.gradle │ │ │ ├── dependencyManagementIsAppliedToATransitiveDependencyDeclaredWithARange.gradle │ │ │ ├── exclusionsAreAppliedToDependenciesVersionedWithConstraints.gradle │ │ │ ├── exclusionsAreHandledCorrectlyForDependenciesThatAppearMultipleTimes.gradle │ │ │ ├── platformConstrainingATransitiveDependencyDoesNotAccidentallyExcludeThatDependency.gradle │ │ │ ├── jbossJavaEEBomCanBeImportedAndUsedForDependencyManagement.gradle │ │ │ ├── whenImportingABomDependencyManagementWithNoVersionIsIgnored.gradle │ │ │ ├── configurationCanBeReferredToByNameWhenConfiguringConfigurationSpecificDependencyManagement.gradle │ │ │ ├── directExclusionDeclaredInABomIsHonored.gradle │ │ │ ├── springCloudStarterParentBomCanBeImportedAndUsedForDependencyManagement.gradle │ │ │ ├── whenImportingABomDependencyManagementWithAClassifierIsIgnored.gradle │ │ │ ├── wildcardExclusionDeclaredInABomIsHonored.gradle │ │ │ ├── dependencyManagementIsNotAppliedToADependencyUseLatestIntegration.gradle │ │ │ ├── importedBomsVersionsCanBeOverridden.gradle │ │ │ ├── transitiveExclusionDeclaredInABomIsHonored.gradle │ │ │ ├── transitiveProjectDependenciesTakePrecedenceOverDependencyManagement.gradle │ │ │ ├── versionsOfDirectDependenciesTakePrecedenceOverDependencyManagementInAnImportedBom.gradle │ │ │ ├── dependencyManagementIsNotAppliedToAnInheritedDependencyUseLatestIntegration.gradle │ │ │ ├── versionsOfDirectDependenciesTakePrecedenceOverDirectDependencyManagement.gradle │ │ │ ├── configurationCanBeUsedDirectlyWhenConfiguringConfigurationSpecificDependencyManagement.gradle │ │ │ ├── exclusionsInImportedBomsForUnresolvableDependenciesAreApplied.gradle │ │ │ ├── explicitDependencyPreventsTheDependencyFromBeingExcluded.gradle │ │ │ ├── resolutionSucceedsWhenDependencyHasAnInvalidPom.gradle │ │ │ ├── transitiveDependencyWithAnUnexcludedPathPreventsExclusion.gradle │ │ │ ├── configurationSpecificDependencyManagementIsInheritedByExtendingConfigurations.gradle │ │ │ ├── versionOnADirectDependencyProvidesDependencyManagementToExtendingConfigurations.gradle │ │ │ ├── dependencyManagementWithExclusionsCanBeDeclaredInTheBuild.gradle │ │ │ ├── propertyInABomCanBeConfiguredUsingAReferenceToAProjectProperty.gradle │ │ │ ├── bomImportOrderIsReflectedInManagedVersionsWhenSameBomIsImportedMultipleTimes.gradle │ │ │ ├── whenOverridingABomPropertyAPropertyOnAnImportTakesPrecedenceOverAProjectProperty.gradle │ │ │ ├── dependencyManagementCanBeDeclaredInTheBuild.gradle │ │ │ ├── exclusionsAreNotInheritedAndDoNotAffectTransitiveDependencies.gradle │ │ │ ├── exclusionCanBeDeclaredOnAnEntryInADependencySet.gradle │ │ │ ├── bomPropertyCanBeUsedToVersionADependency.gradle │ │ │ ├── dependencyManagementBeingOverridenByDependenciesCanBeDisabled.gradle │ │ │ ├── dependencySetCanBeUsedToProvideDependencyManagementForMultipleModulesWithTheSameGroupAndVersion.gradle │ │ │ ├── configurationSpecificDependencyManagementTakesPrecedenceOverGlobalDependencyManagement.gradle │ │ │ ├── constraintsInTransitivePlatformDependenciesDoNotPreventExclusionsFromWorking.gradle │ │ │ ├── dependencyVersionsCanBeDefinedUsingProperties.gradle │ │ │ ├── exclusionsAreNotInheritedAndDoNotAffectDirectDependencies.gradle │ │ │ ├── managedVersionsOfAConfigurationCanBeAccessed.gradle │ │ │ ├── unresolvableDependenciesAreIgnoredWhenApplyingMavenStyleExclusions.gradle │ │ │ ├── bomImportOrderIsReflectedInManagedVersionsWhenThePomIsPublished.gradle │ │ │ ├── dependencyManagementCanBeAppliedToASpecificConfiguration.gradle │ │ │ ├── whenDependencyIsSubstitutedNewCoordinatesAreUsedForDependencyManagement.gradle │ │ │ ├── propertiesImportedFromABomCanBeAccessed.gradle │ │ │ ├── userProvidedResolutionStrategyRunsAfterInternalResolutionStrategy.gradle │ │ │ ├── dependencyManagementCanBeDeclaredInTheBuildUsingTheNewSyntax.gradle │ │ │ ├── dependencyManagementCanBeAppliedToMultipleSpecificConfigurations.gradle │ │ │ └── managedVersionsCanBeAccessedProgramatically.gradle │ │ │ ├── MPPIT │ │ │ ├── generatedPomsAreCustomized.gradle │ │ │ ├── usingImportedPropertiesDoesNotPreventFurtherConfigurationOfThePublishingExtension.gradle │ │ │ └── customizationOfGeneratedPomsCanBeDisabled.gradle │ │ │ ├── GVCIT │ │ │ ├── buildDoesNotProduceDeprecationWarnings.gradle │ │ │ └── pluginIsCompatible.gradle │ │ │ └── VPCIT │ │ │ └── versionsPluginReportsUpgradesForDependenciesWithManagedVersions.gradle │ └── java │ │ └── io │ │ └── spring │ │ └── gradle │ │ └── dependencymanagement │ │ ├── VersionsPluginCompatibilityIntegerationTests.java │ │ ├── internal │ │ ├── dsl │ │ │ └── StandardMavenBomHandlerTests.java │ │ └── properties │ │ │ └── ProjectPropertySourceTests.java │ │ ├── MavenPublishPluginIntegrationTests.java │ │ └── DependencyManagementPluginTests.java └── main │ └── java │ └── io │ └── spring │ └── gradle │ └── dependencymanagement │ ├── package-info.java │ ├── dsl │ ├── package-info.java │ ├── DependencyHandler.java │ ├── GeneratedPomCustomizationHandler.java │ ├── MavenBomHandler.java │ ├── DependencyManagementHandler.java │ ├── ImportsHandler.java │ ├── DependencySetHandler.java │ └── DependencyManagementConfigurer.java │ ├── internal │ ├── package-info.java │ ├── dsl │ │ ├── package-info.java │ │ ├── ClosureBackedAction.java │ │ ├── StandardGeneratedPomCustomizationHandler.java │ │ ├── StandardMavenBomHandler.java │ │ ├── StandardDependencyHandler.java │ │ ├── CompoundDependencyManagementConfigurer.java │ │ └── StandardDependencySetHandler.java │ ├── pom │ │ ├── package-info.java │ │ ├── PomResolver.java │ │ ├── Coordinates.java │ │ ├── PomReference.java │ │ └── Pom.java │ ├── properties │ │ ├── package-info.java │ │ ├── PropertySource.java │ │ ├── MapPropertySource.java │ │ ├── ProjectPropertySource.java │ │ └── CompositePropertySource.java │ ├── bridge │ │ └── package-info.java │ ├── report │ │ └── package-info.java │ ├── maven │ │ ├── package-info.java │ │ ├── PropertySourceValueSource.java │ │ └── RelaxedModelValidator.java │ ├── Versions.java │ ├── Exclusions.java │ └── Exclusion.java │ └── maven │ ├── package-info.java │ └── PomDependencyManagementConfigurer.java ├── ci ├── scripts │ ├── common.sh │ ├── build-project.sh │ ├── generate-changelog.sh │ ├── generate-release-notes.sh │ ├── promote.sh │ ├── sync-to-maven-central.sh │ └── stage.sh ├── config │ ├── release-scripts.yml │ └── changelog-generator.yml ├── images │ ├── ci-image │ │ └── Dockerfile │ ├── get-jdk-url.sh │ ├── README.adoc │ └── setup.sh ├── tasks │ ├── stage.yml │ ├── build-project.yml │ ├── sync-to-maven-central.yml │ ├── generate-release-notes.yml │ ├── generate-changelog.yml │ ├── promote.yml │ └── build-ci-image.yml ├── parameters.yml └── README.adoc ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── config └── checkstyle │ ├── checkstyle.xml │ ├── checkstyle-suppressions.xml │ ├── checkstyle-import-control.xml │ └── checkstyle-header.txt ├── README.md ├── git └── hooks │ └── prepare-forward-merge ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md /.springjavaformatconfig: -------------------------------------------------------------------------------- 1 | java-baseline=8 2 | -------------------------------------------------------------------------------- /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /.github/actions/publish-to-plugin-portal/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=1.1.8-SNAPSHOT 2 | 3 | org.gradle.caching=true 4 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/direct-exclude/1.0/direct-exclude-1.0.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/malformed-exclude/1.0/malformed-exclude-1.0.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/transitive-exclude/1.0/transitive-exclude-1.0.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/dependency-management-child/1.0/dependency-management-child-1.0.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/unresolvable-transitive-dependency/1.0/unresolvable-transitive-dependency-1.0.jar: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ci/scripts/common.sh: -------------------------------------------------------------------------------- 1 | source /opt/concourse-java.sh 2 | 3 | setup_symlinks 4 | cleanup_maven_repo "io.spring.gradle" 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .gradle 3 | .idea 4 | .project 5 | .settings 6 | bin 7 | build 8 | *.iml 9 | *.ipr 10 | *.iws 11 | out -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-gradle-plugins/dependency-management-plugin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ci/config/release-scripts.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | io.spring.concourse: DEBUG 4 | spring: 5 | main: 6 | banner-mode: off 7 | sonatype: 8 | exclude: 9 | - 'build-info\.json' 10 | -------------------------------------------------------------------------------- /ci/images/ci-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:focal-20210401 2 | 3 | ADD setup.sh /setup.sh 4 | ADD get-jdk-url.sh /get-jdk-url.sh 5 | RUN ./setup.sh java8 6 | 7 | ENV JAVA_HOME /opt/openjdk 8 | ENV PATH $JAVA_HOME/bin:$PATH 9 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-consumer/1.0/platform-consumer-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-gradle-plugins/dependency-management-plugin/HEAD/src/test/resources/maven-repo/test/platform-consumer/1.0/platform-consumer-1.0.jar -------------------------------------------------------------------------------- /ci/images/get-jdk-url.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | case "$1" in 5 | java8) 6 | echo "https://github.com/bell-sw/Liberica/releases/download/8u332+9/bellsoft-jdk8u332+9-linux-amd64.tar.gz" 7 | ;; 8 | *) 9 | echo $"Unknown java version" 10 | exit 1 11 | esac 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /ci/tasks/stage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | inputs: 4 | - name: git-repo 5 | outputs: 6 | - name: stage-git-repo 7 | - name: distribution-repository 8 | params: 9 | RELEASE_TYPE: 10 | CI: true 11 | caches: 12 | - path: gradle 13 | run: 14 | path: git-repo/ci/scripts/stage.sh 15 | -------------------------------------------------------------------------------- /ci/scripts/build-project.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source $(dirname $0)/common.sh 5 | repository=$(pwd)/distribution-repository 6 | 7 | pushd git-repo > /dev/null 8 | ulimit -n 65536 9 | ./gradlew --no-daemon -PdeploymentRepository=${repository} build publish 10 | popd > /dev/null 11 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | plugins { 9 | id "com.gradle.develocity" version "3.17.2" 10 | id "io.spring.ge.conventions" version "0.0.17" 11 | } 12 | 13 | rootProject.name = 'dependency-management-plugin' -------------------------------------------------------------------------------- /ci/tasks/build-project.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | inputs: 4 | - name: git-repo 5 | outputs: 6 | - name: distribution-repository 7 | - name: git-repo 8 | caches: 9 | - path: maven 10 | - path: gradle 11 | params: 12 | BRANCH: 13 | CI: true 14 | run: 15 | path: git-repo/ci/scripts/build-project.sh 16 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ci/tasks/sync-to-maven-central.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | inputs: 4 | - name: git-repo 5 | - name: artifactory-repo 6 | params: 7 | BINTRAY_REPO: 8 | BINTRAY_SUBJECT: 9 | BINTRAY_USERNAME: 10 | BINTRAY_API_KEY: 11 | SONATYPE_USER_TOKEN: 12 | SONATYPE_PASSWORD_TOKEN: 13 | run: 14 | path: git-repo/ci/scripts/sync-to-maven-central.sh -------------------------------------------------------------------------------- /ci/parameters.yml: -------------------------------------------------------------------------------- 1 | github-organization: "spring-gradle-plugins" 2 | github-repository: "dependency-management-plugin" 3 | docker-hub-organization: "springci" 4 | artifactory-server: "https://repo.spring.io" 5 | branch: "main" 6 | milestone: "1.1.x" 7 | build-name: "dependency-management-plugin" 8 | concourse-url: "https://ci.spring.io" 9 | task-timeout: 1h00m 10 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyWithAMissingComponentInItsMapIdentifierProducesAHelpfulError.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency group: 'a' 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyWithAMissingComponentInItsStringIdentifierProducesAHelpfulError.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'a:1.0' 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/whenConfigurationIsNotTransitiveExclusionsAreNotCalculated.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("io.spring.dependency-management") 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | configurations { 10 | nonTransitive { 11 | transitive = false 12 | } 13 | } 14 | 15 | dependencies { 16 | nonTransitive("org.eclipse.platform:org.eclipse.swt:3.124.100") 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/run-codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Run CodeQL Analysis" 2 | on: 3 | push: 4 | pull_request: 5 | workflow_dispatch: 6 | schedule: 7 | - cron: '45 0 * * 1' 8 | permissions: read-all 9 | jobs: 10 | run-analysis: 11 | permissions: 12 | actions: read 13 | contents: read 14 | security-events: write 15 | uses: spring-io/github-actions/.github/workflows/codeql-analysis.yml@6e66995f7d29de1e4ff76e4f0def7a10163fe910 16 | -------------------------------------------------------------------------------- /ci/images/README.adoc: -------------------------------------------------------------------------------- 1 | == CI Images 2 | 3 | These images are used by CI to run the actual builds. 4 | 5 | To build the image locally run the following from this directory: 6 | 7 | ---- 8 | $ docker build --no-cache -f /Dockerfile . 9 | ---- 10 | 11 | For example 12 | 13 | ---- 14 | $ docker build --no-cache -f ci-image/Dockerfile . 15 | ---- 16 | 17 | To test run: 18 | 19 | ---- 20 | $ docker run -it --entrypoint /bin/bash 21 | ---- 22 | -------------------------------------------------------------------------------- /.github/actions/sync-to-maven-central/artifacts.spec: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "aql": { 5 | "items.find": { 6 | "$and": [ 7 | { 8 | "@build.name": "${buildName}", 9 | "@build.number": "${buildNumber}", 10 | "name": { 11 | "$nmatch": "*docs*" 12 | } 13 | } 14 | ] 15 | } 16 | }, 17 | "target": "nexus/" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /ci/scripts/generate-changelog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | CONFIG_DIR=git-repo/ci/config 5 | version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' ) 6 | 7 | java -jar /github-changelog-generator.jar \ 8 | --spring.config.location=${CONFIG_DIR}/changelog-generator.yml \ 9 | ${version} generated-changelog/changelog.md 10 | 11 | echo ${version} > generated-changelog/version 12 | echo v${version} > generated-changelog/tag 13 | -------------------------------------------------------------------------------- /ci/tasks/generate-release-notes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | image_resource: 4 | type: docker-image 5 | source: 6 | repository: springio/github-release-notes-generator 7 | tag: '0.0.2' 8 | inputs: 9 | - name: git-repo 10 | - name: version 11 | outputs: 12 | - name: generated-release-notes 13 | params: 14 | GITHUB_ORGANIZATION: 15 | GITHUB_REPO: 16 | GITHUB_USERNAME: 17 | GITHUB_TOKEN: 18 | RELEASE_TYPE: 19 | run: 20 | path: git-repo/ci/scripts/generate-release-notes.sh 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/MPPIT/generatedPomsAreCustomized.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' 3 | id 'java' 4 | id 'maven-publish' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencyManagement { 12 | imports { 13 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.4.2.RELEASE' 14 | } 15 | } 16 | 17 | publishing { 18 | publications { 19 | mavenJava(MavenPublication) { 20 | from components.java 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/GVCIT/buildDoesNotProduceDeprecationWarnings.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.springframework.boot:spring-boot-dependencies:2.7.15' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation("org.springframework.boot:spring-boot-starter") 18 | implementation("org.keycloak:keycloak-admin-client:25.0.1") 19 | } 20 | -------------------------------------------------------------------------------- /.github/actions/publish-to-plugin-portal/artifacts.spec: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "aql": { 5 | "items.find": { 6 | "$and": [ 7 | { 8 | "@build.name": "${buildName}", 9 | "@build.number": "${buildNumber}", 10 | "path": { 11 | "$match": "io/spring/gradle/dependency-management-plugin/*" 12 | } 13 | } 14 | ] 15 | } 16 | }, 17 | "target": "gradle-plugin-portal/" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/artifactsWithAPomAreTolerated.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | flatDir( dirs: 'lib') 8 | } 9 | 10 | dependencies { 11 | implementation ':foo:1.0.0' 12 | } 13 | 14 | task resolve { 15 | doFirst { 16 | def files = project.configurations.compileClasspath.resolve() 17 | def output = new File("${buildDir}/resolved.txt") 18 | output.parentFile.mkdirs() 19 | files.collect { it.name }.each { output << "${it}\n" } 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/MPPIT/usingImportedPropertiesDoesNotPreventFurtherConfigurationOfThePublishingExtension.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' 3 | id 'java' 4 | id 'maven-publish' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencyManagement { 12 | dependencies { 13 | dependency "com.foo:bar:\${importedProperties['bar.version']}" 14 | } 15 | } 16 | 17 | publishing { 18 | publications { 19 | mavenJava(MavenPublication) { 20 | from components.java 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ci/tasks/generate-changelog.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | image_resource: 4 | type: registry-image 5 | source: 6 | repository: springio/github-changelog-generator 7 | tag: '0.0.7' 8 | username: ((docker-hub-username)) 9 | password: ((docker-hub-password)) 10 | inputs: 11 | - name: git-repo 12 | - name: artifactory-repo 13 | outputs: 14 | - name: generated-changelog 15 | params: 16 | GITHUB_ORGANIZATION: 17 | GITHUB_REPO: 18 | GITHUB_USERNAME: 19 | GITHUB_TOKEN: 20 | RELEASE_TYPE: 21 | run: 22 | path: git-repo/ci/scripts/generate-changelog.sh 23 | -------------------------------------------------------------------------------- /ci/config/changelog-generator.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | repository: spring-gradle-plugins/dependency-management-plugin 3 | sections: 4 | - title: ":star: New Features" 5 | labels: 6 | - "type: enhancement" 7 | - title: ":lady_beetle: Bug Fixes" 8 | labels: 9 | - "type: bug" 10 | - "type: regression" 11 | - title: ":notebook_with_decorative_cover: Documentation" 12 | labels: 13 | - "type: documentation" 14 | - title: ":hammer: Dependency Upgrades" 15 | sort: "title" 16 | labels: 17 | - "type: dependency-upgrade" 18 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/VPCIT/versionsPluginReportsUpgradesForDependenciesWithManagedVersions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.github.ben-manes.versions' version '0.42.0' 3 | id 'io.spring.dependency-management' 4 | id 'java' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencyManagement { 12 | dependencies { 13 | dependency 'commons-logging:commons-logging:1.1.3' 14 | } 15 | } 16 | 17 | dependencies { 18 | implementation 'commons-logging:commons-logging' 19 | } 20 | 21 | dependencyUpdates { 22 | outputFormatter = 'json' 23 | } 24 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/MPPIT/customizationOfGeneratedPomsCanBeDisabled.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' 3 | id 'java' 4 | id 'maven-publish' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencyManagement { 12 | generatedPomCustomization { 13 | enabled = false 14 | } 15 | imports { 16 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.4.2.RELEASE' 17 | } 18 | } 19 | 20 | publishing { 21 | publications { 22 | mavenJava(MavenPublication) { 23 | from components.java 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ci/README.adoc: -------------------------------------------------------------------------------- 1 | == Concourse pipeline 2 | 3 | Ensure that you've setup the dependency-management-plugin target and can login 4 | 5 | [source] 6 | ---- 7 | $ fly -t dependency-management-plugin login -n dependency-management-plugin -c https://ci.spring.io 8 | ---- 9 | 10 | The pipeline can be deployed using the following command: 11 | 12 | [source] 13 | ---- 14 | $ fly -t dependency-management-plugin set-pipeline -p dependency-management-plugin-1.1.x -c ci/pipeline.yml -l ci/parameters.yml 15 | ---- 16 | 17 | NOTE: This assumes that you have Vault integration configured with the appropriate secrets. 18 | -------------------------------------------------------------------------------- /ci/scripts/generate-release-notes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | version=$( cat version/version ) 5 | milestone=${version} 6 | 7 | java -jar /github-release-notes-generator.jar \ 8 | --releasenotes.github.username=${GITHUB_USERNAME} \ 9 | --releasenotes.github.password=${GITHUB_TOKEN} \ 10 | --releasenotes.github.organization=spring-gradle-plugins \ 11 | --releasenotes.github.repository=dependency-management-plugin \ 12 | ${milestone} generated-release-notes/release-notes.md 13 | 14 | echo ${version} > generated-release-notes/version 15 | echo v${version} > generated-release-notes/tag 16 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomThatReferencesJavaHomeCanBeImported.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.jboss:jboss-parent:11' 13 | } 14 | } 15 | 16 | 17 | task managedVersions { 18 | doFirst { 19 | def output = new File("${buildDir}/managed-versions.txt") 20 | output.parentFile.mkdirs() 21 | dependencyManagement.managedVersions.each { key, value -> 22 | output << "${key} -> ${value}\n" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/transitiveDependenciesWithACircularReferenceAreTolerated.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'org.apache.xmlgraphics:batik-rasterizer:1.7' 12 | } 13 | 14 | task resolve { 15 | doFirst { 16 | def files = project.configurations.compileClasspath.resolve() 17 | def output = new File("${buildDir}/resolved.txt") 18 | output.parentFile.mkdirs() 19 | files.collect { it.name }.each { output << "${it}\n" } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionThatIsMalformedIsTolerated.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:malformed-exclude:1.0' 15 | } 16 | 17 | task resolve { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } -------------------------------------------------------------------------------- /ci/tasks/promote.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | image_resource: 4 | type: registry-image 5 | source: 6 | repository: springio/concourse-release-scripts 7 | tag: '0.3.4' 8 | username: ((docker-hub-username)) 9 | password: ((docker-hub-password)) 10 | inputs: 11 | - name: git-repo 12 | - name: artifactory-repo 13 | outputs: 14 | - name: version 15 | params: 16 | ARTIFACTORY_SERVER: 17 | ARTIFACTORY_USERNAME: 18 | ARTIFACTORY_PASSWORD: 19 | RELEASE_TYPE: 20 | SONATYPE_USER: 21 | SONATYPE_PASSWORD: 22 | SONATYPE_URL: 23 | SONATYPE_STAGING_PROFILE: 24 | run: 25 | path: git-repo/ci/scripts/promote.sh 26 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionThatAppliesTransitivelyIsHonored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:transitive-exclude:1.0' 15 | } 16 | 17 | task resolve { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/no-dependency-management-bom/1.0/no-dependency-management-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | no-dependency-management-bom 8 | 1.0 9 | pom 10 | 11 | 12 | alpha 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependenciesWithExtremelyLargePomsAreHandled.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'io.spring.dependency-management' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'org.patrodyne.jvnet:hisrc-basicjaxb-plugins:2.1.0' 12 | } 13 | 14 | tasks.register("resolve") { 15 | doFirst { 16 | def files = project.configurations.compileClasspath.resolve() 17 | def output = new File("${buildDir}/resolved.txt") 18 | output.parentFile.mkdirs() 19 | files.collect { it.name }.each { output << "${it}\n" } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dynamicVersionIsNotAddedToDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'commons-logging:commons-logging:latest.integration' 12 | } 13 | 14 | task managedVersions { 15 | doFirst { 16 | def output = new File("${buildDir}/managed-versions.txt") 17 | output.parentFile.mkdirs() 18 | output.createNewFile() 19 | dependencyManagement.managedVersions.each { key, value -> 20 | output << "${key} -> ${value}\n" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionDeclaredOnTheDependencyThatHasTheExcludedDependencyIsHonored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:direct-exclude:1.0' 15 | } 16 | 17 | task resolve { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsAreAppliedCorrectlyToDependenciesThatAreReferencedMultipleTimes.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation 'org.springframework.boot:spring-boot-starter-remote-shell:1.2.0.RELEASE' 12 | } 13 | 14 | task resolve { 15 | doFirst { 16 | def files = project.configurations.compileClasspath.resolve() 17 | def output = new File("${buildDir}/resolved.txt") 18 | output.parentFile.mkdirs() 19 | files.collect { it.name }.each { output << "${it}\n" } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/importOfABomCanReferenceAProperty.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | ext['platformVersion'] = '1.0.1.RELEASE' 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom "io.spring.platform:platform-bom:$platformVersion" 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomWithNoDependencyManagementCanBeImportedAndItsPropertiesUsed.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url file("maven-repo") 9 | } 10 | } 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom 'test:no-dependency-management-bom:1.0' 15 | } 16 | } 17 | 18 | task importedProperties { 19 | doFirst { 20 | def output = new File("${buildDir}/imported-properties.txt") 21 | output.parentFile.mkdirs() 22 | project.dependencyManagement.importedProperties.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependenciesDeclaredInAPlatformAreNotAccidentallyExcluded.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url file("maven-repo") 9 | } 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation(platform("test:platform-with-dependencies:1.0")) 15 | } 16 | 17 | tasks.register("resolve") { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsFromAncestorsOfADependencyAreAppliedCorrectly.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { url 'https://repo.spring.io/milestone' } 9 | } 10 | 11 | dependencies { 12 | implementation 'org.springframework.cloud:spring-cloud-starter-zuul:1.0.0.RC1' 13 | } 14 | 15 | task resolve { 16 | doFirst { 17 | def files = project.configurations.compileClasspath.resolve() 18 | def output = new File("${buildDir}/resolved.txt") 19 | output.parentFile.mkdirs() 20 | files.collect { it.name }.each { output << "${it}\n" } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/resolutionSucceedsWhenDependencyReliesOnConstraintsFromPlatformDependencies.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url file("maven-repo") 9 | } 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation("test:platform-consumer:1.0"); 15 | } 16 | 17 | tasks.register("resolve") { 18 | doFirst { 19 | def files = project.configurations.runtimeClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/managedDependencyCanBeConfiguredUsingAGString.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | def springVersion = '4.1.5.RELEASE' 11 | 12 | dependencyManagement { 13 | dependencies { 14 | dependency "org.springframework:spring-core:$springVersion" 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/resolutionSucceedsWhenDependencyReliesOnDependencyManagementFromItsAncestors.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url file("maven-repo") 9 | } 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation("test:dependency-management-child:1.0"); 15 | } 16 | 17 | tasks.register("resolve") { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/directProjectDependenciesTakePrecedenceOverDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'test:child:1.0.0' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation project([path: ':child']) 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/dependency-management-parent/1.0/dependency-management-parent-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | test 8 | dependency-management-grandparent 9 | 1.0 10 | 11 | 12 | 13 | dependency-management-parent 14 | pom 15 | 16 | 17 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle-import-control.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomImportOrderIsReflectedInManagedVersions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.7.RELEASE' 13 | mavenBom 'io.spring.platform:platform-bom:2.0.0.RELEASE' 14 | } 15 | } 16 | 17 | task managedVersions { 18 | doFirst { 19 | def output = new File("${buildDir}/managed-versions.txt") 20 | output.parentFile.mkdirs() 21 | dependencyManagement.managedVersions.each { key, value -> 22 | output << "${key} -> ${value}\n" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/importOfABomCanUsePropertyMethodToReferenceAProperty.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | ext['platformVersion'] = '1.0.1.RELEASE' 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom "io.spring.platform:platform-bom:${property('platformVersion')}" 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/importedBomCanBeUsedToApplyDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | } 15 | dependencies { 16 | implementation 'org.springframework:spring-core' 17 | } 18 | 19 | task resolve { 20 | doFirst { 21 | def files = project.configurations.compileClasspath.resolve() 22 | def output = new File("${buildDir}/resolved.txt") 23 | output.parentFile.mkdirs() 24 | files.collect { it.name }.each { output << "${it}\n" } 25 | } 26 | } -------------------------------------------------------------------------------- /ci/tasks/build-ci-image.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | image_resource: 4 | type: registry-image 5 | source: 6 | repository: concourse/oci-build-task 7 | tag: 0.9.0 8 | inputs: 9 | - name: ci-images-git-repo 10 | outputs: 11 | - name: image 12 | caches: 13 | - path: ci-image-cache 14 | params: 15 | CONTEXT: ci-images-git-repo/ci/images 16 | DOCKERFILE: ci-images-git-repo/ci/images/((ci-image-name))/Dockerfile 17 | DOCKER_HUB_AUTH: ((docker-hub-auth)) 18 | run: 19 | path: /bin/sh 20 | args: 21 | - "-c" 22 | - | 23 | mkdir -p /root/.docker 24 | cat > /root/.docker/config.json < version/version 18 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyWithAnOtherwiseExcludedTransitiveDependencyOverridesTheExclude.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:direct-exclude:1.0' 15 | implementation 'org.springframework:spring-core:4.1.2.RELEASE' 16 | } 17 | 18 | task resolve { 19 | doFirst { 20 | def files = project.configurations.compileClasspath.resolve() 21 | def output = new File("${buildDir}/resolved.txt") 22 | output.parentFile.mkdirs() 23 | files.collect { it.name }.each { output << "${it}\n" } 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/pomExclusionsCanBeDisabled.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | applyMavenExclusions = false 15 | } 16 | dependencies { 17 | implementation 'org.springframework:spring-core' 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/propertyInABomCanBeOverriddenWhenItIsImported.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | 11 | dependencyManagement { 12 | imports { 13 | mavenBom('org.springframework.boot:spring-boot-dependencies:1.3.5.RELEASE') { 14 | bomProperties(['spring.version':'4.3.0.RELEASE']) 15 | } 16 | } 17 | } 18 | 19 | task managedVersions { 20 | doFirst { 21 | def output = new File("${buildDir}/managed-versions.txt") 22 | output.parentFile.mkdirs() 23 | dependencyManagement.managedVersions.each { key, value -> 24 | output << "${key} -> ${value}\n" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementIsAppliedToATransitiveDependencyDeclaredWithARange.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'com.google.guava:guava:18.0' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation 'org.assertj:assertj-guava:3.0.0' 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.runtimeClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsAreAppliedToDependenciesVersionedWithConstraints.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:transitive-exclude' 15 | constraints { 16 | implementation 'test:transitive-exclude:1.0' 17 | } 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsAreHandledCorrectlyForDependenciesThatAppearMultipleTimes.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | implementation("org.springframework.cloud:spring-cloud-starter-eureka:1.0.0.RELEASE") 12 | implementation("org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE") 13 | } 14 | 15 | task resolve { 16 | doFirst { 17 | def files = project.configurations.compileClasspath.resolve() 18 | def output = new File("${buildDir}/resolved.txt") 19 | output.parentFile.mkdirs() 20 | files.collect { it.name }.each { output << "${it}\n" } 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/platformConstrainingATransitiveDependencyDoesNotAccidentallyExcludeThatDependency.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url file("maven-repo") 9 | } 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation(platform("test:platform-with-constrained-transitive-dependency:1.0")) 15 | } 16 | 17 | tasks.register("resolve") { 18 | doFirst { 19 | def files = project.configurations.compileClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/jbossJavaEEBomCanBeImportedAndUsedForDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.jboss.spec:jboss-javaee-6.0:1.0.0.Final' 13 | } 14 | } 15 | dependencies { 16 | implementation 'org.jboss.spec.javax.el:jboss-el-api_2.2_spec' 17 | } 18 | 19 | task resolve { 20 | doFirst { 21 | def files = project.configurations.compileClasspath.resolve() 22 | def output = new File("${buildDir}/resolved.txt") 23 | output.parentFile.mkdirs() 24 | files.collect { it.name }.each { output << "${it}\n" } 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/whenImportingABomDependencyManagementWithNoVersionIsIgnored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:missing-managed-version-bom:1.0' 16 | } 17 | } 18 | 19 | task managedVersions { 20 | doFirst { 21 | def output = new File("${buildDir}/managed-versions.txt") 22 | output.parentFile.mkdirs() 23 | output.createNewFile() 24 | dependencyManagement.implementation.managedVersions.each { key, value -> 25 | output << "${key} -> ${value}\n" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/configurationCanBeReferredToByNameWhenConfiguringConfigurationSpecificDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | configurations("implementation") { 12 | dependencies { 13 | dependency 'org.springframework:spring-core:4.0.0.RELEASE' 14 | } 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.implementation.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/directExclusionDeclaredInABomIsHonored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:direct-exclude-bom:1.0' 16 | } 17 | } 18 | dependencies { 19 | implementation 'org.springframework:spring-tx:4.1.2.RELEASE' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/springCloudStarterParentBomCanBeImportedAndUsedForDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url 'https://repo.spring.io/milestone' 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:1.0.0.M3' 16 | } 17 | } 18 | 19 | 20 | task managedVersions { 21 | doFirst { 22 | def output = new File("${buildDir}/managed-versions.txt") 23 | output.parentFile.mkdirs() 24 | dependencyManagement.managedVersions.each { key, value -> 25 | output << "${key} -> ${value}\n" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/whenImportingABomDependencyManagementWithAClassifierIsIgnored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:dependency-management-with-classifier-bom:1.0' 16 | } 17 | } 18 | 19 | task managedVersions { 20 | doFirst { 21 | def output = new File("${buildDir}/managed-versions.txt") 22 | output.parentFile.mkdirs() 23 | output.createNewFile() 24 | dependencyManagement.implementation.managedVersions.each { key, value -> 25 | output << "${key} -> ${value}\n" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/wildcardExclusionDeclaredInABomIsHonored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:wildcard-exclude-bom:1.0' 16 | } 17 | } 18 | dependencies { 19 | implementation 'org.springframework:spring-tx:4.1.2.RELEASE' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementIsNotAppliedToADependencyUseLatestIntegration.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency "commons-logging:commons-logging:1.1.3" 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation "commons-logging:commons-logging:latest.integration" 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.runtimeClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/importedBomsVersionsCanBeOverridden.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | ext["spring.version"] = "4.0.5.RELEASE" 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 15 | } 16 | } 17 | 18 | dependencies { 19 | implementation 'org.springframework:spring-core' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/transitiveExclusionDeclaredInABomIsHonored.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:transitive-exclude-bom:1.0' 16 | } 17 | } 18 | dependencies { 19 | implementation 'org.springframework:spring-tx:4.1.2.RELEASE' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/transitiveProjectDependenciesTakePrecedenceOverDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'test:child:1.0.0' 13 | dependency 'test-other:grandchild:1.0.0' 14 | } 15 | } 16 | 17 | dependencies { 18 | implementation project([path: ':child']) 19 | } 20 | 21 | task resolve { 22 | doFirst { 23 | def files = project.configurations.runtimeClasspath.resolve() 24 | def output = new File("${buildDir}/resolved.txt") 25 | output.parentFile.mkdirs() 26 | files.collect { it.name }.each { output << "${it}\n" } 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/versionsOfDirectDependenciesTakePrecedenceOverDependencyManagementInAnImportedBom.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | } 15 | dependencies { 16 | implementation 'org.springframework:spring-core:4.0.4.RELEASE' 17 | } 18 | 19 | task resolve { 20 | doFirst { 21 | def files = project.configurations.compileClasspath.resolve() 22 | def output = new File("${buildDir}/resolved.txt") 23 | output.parentFile.mkdirs() 24 | files.collect { it.name }.each { output << "${it}\n" } 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementIsNotAppliedToAnInheritedDependencyUseLatestIntegration.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency "commons-logging:commons-logging:1.1.3" 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation "commons-logging:commons-logging:latest.integration" 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/versionsOfDirectDependenciesTakePrecedenceOverDirectDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'org.springframework:spring-core:4.0.4.RELEASE' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation 'org.springframework:spring-core:4.0.6.RELEASE' 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/configurationCanBeUsedDirectlyWhenConfiguringConfigurationSpecificDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | configurations(project.configurations.getByName("implementation")) { 12 | dependencies { 13 | dependency 'org.springframework:spring-core:4.0.0.RELEASE' 14 | } 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.implementation.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsInImportedBomsForUnresolvableDependenciesAreApplied.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | imports { 15 | mavenBom 'test:exclude-unresolvable-dependency:1.0' 16 | } 17 | } 18 | dependencies { 19 | implementation 'test:unresolvable-transitive-dependency' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/explicitDependencyPreventsTheDependencyFromBeingExcluded.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | } 15 | dependencies { 16 | implementation 'org.springframework:spring-core' 17 | implementation 'org.apache.hive:hive-common:0.14.0' 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/resolutionSucceedsWhenDependencyHasAnInvalidPom.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | // Invalid model version 12 | implementation("org.eclipse.platform:org.eclipse.core.contenttype:3.8.200") 13 | // Self-referential pom 14 | implementation("eu.fraho.spring:security-jwt-base-spring-boot-starter:4.6.7") 15 | } 16 | 17 | tasks.register("resolve") { 18 | doFirst { 19 | def files = project.configurations.runtimeClasspath.resolve() 20 | def output = new File("${buildDir}/resolved.txt") 21 | output.parentFile.mkdirs() 22 | files.collect { it.name }.each { output << "${it}\n" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/transitiveDependencyWithAnUnexcludedPathPreventsExclusion.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | } 15 | dependencies { 16 | implementation 'org.springframework:spring-core' 17 | implementation 'commons-logging:commons-logging:1.1.3' 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def files = project.configurations.compileClasspath.resolve() 23 | def output = new File("${buildDir}/resolved.txt") 24 | output.parentFile.mkdirs() 25 | files.collect { it.name }.each { output << "${it}\n" } 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/configurationSpecificDependencyManagementIsInheritedByExtendingConfigurations.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | implementation { 12 | dependencies { 13 | dependency 'commons-logging:commons-logging:1.1.1' 14 | } 15 | } 16 | } 17 | 18 | dependencies { 19 | testRuntimeOnly 'commons-logging:commons-logging' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.testRuntimeClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/illegal-system-path/1.0/illegal-system-path-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | illegal-system-path 8 | 1.0 9 | jar 10 | 11 | 12 | 13 | com.example 14 | whatever 15 | foo/bar/baz 16 | 1.0 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/versionOnADirectDependencyProvidesDependencyManagementToExtendingConfigurations.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | implementation { 12 | dependencies { 13 | dependency 'commons-logging:commons-logging:1.1.1' 14 | } 15 | } 16 | } 17 | 18 | dependencies { 19 | implementation 'commons-logging:commons-logging:1.1.3' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.testRuntimeClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/unresolvable-transitive-dependency/1.0/unresolvable-transitive-dependency-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | unresolvable-transitive-dependency 8 | 1.0 9 | jar 10 | 11 | 12 | 13 | test 14 | unresolvable-dependency 15 | 1.0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementWithExclusionsCanBeDeclaredInTheBuild.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency('org.springframework:spring-core:4.0.4.RELEASE') { 13 | exclude 'commons-logging:commons-logging' 14 | } 15 | } 16 | } 17 | 18 | dependencies { 19 | implementation 'org.springframework:spring-core' 20 | } 21 | 22 | task resolve { 23 | doFirst { 24 | def files = project.configurations.compileClasspath.resolve() 25 | def output = new File("${buildDir}/resolved.txt") 26 | output.parentFile.mkdirs() 27 | files.collect { it.name }.each { output << "${it}\n" } 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/propertyInABomCanBeConfiguredUsingAReferenceToAProjectProperty.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | project.ext['springVersion'] = '4.3.0.RELEASE' 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom('org.springframework.boot:spring-boot-dependencies:1.3.5.RELEASE') { 15 | bomProperties(['spring.version':springVersion]) 16 | } 17 | } 18 | } 19 | 20 | task managedVersions { 21 | doFirst { 22 | def output = new File("${buildDir}/managed-versions.txt") 23 | output.parentFile.mkdirs() 24 | dependencyManagement.managedVersions.each { key, value -> 25 | output << "${key} -> ${value}\n" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/missing-managed-version-bom/1.0/missing-managed-version-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | missing-managed-version-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | org.springframework 15 | spring-core 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/actions/publish-to-plugin-portal/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.gradle.plugin-publish" version "1.2.1" 3 | } 4 | 5 | tasks.register("publishExisting", com.gradle.publish.PublishExistingTask) { 6 | pluginId = "io.spring.dependency-management" 7 | fileRepositoryRoot = new File("${repositoryRoot}") 8 | pluginVersion = "${dependencyManagementPluginVersion}" 9 | pluginCoordinates = "io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}" 10 | displayName = "Dependency Management Plugin" 11 | pluginDescription = "A Gradle plugin that provides Maven-like dependency management functionality" 12 | website = "https://github.com/spring-gradle-plugins/dependency-management-plugin" 13 | vcsUrl = "https://github.com/spring-gradle-plugins/dependency-management-plugin" 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomImportOrderIsReflectedInManagedVersionsWhenSameBomIsImportedMultipleTimes.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:2.0.0.RELEASE' 13 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.7.RELEASE' 14 | mavenBom 'io.spring.platform:platform-bom:2.0.0.RELEASE' 15 | } 16 | } 17 | 18 | task managedVersions { 19 | doFirst { 20 | def output = new File("${buildDir}/managed-versions.txt") 21 | output.parentFile.mkdirs() 22 | dependencyManagement.managedVersions.each { key, value -> 23 | output << "${key} -> ${value}\n" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/whenOverridingABomPropertyAPropertyOnAnImportTakesPrecedenceOverAProjectProperty.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | project.ext['spring.version'] = '4.0.1.RELEASE' 11 | 12 | dependencyManagement { 13 | imports { 14 | mavenBom('org.springframework.boot:spring-boot-dependencies:1.3.5.RELEASE') { 15 | bomProperty 'spring.version', '4.3.0.RELEASE' 16 | } 17 | } 18 | } 19 | 20 | task managedVersions { 21 | doFirst { 22 | def output = new File("${buildDir}/managed-versions.txt") 23 | output.parentFile.mkdirs() 24 | dependencyManagement.managedVersions.each { key, value -> 25 | output << "${key} -> ${value}\n" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementCanBeDeclaredInTheBuild.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'org.springframework:spring-core:4.0.4.RELEASE' 13 | dependency ('commons-logging:commons-logging:1.1.2') { 14 | exclude 'foo:bar' 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation 'org.springframework:spring-core' 21 | } 22 | 23 | task resolve { 24 | doFirst { 25 | def files = project.configurations.compileClasspath.resolve() 26 | def output = new File("${buildDir}/resolved.txt") 27 | output.parentFile.mkdirs() 28 | files.collect { it.name }.each { output << "${it}\n" } 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/bravo-pom-customization-bom/1.0/bravo-pom-customization-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | bravo-pom-customization-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | bravo 15 | bravo 16 | 1.0 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsAreNotInheritedAndDoNotAffectTransitiveDependencies.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.0.RELEASE' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation 'org.codehaus.groovy:groovy' 18 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 19 | } 20 | 21 | task resolve { 22 | doFirst { 23 | def files = project.configurations.testRuntimeClasspath.resolve() 24 | def output = new File("${buildDir}/resolved.txt") 25 | output.parentFile.mkdirs() 26 | files.collect { it.name }.each { output << "${it}\n" } 27 | } 28 | } -------------------------------------------------------------------------------- /config/checkstyle/checkstyle-header.txt: -------------------------------------------------------------------------------- 1 | ^\Q/*\E$ 2 | ^\Q * Copyright \E20\d\d\-20\d\d\Q the original author or authors.\E$ 3 | ^\Q *\E$ 4 | ^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$ 5 | ^\Q * you may not use this file except in compliance with the License.\E$ 6 | ^\Q * You may obtain a copy of the License at\E$ 7 | ^\Q *\E$ 8 | ^\Q * https://www.apache.org/licenses/LICENSE-2.0\E$ 9 | ^\Q *\E$ 10 | ^\Q * Unless required by applicable law or agreed to in writing, software\E$ 11 | ^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$ 12 | ^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$ 13 | ^\Q * See the License for the specific language governing permissions and\E$ 14 | ^\Q * limitations under the License.\E$ 15 | ^\Q */\E$ 16 | ^$ 17 | ^.*$ 18 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionCanBeDeclaredOnAnEntryInADependencySet.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependencySet(group: 'org.springframework', version: '4.1.4.RELEASE') { 13 | entry('spring-core') { 14 | exclude 'commons-logging:commons-logging' 15 | } 16 | } 17 | } 18 | } 19 | 20 | dependencies { 21 | implementation 'org.springframework:spring-core' 22 | } 23 | 24 | task resolve { 25 | doFirst { 26 | def files = project.configurations.compileClasspath.resolve() 27 | def output = new File("${buildDir}/resolved.txt") 28 | output.parentFile.mkdirs() 29 | files.collect { it.name }.each { output << "${it}\n" } 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomPropertyCanBeUsedToVersionADependency.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | configurations { 11 | myConfiguration 12 | } 13 | 14 | dependencyManagement { 15 | imports { 16 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 17 | } 18 | } 19 | 20 | dependencies { 21 | myConfiguration "org.hibernate:hibernate-envers:${project.dependencyManagement.importedProperties['hibernate.version']}" 22 | } 23 | 24 | task resolve { 25 | doFirst { 26 | def files = project.configurations.myConfiguration.resolve() 27 | def output = new File("${buildDir}/resolved.txt") 28 | output.parentFile.mkdirs() 29 | files.collect { it.name }.each { output << "${it}\n" } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/actions/create-github-release/changelog-generator.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | repository: spring-gradle-plugins/dependency-management-plugin 3 | sections: 4 | - title: ":star: New Features" 5 | labels: 6 | - "type: enhancement" 7 | - title: ":lady_beetle: Bug Fixes" 8 | labels: 9 | - "type: bug" 10 | - "type: regression" 11 | - title: ":notebook_with_decorative_cover: Documentation" 12 | labels: 13 | - "type: documentation" 14 | - title: ":hammer: Dependency Upgrades" 15 | sort: "title" 16 | labels: 17 | - "type: dependency-upgrade" 18 | issues: 19 | ports: 20 | - label: "status: forward-port" 21 | bodyExpression: 'Forward port of issue #(\d+).*' 22 | - label: "status: back-port" 23 | bodyExpression: 'Back port of issue #(\d+).*' 24 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Central plugin classes. 19 | */ 20 | package io.spring.gradle.dependencymanagement; 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementBeingOverridenByDependenciesCanBeDisabled.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | overriddenByDependencies = false 12 | dependencies { 13 | dependency('org.springframework:spring-core:4.0.3.RELEASE') { 14 | exclude 'commons-logging:commons-logging' 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation 'org.springframework:spring-core:4.0.4.RELEASE' 21 | } 22 | 23 | task resolve { 24 | doFirst { 25 | def files = project.configurations.compileClasspath.resolve() 26 | def output = new File("${buildDir}/resolved.txt") 27 | output.parentFile.mkdirs() 28 | files.collect { it.name }.each { output << "${it}\n" } 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencySetCanBeUsedToProvideDependencyManagementForMultipleModulesWithTheSameGroupAndVersion.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependencySet(group: 'org.slf4j', version: '1.7.7') { 13 | entry 'slf4j-api' 14 | entry 'slf4j-simple' 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation 'org.slf4j:slf4j-api' 21 | implementation 'org.slf4j:slf4j-simple' 22 | } 23 | 24 | task resolve { 25 | doFirst { 26 | def files = project.configurations.compileClasspath.resolve() 27 | def output = new File("${buildDir}/resolved.txt") 28 | output.parentFile.mkdirs() 29 | files.collect { it.name }.each { output << "${it}\n" } 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/dependency-management-grandparent/1.0/dependency-management-grandparent-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | dependency-management-grandparent 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | org.springframework 15 | spring-core 16 | 5.3.27 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/first-alpha-dependency-management/1.0/first-alpha-dependency-management-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | first-alpha-dependency-management 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | alpha 15 | alpha 16 | 1.0 17 | runtime 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/second-alpha-dependency-management/1.0/second-alpha-dependency-management-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | second-alpha-dependency-management 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | alpha 15 | alpha 16 | 2.0 17 | runtime 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Classes that implement the plugin's DSL. 19 | */ 20 | package io.spring.gradle.dependencymanagement.dsl; 21 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal central plugin classes. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal; 21 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/dependency-management-child/1.0/dependency-management-child-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | test 8 | dependency-management-parent 9 | 1.0 10 | 11 | 12 | 13 | dependency-management-child 14 | jar 15 | 16 | 17 | 18 | org.springframework 19 | spring-core 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/malformed-exclude/1.0/malformed-exclude-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | malformed-exclude 8 | 1.0 9 | jar 10 | 11 | 12 | 13 | org.springframework 14 | spring-core 15 | 4.1.2.RELEASE 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/maven/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Classes that work with Gradle's Maven intergration. 19 | */ 20 | package io.spring.gradle.dependencymanagement.maven; 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/configurationSpecificDependencyManagementTakesPrecedenceOverGlobalDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'commons-logging:commons-logging:1.1.2' 13 | } 14 | implementation { 15 | dependencies { 16 | dependency 'commons-logging:commons-logging:1.1.1' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation 'org.springframework:spring-core:4.0.6.RELEASE' 23 | } 24 | 25 | task resolve { 26 | doFirst { 27 | def files = project.configurations.compileClasspath.resolve() 28 | def output = new File("${buildDir}/resolved.txt") 29 | output.parentFile.mkdirs() 30 | files.collect { it.name }.each { output << "${it}\n" } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal classes that implement the plugin's DSL. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.dsl; 21 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/pom/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal classes for modeling and resolving Maven poms. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.pom; 21 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/properties/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal classes for working with properties. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.properties; 21 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/bridge/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Bridge providing access to the plugin's internal classes. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.bridge; 21 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/dependency-management-with-classifier-bom/1.0/dependency-management-with-classifier-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | dependency-management-with-classifier-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | com.example 15 | module 16 | classified 17 | 1.0 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/report/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal classes for reporting a project's dependency management. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.report; 21 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/constraintsInTransitivePlatformDependenciesDoNotPreventExclusionsFromWorking.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'io.spring.dependency-management' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | 11 | dependencyManagement { 12 | dependencies { 13 | dependency('org.apache.xmlrpc:xmlrpc-client:3.1.3') { 14 | exclude 'junit:junit' 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation 'org.apache.xmlrpc:xmlrpc-client:3.1.3' 21 | implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4' 22 | } 23 | 24 | tasks.register("resolve") { 25 | doFirst { 26 | def files = project.configurations.compileClasspath.resolve() 27 | def output = new File("${buildDir}/resolved.txt") 28 | output.parentFile.mkdirs() 29 | files.collect { it.name }.each { output << "${it}\n" } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/maven/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal classes that use the Maven API to extract extract information from Maven poms. 19 | */ 20 | package io.spring.gradle.dependencymanagement.internal.maven; 21 | -------------------------------------------------------------------------------- /.github/actions/create-github-release/action.yml: -------------------------------------------------------------------------------- 1 | name: Create GitHub Release 2 | description: Create the release on GitHub with a changelog 3 | inputs: 4 | milestone: 5 | description: Name of the GitHub milestone for which a release will be created 6 | required: true 7 | token: 8 | description: Token to use for authentication with GitHub 9 | required: true 10 | runs: 11 | using: composite 12 | steps: 13 | - name: Generate Changelog 14 | uses: spring-io/github-changelog-generator@052892c62af51f8af87a9da6de55e70864b7df12 15 | with: 16 | milestone: ${{ inputs.milestone }} 17 | token: ${{ inputs.token }} 18 | config-file: .github/actions/create-github-release/changelog-generator.yml 19 | - name: Create GitHub Release 20 | shell: bash 21 | env: 22 | GITHUB_TOKEN: ${{ inputs.token }} 23 | run: gh release create ${{ format('v{0}', inputs.milestone) }} --notes-file changelog.md 24 | -------------------------------------------------------------------------------- /ci/scripts/sync-to-maven-central.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | buildName=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.name' ) 5 | buildNumber=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.number' ) 6 | packageName="io.spring.gradle.dependency-management" 7 | version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' ) 8 | 9 | echo "Syncing ${buildName}/${buildNumber} to Maven Central" 10 | curl \ 11 | -s \ 12 | --connect-timeout 240 \ 13 | --max-time 2700 \ 14 | -u ${BINTRAY_USERNAME}:${BINTRAY_PASSWORD} \ 15 | -H "Content-Type: application/json" -d "{\"username\": \"${SONATYPE_USER_TOKEN}\", \"password\": \"${SONATYPE_PASSWORD_TOKEN}\"}" \ 16 | -f \ 17 | -X \ 18 | POST "https://api.bintray.com/maven_central_sync/${BINTRAY_SUBJECT}/${BINTRAY_REPO}/${packageName}/versions/${version}" > /dev/null || { echo "Failed to sync" >&2; exit 1; } 19 | echo "Sync complete" -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyVersionsCanBeDefinedUsingProperties.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | ext['springVersion'] = '4.1.1.RELEASE' 11 | ext['slf4jVersion'] = '1.7.7' 12 | 13 | dependencyManagement { 14 | dependencies { 15 | dependency "org.springframework:spring-core:$springVersion" 16 | dependency "org.springframework:spring-beans:$springVersion" 17 | dependency "org.springframework:spring-tx:${project.ext['springVersion']}" 18 | dependencySet(group: 'org.slf4j', version: slf4jVersion) { 19 | entry 'slf4j-api' 20 | } 21 | } 22 | } 23 | 24 | task managedVersions { 25 | doFirst { 26 | def output = new File("${buildDir}/managed-versions.txt") 27 | output.parentFile.mkdirs() 28 | dependencyManagement.managedVersions.each { key, value -> 29 | output << "${key} -> ${value}\n" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/wildcard-exclude-bom/1.0/wildcard-exclude-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | wildcard-exclude-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | org.springframework 15 | spring-core 16 | 4.1.2.RELEASE 17 | 18 | 19 | commons-logging 20 | * 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/direct-exclude-bom/1.0/direct-exclude-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | direct-exclude-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | org.springframework 15 | spring-core 16 | 4.1.2.RELEASE 17 | 18 | 19 | commons-logging 20 | commons-logging 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ci/images/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | ########################################################### 5 | # UTILS 6 | ########################################################### 7 | 8 | export DEBIAN_FRONTEND=noninteractive 9 | apt-get update 10 | apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq unzip 11 | ln -fs /usr/share/zoneinfo/UTC /etc/localtime 12 | dpkg-reconfigure --frontend noninteractive tzdata 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh 16 | 17 | ########################################################### 18 | # JAVA 19 | ########################################################### 20 | JDK_URL=$( ./get-jdk-url.sh $1 ) 21 | 22 | mkdir -p /opt/openjdk 23 | cd /opt/openjdk 24 | curl -L ${JDK_URL} | tar zx --strip-components=1 25 | test -f /opt/openjdk/bin/java 26 | test -f /opt/openjdk/bin/javac 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/exclusionsAreNotInheritedAndDoNotAffectDirectDependencies.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencies { 14 | implementation 'test:direct-exclude:1.0' 15 | testImplementation 'commons-logging:commons-logging:1.1.3' 16 | } 17 | 18 | task resolveCompile { 19 | doFirst { 20 | def files = project.configurations.compileClasspath.resolve() 21 | def output = new File("${buildDir}/resolved-compile.txt") 22 | output.parentFile.mkdirs() 23 | files.collect { it.name }.each { output << "${it}\n" } 24 | } 25 | } 26 | 27 | task resolveTestCompile { 28 | doFirst { 29 | def files = project.configurations.testCompileClasspath.resolve() 30 | def output = new File("${buildDir}/resolved-test-compile.txt") 31 | output.parentFile.mkdirs() 32 | files.collect { it.name }.each { output << "${it}\n" } 33 | } 34 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/managedVersionsOfAConfigurationCanBeAccessed.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | implementation { 12 | imports { 13 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.7.RELEASE' 14 | } 15 | } 16 | } 17 | 18 | def verifyManagedVersion(def versions, def id, def expected) { 19 | def actual = versions[id] 20 | if (actual != expected) { 21 | throw new GradleException("Managed version for '${id}' was '${actual}' but '${expected}' was expected") 22 | } 23 | } 24 | 25 | 26 | task verify { 27 | doFirst { 28 | verifyManagedVersion(dependencyManagement.testImplementation.managedVersions, "org.springframework:spring-core", "4.1.8.RELEASE") 29 | verifyManagedVersion(dependencyManagement.getManagedVersionsForConfiguration(configurations.testImplementation), "org.springframework:spring-core", null) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/unresolvableDependenciesAreIgnoredWhenApplyingMavenStyleExclusions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { 9 | url file("maven-repo") 10 | } 11 | } 12 | 13 | dependencyManagement { 14 | dependencies { 15 | dependency('org.springframework:spring-core:4.0.3.RELEASE') { 16 | exclude 'commons-logging:commons-logging' 17 | } 18 | } 19 | } 20 | dependencies { 21 | implementation 'org.springframework:spring-core' 22 | implementation 'test:unresolvable-transitive-dependency:1.0' 23 | } 24 | 25 | configurations { 26 | implementation.exclude group: 'test', module: 'unresolvable-dependency' 27 | } 28 | 29 | task resolve { 30 | doFirst { 31 | def files = project.configurations.compileClasspath.resolve() 32 | def output = new File("${buildDir}/resolved.txt") 33 | output.parentFile.mkdirs() 34 | files.collect { it.name }.each { output << "${it}\n" } 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/transitive-exclude-bom/1.0/transitive-exclude-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | test 8 | transitive-exclude-bom 9 | 1.0 10 | pom 11 | 12 | 13 | 14 | 15 | org.springframework 16 | spring-tx 17 | 4.1.2.RELEASE 18 | 19 | 20 | commons-logging 21 | commons-logging 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/exclude-unresolvable-dependency/1.0/exclude-unresolvable-dependency-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | exclude-unresolvable-dependency 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | test 15 | unresolvable-transitive-dependency 16 | 1.0 17 | 18 | 19 | test 20 | unresolvable-dependency 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/bomImportOrderIsReflectedInManagedVersionsWhenThePomIsPublished.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | id 'maven-publish' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencyManagement { 12 | imports { 13 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.7.RELEASE' 14 | mavenBom 'io.spring.platform:platform-bom:2.0.0.RELEASE' 15 | } 16 | } 17 | 18 | publishing { 19 | publications { 20 | maven(MavenPublication) { 21 | groupId = 'group-id' 22 | artifactId = 'dep-management' 23 | version = '1.0' 24 | 25 | from components.java 26 | } 27 | } 28 | } 29 | 30 | 31 | task managedVersionsAfterPublishPom { 32 | dependsOn generatePomFileForMavenPublication 33 | doFirst { 34 | def output = new File("${buildDir}/managed-versions.txt") 35 | output.parentFile.mkdirs() 36 | dependencyManagement.managedVersions.each { key, value -> 37 | output << "${key} -> ${value}\n" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/direct-exclude/1.0/direct-exclude-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | direct-exclude 8 | 1.0 9 | jar 10 | 11 | 12 | 13 | org.springframework 14 | spring-core 15 | 4.1.2.RELEASE 16 | 17 | 18 | commons-logging 19 | commons-logging 20 | 21 | 22 | 23 | 24 | org.springframework 25 | spring-tx 26 | 4.1.2.RELEASE 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/transitive-exclude/1.0/transitive-exclude-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | transitive-exclude 8 | 1.0 9 | jar 10 | 11 | 12 | 13 | org.springframework 14 | spring-beans 15 | 4.1.2.RELEASE 16 | 17 | 18 | commons-logging 19 | commons-logging 20 | 21 | 22 | 23 | 24 | org.springframework 25 | spring-tx 26 | 4.1.2.RELEASE 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /.github/workflows/build-and-deploy-snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy Snapshot 2 | on: 3 | push: 4 | branches: 5 | - main 6 | permissions: 7 | contents: read 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | jobs: 11 | build: 12 | if: ${{ github.repository == 'spring-gradle-plugins/dependency-management-plugin' }} 13 | name: Build and Deploy Snapshot 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Check Out Code 17 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 18 | - name: Build 19 | uses: ./.github/actions/build 20 | with: 21 | develocity-access-key: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} 22 | - name: Deploy 23 | uses: ./.github/actions/deploy-to-artifactory 24 | with: 25 | build-name-version: '1.1.x' 26 | username: ${{ secrets.ARTIFACTORY_USERNAME }} 27 | password: ${{ secrets.ARTIFACTORY_PASSWORD }} 28 | signing-key: ${{ secrets.GPG_PRIVATE_KEY }} 29 | signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} 30 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementCanBeAppliedToASpecificConfiguration.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | configurations { 10 | managed 11 | unmanaged 12 | } 13 | 14 | dependencyManagement { 15 | managed { 16 | dependencies { 17 | dependency ('commons-logging:commons-logging:1.1.2') 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | managed 'org.springframework:spring-core:4.0.6.RELEASE' 24 | unmanaged 'org.springframework:spring-core:4.0.6.RELEASE' 25 | } 26 | 27 | task resolveManaged { 28 | doFirst { 29 | def files = project.configurations.managed.resolve() 30 | def output = new File("${buildDir}/resolved-managed.txt") 31 | output.parentFile.mkdirs() 32 | files.collect { it.name }.each { output << "${it}\n" } 33 | } 34 | } 35 | 36 | task resolveUnmanaged { 37 | doFirst { 38 | def files = project.configurations.unmanaged.resolve() 39 | def output = new File("${buildDir}/resolved-unmanaged.txt") 40 | output.parentFile.mkdirs() 41 | files.collect { it.name }.each { output << "${it}\n" } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/alpha-pom-customization-bom/1.0/alpha-pom-customization-bom-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | test 7 | alpha-pom-customization-bom 8 | 1.0 9 | pom 10 | 11 | 12 | 13 | 14 | alpha 15 | alpha 16 | 1.0 17 | runtime 18 | foo 19 | 20 | 21 | commons-logging 22 | commons-logging 23 | 24 | 25 | foo 26 | bar 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-a/1.0/platform-a-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 4.0.0 10 | test 11 | platform-a 12 | 1.0 13 | pom 14 | 15 | 16 | 17 | org.springframework 18 | spring-core 19 | 5.3.27 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-with-dependencies/1.0/platform-with-dependencies-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 4.0.0 10 | test 11 | platform-with-dependencies 12 | 1.0 13 | pom 14 | 15 | 16 | org.springframework 17 | spring-core 18 | 5.3.27 19 | compile 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/whenDependencyIsSubstitutedNewCoordinatesAreUsedForDependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | project.configurations.all { 3 | resolutionStrategy.eachDependency { 4 | if (requested.group == "org.bouncycastle" && requested.name == "bcprov-jdk15on") { 5 | useTarget("org.bouncycastle:bcprov-jdk18on:1.78.1") 6 | } 7 | } 8 | } 9 | } 10 | 11 | plugins { 12 | id "java" 13 | id "io.spring.dependency-management" 14 | } 15 | 16 | /* 17 | configurations.all { 18 | resolutionStrategy.eachDependency { 19 | if (requested.group == "org.bouncycastle" && requested.name == "bcprov-jdk15on") { 20 | useTarget("org.bouncycastle:bcprov-jdk18on:1.78.1") 21 | } 22 | } 23 | } 24 | */ 25 | 26 | repositories { 27 | mavenCentral() 28 | } 29 | 30 | dependencies { 31 | implementation("org.bouncycastle:bcprov-jdk15on:1.70") 32 | } 33 | 34 | task resolve { 35 | doFirst { 36 | def files = project.configurations.compileClasspath.resolve() 37 | def output = new File("${buildDir}/resolved.txt") 38 | output.parentFile.mkdirs() 39 | files.collect { it.name }.each { output << "${it}\n" } 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/propertiesImportedFromABomCanBeAccessed.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | configurations { 11 | myConfiguration 12 | } 13 | 14 | dependencyManagement { 15 | imports { 16 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 17 | } 18 | myConfiguration { 19 | imports { 20 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.1.RELEASE' 21 | } 22 | } 23 | } 24 | 25 | def verifyImportedProperty(def properties, def name, def expected) { 26 | def actual = properties[name] 27 | if (actual != expected) { 28 | throw new GradleException("Property named '${name}' was '${actual}' but '${expected}' was expected") 29 | } 30 | } 31 | 32 | 33 | task verify { 34 | doFirst { 35 | verifyImportedProperty(dependencyManagement.importedProperties, "hibernate.version", "4.3.5.Final") 36 | verifyImportedProperty(dependencyManagement.myConfiguration.importedProperties, "spring.version", "4.1.4.RELEASE") 37 | verifyImportedProperty(dependencyManagement.myConfiguration.importedProperties, "jruby.version", "1.7.12") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/userProvidedResolutionStrategyRunsAfterInternalResolutionStrategy.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'org.springframework:spring-core:4.2.6.RELEASE' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation 'org.springframework:spring-core:#' 18 | } 19 | 20 | Closure versionStrategy = { 21 | it.eachDependency(new Action() { 22 | 23 | @Override 24 | void execute(DependencyResolveDetails details) { 25 | if (details.target.name == 'spring-core') { 26 | details.useVersion('4.2.6.RELEASE') 27 | } 28 | } 29 | 30 | }) 31 | } 32 | 33 | dependencyManagement.resolutionStrategy versionStrategy 34 | 35 | configurations.all { 36 | resolutionStrategy versionStrategy 37 | } 38 | 39 | task resolve { 40 | doFirst { 41 | def files = project.configurations.compileClasspath.resolve() 42 | def output = new File("${buildDir}/resolved.txt") 43 | output.parentFile.mkdirs() 44 | files.collect { it.name }.each { output << "${it}\n" } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dependency Management Plugin 2 | 3 | A Gradle plugin that provides Maven-like dependency management and exclusions. The 4 | plugin provides a DSL to configure dependency management directly and by importing 5 | existing Maven boms. Based on the configured dependency management, the plugin will 6 | control the versions of your project's direct and transitive dependencies and will honour 7 | any exclusions declared in the poms of your project's dependencies and any imported boms. 8 | 9 | To learn more about using the Dependency Management Plugin, please refer to its 10 | [reference documentation][1]. 11 | 12 | ## Contributing 13 | 14 | Contributors to this project agree to uphold its [code of conduct][2]. 15 | [Pull requests][3] are welcome. Please see the [contributor guidelines][4] for details. 16 | 17 | ## Licence 18 | 19 | Dependency Management Plugin is open source software released under the [Apache 2.0 20 | license][5]. 21 | 22 | [1]: https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/ 23 | [2]: CODE_OF_CONDUCT.md 24 | [3]: https://help.github.com/articles/using-pull-requests/ 25 | [4]: CONTRIBUTING.md 26 | [5]: https://www.apache.org/licenses/LICENSE-2.0.html 27 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-b/1.0/platform-b-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 4.0.0 10 | test 11 | platform-b 12 | 1.0 13 | pom 14 | 15 | 16 | 17 | test 18 | platform-a 19 | 1.0 20 | pom 21 | import 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/properties/PropertySource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.properties; 18 | 19 | /** 20 | * A source for properties. 21 | * 22 | * @author Andy Wilkinson 23 | */ 24 | @FunctionalInterface 25 | public interface PropertySource { 26 | 27 | /** 28 | * Returns the property with the given {@code name} or {@code null} if the source has 29 | * no such property. 30 | * @param name name of the property 31 | * @return the property or {@code null} 32 | */ 33 | Object getProperty(String name); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-a/1.0/platform-a-1.0.module: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": "1.1", 3 | "component": { 4 | "group": "test", 5 | "module": "platform-a", 6 | "version": "1.0", 7 | "attributes": { 8 | "org.gradle.status": "release" 9 | } 10 | }, 11 | "createdBy": { 12 | "gradle": { 13 | "version": "8.1.1" 14 | } 15 | }, 16 | "variants": [ 17 | { 18 | "name": "apiElements", 19 | "attributes": { 20 | "org.gradle.category": "platform", 21 | "org.gradle.usage": "java-api" 22 | }, 23 | "dependencyConstraints": [ 24 | { 25 | "group": "org.springframework", 26 | "module": "spring-core", 27 | "version": { 28 | "requires": "5.3.27" 29 | } 30 | } 31 | ] 32 | }, 33 | { 34 | "name": "runtimeElements", 35 | "attributes": { 36 | "org.gradle.category": "platform", 37 | "org.gradle.usage": "java-runtime" 38 | }, 39 | "dependencyConstraints": [ 40 | { 41 | "group": "org.springframework", 42 | "module": "spring-core", 43 | "version": { 44 | "requires": "5.3.27" 45 | } 46 | } 47 | ] 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/GVCIT/pluginIsCompatible.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "io.spring.dependency-management" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'org.springframework.boot:spring-boot-dependencies:1.4.2.RELEASE' 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation('org.springframework.boot:spring-boot-starter') 18 | } 19 | 20 | task resolve { 21 | doFirst { 22 | def names = configurations.runtimeClasspath.resolve().collect { it.name } 23 | if (!names.containsAll("spring-boot-starter-1.4.2.RELEASE.jar", "spring-boot-1.4.2.RELEASE.jar", 24 | "spring-boot-autoconfigure-1.4.2.RELEASE.jar", 25 | "spring-boot-starter-logging-1.4.2.RELEASE.jar", "spring-core-4.3.4.RELEASE.jar", 26 | "snakeyaml-1.17.jar", "spring-context-4.3.4.RELEASE.jar", "logback-classic-1.1.7.jar", 27 | "jcl-over-slf4j-1.7.21.jar", "jul-to-slf4j-1.7.21.jar", "log4j-over-slf4j-1.7.21.jar", 28 | "spring-aop-4.3.4.RELEASE.jar", "spring-beans-4.3.4.RELEASE.jar", 29 | "spring-expression-4.3.4.RELEASE.jar", "logback-core-1.1.7.jar", "slf4j-api-1.7.21.jar")) { 30 | throw new RuntimeException("Dependencies were not resolved as expected. Names were $names") 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-with-dependencies/1.0/platform-with-dependencies-1.0.module: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": "1.1", 3 | "component": { 4 | "group": "test", 5 | "module": "platform-with-dependencies", 6 | "version": "1.0", 7 | "attributes": { 8 | "org.gradle.status": "release" 9 | } 10 | }, 11 | "createdBy": { 12 | "gradle": { 13 | "version": "8.1.1" 14 | } 15 | }, 16 | "variants": [ 17 | { 18 | "name": "apiElements", 19 | "attributes": { 20 | "org.gradle.category": "platform", 21 | "org.gradle.usage": "java-api" 22 | }, 23 | "dependencies": [ 24 | { 25 | "group": "org.springframework", 26 | "module": "spring-core", 27 | "version": { 28 | "requires": "5.3.27" 29 | } 30 | } 31 | ] 32 | }, 33 | { 34 | "name": "runtimeElements", 35 | "attributes": { 36 | "org.gradle.category": "platform", 37 | "org.gradle.usage": "java-runtime" 38 | }, 39 | "dependencies": [ 40 | { 41 | "group": "org.springframework", 42 | "module": "spring-core", 43 | "version": { 44 | "requires": "6.0.12" 45 | } 46 | } 47 | ] 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementCanBeDeclaredInTheBuildUsingTheNewSyntax.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | dependencies { 12 | dependency 'org.springframework:spring-core:4.0.4.RELEASE' 13 | dependency('commons-logging:commons-logging:1.1.2') { 14 | exclude 'foo:bar' 15 | } 16 | dependency group:'alpha', name: 'bravo', version: '1.0' 17 | dependency(group:'charlie', name: 'delta', version: '2.0') { 18 | exclude group:'bar', name:'baz' 19 | } 20 | } 21 | } 22 | 23 | 24 | task managedVersions { 25 | doFirst { 26 | def output = new File("${buildDir}/managed-versions.txt") 27 | output.parentFile.mkdirs() 28 | dependencyManagement.managedVersions.each { key, value -> 29 | output << "${key} -> ${value}\n" 30 | } 31 | } 32 | } 33 | 34 | task exclusions { 35 | doFirst { 36 | def output = new File("${buildDir}/exclusions.txt") 37 | output.parentFile.mkdirs() 38 | def exclusions = project.dependencyManagement.dependencyManagementContainer.getExclusions(null) 39 | exclusions.exclusionsByDependency.each { key, value -> 40 | output << "${key} -> " 41 | output << value.collect { "${it.groupId}:${it.artifactId}" } 42 | output << "\n" 43 | } 44 | 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/DependencyHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * A handler for configuring a managed dependency. 23 | * 24 | * @author Andy Wilkinson 25 | */ 26 | public interface DependencyHandler { 27 | 28 | /** 29 | * Adds the given exclusion in the form {@code group:name}. 30 | * @param exclusion the exclusion 31 | */ 32 | void exclude(String exclusion); 33 | 34 | /** 35 | * Adds the given exclusion using the {@code group} and {@code name} entries in the 36 | * map. 37 | * @param exclusion the exclusion 38 | */ 39 | void exclude(Map exclusion); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-consumer/1.0/platform-consumer-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 4.0.0 10 | test 11 | platform-consumer 12 | 1.0 13 | 14 | 15 | 16 | test 17 | platform-b 18 | 1.0 19 | pom 20 | import 21 | 22 | 23 | 24 | 25 | 26 | org.springframework 27 | spring-core 28 | runtime 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/Versions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal; 18 | 19 | import java.util.Arrays; 20 | import java.util.Collections; 21 | import java.util.HashSet; 22 | import java.util.Set; 23 | 24 | /** 25 | * Utility methods for working with dependency versions. 26 | * 27 | * @author Andy Wilkinson 28 | */ 29 | final class Versions { 30 | 31 | private static final Set DYNAMIC_PREFIXES = Collections 32 | .unmodifiableSet(new HashSet<>(Arrays.asList("latest.", "[", "]", "("))); 33 | 34 | private Versions() { 35 | } 36 | 37 | static boolean isDynamic(String version) { 38 | return DYNAMIC_PREFIXES.stream().anyMatch(version::startsWith) || version.endsWith("+"); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/properties/MapPropertySource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.properties; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * A {@link PropertySource} backs by a {@link Map}. 23 | * 24 | * @author Andy Wilkinson 25 | */ 26 | public class MapPropertySource implements PropertySource { 27 | 28 | private final Map properties; 29 | 30 | /** 31 | * Creates a new {@code MapPropertySource} backed by the given {@map}. 32 | * @param map the map 33 | */ 34 | public MapPropertySource(Map map) { 35 | this.properties = map; 36 | } 37 | 38 | @Override 39 | public Object getProperty(String name) { 40 | return this.properties.get(name); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/GeneratedPomCustomizationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | /** 20 | * A handler for configuring the customization of generated POMs. 21 | * 22 | * @author Andy Wilkinson 23 | */ 24 | public interface GeneratedPomCustomizationHandler { 25 | 26 | /** 27 | * Sets whether or not customization of generated poms is enabled. Defaults to 28 | * {@code true}. 29 | * @param enabled whether or not customization is enabled 30 | */ 31 | void setEnabled(boolean enabled); 32 | 33 | /** 34 | * Sets whether or not customization of generated poms is enabled. Defaults to 35 | * {@code true}. 36 | * @param enabled whether or not customization is enabled 37 | */ 38 | void enabled(boolean enabled); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-b/1.0/platform-b-1.0.module: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": "1.1", 3 | "component": { 4 | "group": "test", 5 | "module": "platform-b", 6 | "version": "1.0", 7 | "attributes": { 8 | "org.gradle.status": "release" 9 | } 10 | }, 11 | "createdBy": { 12 | "gradle": { 13 | "version": "8.1.1" 14 | } 15 | }, 16 | "variants": [ 17 | { 18 | "name": "apiElements", 19 | "attributes": { 20 | "org.gradle.category": "platform", 21 | "org.gradle.usage": "java-api" 22 | }, 23 | "dependencies": [ 24 | { 25 | "group": "test", 26 | "module": "platform-a", 27 | "version": { 28 | "requires": "1.0" 29 | }, 30 | "attributes": { 31 | "org.gradle.category": "platform" 32 | }, 33 | "endorseStrictVersions": true 34 | } 35 | ] 36 | }, 37 | { 38 | "name": "runtimeElements", 39 | "attributes": { 40 | "org.gradle.category": "platform", 41 | "org.gradle.usage": "java-runtime" 42 | }, 43 | "dependencies": [ 44 | { 45 | "group": "test", 46 | "module": "platform-a", 47 | "version": { 48 | "requires": "1.0" 49 | }, 50 | "attributes": { 51 | "org.gradle.category": "platform" 52 | }, 53 | "endorseStrictVersions": true 54 | } 55 | ] 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-with-constrained-transitive-dependency/1.0/platform-with-constrained-transitive-dependency-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 4.0.0 10 | test 11 | platform-with-constrained-transitive-dependency 12 | 1.0 13 | pom 14 | 15 | 16 | 17 | com.squareup.okio 18 | okio 19 | 3.6.0 20 | 21 | 22 | 23 | 24 | 25 | com.squareup.okhttp3 26 | okhttp 27 | 4.11.0 28 | compile 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.github/actions/deploy-to-artifactory/action.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Artifactory 2 | description: Deploys artifacts to Artifactory 3 | inputs: 4 | build-name-version: 5 | description: 'Version to append to the build name' 6 | required: true 7 | repository: 8 | description: 'Artifactory repository to deploy to' 9 | required: false 10 | default: 'plugins-snapshot-local' 11 | username: 12 | description: 'Username for authentication with Artifactory' 13 | required: true 14 | password: 15 | description: 'Password for authentication with Artifactory' 16 | required: true 17 | signing-key: 18 | description: 'Key used to sign artifacts' 19 | required: true 20 | signing-passphrase: 21 | description: 'Passphrase for the signing key' 22 | required: true 23 | runs: 24 | using: composite 25 | steps: 26 | - name: Deploy 27 | uses: spring-io/artifactory-deploy-action@26bbe925a75f4f863e1e529e85be2d0093cac116 # v0.0.1 28 | with: 29 | artifact-properties: | 30 | /**/dependency-management-plugin-*.zip::zip.type=docs,zip.deployed=false 31 | build-name: ${{ format('dependency-management-plugin-{0}', inputs.build-name-version) }} 32 | folder: 'artifactory' 33 | username: ${{ inputs.username }} 34 | password: ${{ inputs.password }} 35 | repository: ${{ inputs.repository }} 36 | signing-key: ${{ inputs.signing-key }} 37 | signing-passphrase: ${{ inputs.signing-passphrase }} 38 | uri: 'https://repo.spring.io' 39 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/MavenBomHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * Handler for customizing the import of a Maven bom. 23 | * 24 | * @author Andy Wilkinson 25 | * @see ImportsHandler#mavenBom(String, groovy.lang.Closure) 26 | */ 27 | public interface MavenBomHandler { 28 | 29 | /** 30 | * Configures a property to be used when resolving the contents of the imported bom. 31 | * @param name the name of the property 32 | * @param value the value of the property 33 | */ 34 | void bomProperty(String name, String value); 35 | 36 | /** 37 | * Configures properties to be used when resolving the contents of the imported bom. 38 | * @param properties the properties 39 | */ 40 | void bomProperties(Map properties); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/maven/PropertySourceValueSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.maven; 18 | 19 | import io.spring.gradle.dependencymanagement.internal.properties.PropertySource; 20 | import io.spring.gradle.dependencymanagement.org.codehaus.plexus.interpolation.AbstractValueSource; 21 | 22 | /** 23 | * An {@link AbstractValueSource} backed by a {@link PropertySource}. 24 | * 25 | * @author Andy Wilkinson 26 | */ 27 | class PropertySourceValueSource extends AbstractValueSource { 28 | 29 | private final PropertySource propertySource; 30 | 31 | PropertySourceValueSource(PropertySource propertySource) { 32 | super(false); 33 | this.propertySource = propertySource; 34 | } 35 | 36 | @Override 37 | public Object getValue(String name) { 38 | return this.propertySource.getProperty(name); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/dependencyManagementCanBeAppliedToMultipleSpecificConfigurations.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | configurations { 10 | managed1 11 | managed2 12 | unmanaged 13 | } 14 | 15 | dependencyManagement { 16 | configurations(managed1, managed2) { 17 | dependencies { 18 | dependency ('commons-logging:commons-logging:1.1.2') 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | managed1 'org.springframework:spring-core:4.0.6.RELEASE' 25 | managed2 'org.springframework:spring-core:4.0.6.RELEASE' 26 | unmanaged 'org.springframework:spring-core:4.0.6.RELEASE' 27 | } 28 | 29 | task resolveManaged1 { 30 | doFirst { 31 | def files = project.configurations.managed2.resolve() 32 | def output = new File("${buildDir}/resolved-managed1.txt") 33 | output.parentFile.mkdirs() 34 | files.collect { it.name }.each { output << "${it}\n" } 35 | } 36 | } 37 | 38 | task resolveManaged2 { 39 | doFirst { 40 | def files = project.configurations.managed1.resolve() 41 | def output = new File("${buildDir}/resolved-managed2.txt") 42 | output.parentFile.mkdirs() 43 | files.collect { it.name }.each { output << "${it}\n" } 44 | } 45 | } 46 | 47 | task resolveUnmanaged { 48 | doFirst { 49 | def files = project.configurations.unmanaged.resolve() 50 | def output = new File("${buildDir}/resolved-unmanaged.txt") 51 | output.parentFile.mkdirs() 52 | files.collect { it.name }.each { output << "${it}\n" } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/ClosureBackedAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import groovy.lang.Closure; 20 | import org.gradle.api.Action; 21 | 22 | /** 23 | * An {@link Action} that's backed by a {@link Closure}. 24 | * 25 | * @param the type handled by this action 26 | * @author Andy Wilkinson 27 | */ 28 | class ClosureBackedAction implements Action { 29 | 30 | private final Closure closure; 31 | 32 | ClosureBackedAction(Closure closure) { 33 | this.closure = closure; 34 | } 35 | 36 | @Override 37 | public void execute(T delegate) { 38 | this.closure.setResolveStrategy(Closure.DELEGATE_FIRST); 39 | this.closure.setDelegate(delegate); 40 | if (this.closure.getMaximumNumberOfParameters() == 0) { 41 | this.closure.call(); 42 | } 43 | else { 44 | this.closure.call(delegate); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/maven/PomDependencyManagementConfigurer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.maven; 18 | 19 | import groovy.util.Node; 20 | import org.gradle.api.Action; 21 | import org.gradle.api.XmlProvider; 22 | 23 | /** 24 | * A {@code PomDependencyManagementConfigurer} is used to configure the dependency 25 | * management of a Gradle-generated Maven pom. 26 | * 27 | * @author Andy Wilkinson 28 | */ 29 | public interface PomDependencyManagementConfigurer extends Action { 30 | 31 | /** 32 | * Configures the dependency management of the pom that's available from the given 33 | * {@code xmlProvider}. 34 | * @param xmlProvider the provider of the pom's XML 35 | */ 36 | @Override 37 | void execute(XmlProvider xmlProvider); 38 | 39 | /** 40 | * Configures the dependency management of the given {@code pom}. 41 | * @param pom the pom to configure 42 | */ 43 | void configurePom(Node pom); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /.github/actions/build/action.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | description: Builds the plugin 3 | inputs: 4 | develocity-access-key: 5 | description: Access key for authentication with https://ge.spring.io 6 | required: true 7 | outputs: 8 | version: 9 | description: 'The version that was built' 10 | value: ${{ steps.read-version.outputs.version }} 11 | runs: 12 | using: composite 13 | steps: 14 | - name: Set up Java 15 | uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 16 | with: 17 | distribution: 'liberica' 18 | java-version: 8 19 | - name: Set Up Gradle 20 | uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 21 | - name: Configure Gradle Properties 22 | shell: bash 23 | run: | 24 | mkdir -p $HOME/.gradle 25 | echo 'systemProp.user.name=spring-builds+github' >> $HOME/.gradle/gradle.properties 26 | echo 'systemProp.org.gradle.internal.launcher.welcomeMessageEnabled=false' >> $HOME/.gradle/gradle.properties 27 | echo 'org.gradle.daemon=false' >> $HOME/.gradle/gradle.properties 28 | - name: Build and Publish 29 | shell: bash 30 | env: 31 | DEVELOCITY_ACCESS_KEY: ${{ inputs.develocity-access-key }} 32 | run: ./gradlew -PdeploymentRepository=$(pwd)/artifactory build publishAllPublicationsToDeploymentRepository 33 | - name: Read Version From gradle.properties 34 | id: read-version 35 | shell: bash 36 | run: | 37 | version=$(sed -n 's/version=\(.*\)/\1/p' gradle.properties) 38 | echo "Version is $version" 39 | echo "version=$version" >> $GITHUB_OUTPUT 40 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/DependencyManagementHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * A handler for configuring and accessing dependency management. 23 | * 24 | * @author Andy Wilkinson 25 | */ 26 | public interface DependencyManagementHandler extends DependencyManagementConfigurer { 27 | 28 | /** 29 | * Returns the properties from any imported boms. 30 | * @return the imported properties 31 | */ 32 | Map getImportedProperties(); 33 | 34 | /** 35 | * Returns a map of the managed versions for the configuration associated with this 36 | * handler. The entire {@link org.gradle.api.artifacts.Configuration#getHierarchy()} 37 | * configuration hierarchy} is considered. The key-value pairs in the map have the 38 | * form {@code group:name = version}. 39 | * @return the managed versions 40 | */ 41 | Map getManagedVersions(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/StandardGeneratedPomCustomizationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import io.spring.gradle.dependencymanagement.dsl.GeneratedPomCustomizationHandler; 20 | import io.spring.gradle.dependencymanagement.internal.DependencyManagementSettings.PomCustomizationSettings; 21 | 22 | /** 23 | * Standard implementation of {@link GeneratedPomCustomizationHandler}. 24 | * 25 | * @author Andy Wilkinson 26 | */ 27 | class StandardGeneratedPomCustomizationHandler implements GeneratedPomCustomizationHandler { 28 | 29 | private final PomCustomizationSettings settings; 30 | 31 | StandardGeneratedPomCustomizationHandler(PomCustomizationSettings settings) { 32 | this.settings = settings; 33 | } 34 | 35 | @Override 36 | public void setEnabled(boolean enabled) { 37 | this.settings.setEnabled(enabled); 38 | } 39 | 40 | @Override 41 | public void enabled(boolean enabled) { 42 | this.settings.setEnabled(enabled); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/properties/ProjectPropertySource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.properties; 18 | 19 | import org.gradle.api.Project; 20 | 21 | /** 22 | * A {@link PropertySource} backed by a {@link Project}. 23 | * 24 | * @author Andy Wilkinson 25 | * @see Project#hasProperty(String) 26 | */ 27 | public class ProjectPropertySource implements PropertySource { 28 | 29 | private final Project project; 30 | 31 | /** 32 | * Creates a new {@link ProjectPropertySource} backed by the given {@code project}. 33 | * @param project the project 34 | */ 35 | public ProjectPropertySource(Project project) { 36 | this.project = project; 37 | } 38 | 39 | @Override 40 | public String getProperty(String name) { 41 | if ("version".equals(name)) { 42 | return null; 43 | } 44 | if (this.project.hasProperty(name)) { 45 | Object property = this.project.property(name); 46 | if (property != null) { 47 | return property.toString(); 48 | } 49 | } 50 | return null; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/properties/CompositePropertySource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.properties; 18 | 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import java.util.Objects; 22 | 23 | /** 24 | * A {@link PropertySource} that delegates to other property sources. 25 | * 26 | * @author Andy Wilkinson 27 | */ 28 | public class CompositePropertySource implements PropertySource { 29 | 30 | private final List delegates; 31 | 32 | /** 33 | * Creates a new {@code CompositePropertySource} that will delegate to the given 34 | * {@code delegates}. 35 | * @param delegates the delegates 36 | */ 37 | public CompositePropertySource(PropertySource... delegates) { 38 | this.delegates = Arrays.asList(delegates); 39 | } 40 | 41 | @Override 42 | public Object getProperty(String name) { 43 | return this.delegates.stream() 44 | .map((delegate) -> delegate.getProperty(name)) 45 | .filter(Objects::nonNull) 46 | .findFirst() 47 | .orElse(null); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /.github/actions/publish-to-plugin-portal/action.yml: -------------------------------------------------------------------------------- 1 | name: Publish Gradle Plugin 2 | description: Publishes the plugin to Gradle's Plugin Portal 3 | inputs: 4 | jfrog-cli-config-token: 5 | description: 'Config token for the JFrog CLI' 6 | required: true 7 | plugin-version: 8 | description: 'Version of the plugin' 9 | required: true 10 | gradle-plugin-publish-key: 11 | description: 'Gradle publishing key' 12 | required: true 13 | gradle-plugin-publish-secret: 14 | description: 'Gradle publishing secret' 15 | required: true 16 | build-number: 17 | description: 'The build number to use when downloading plugin artifacts' 18 | required: false 19 | default: ${{ github.run_number }} 20 | runs: 21 | using: composite 22 | steps: 23 | - name: Set Up JFrog CLI 24 | uses: jfrog/setup-jfrog-cli@d82fe26823e1f25529250895d5673f65b02af085 # v4.0.1 25 | env: 26 | JF_ENV_SPRING: ${{ inputs.jfrog-cli-config-token }} 27 | - name: Download Artifacts 28 | shell: bash 29 | run: jf rt download --spec ${{ format('{0}/artifacts.spec', github.action_path) }} --spec-vars 'buildName=${{ format('dependency-management-plugin-{0}', inputs.plugin-version) }};buildNumber=${{ inputs.build-number }}' 30 | - name: Set Up Java 31 | uses: actions/setup-java@v4 32 | with: 33 | distribution: 'liberica' 34 | java-version: '17' 35 | - name: Publish 36 | shell: bash 37 | working-directory: ${{ github.action_path }} 38 | run: ${{ github.workspace }}/gradlew publishExisting -Pgradle.publish.key=${{ inputs.gradle-plugin-publish-key }} -Pgradle.publish.secret=${{ inputs.gradle-plugin-publish-secret }} -PdependencyManagementPluginVersion=${{ inputs.plugin-version }} -PrepositoryRoot=${{ github.workspace }}/gradle-plugin-portal 39 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/Exclusions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal; 18 | 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.HashSet; 22 | import java.util.Map; 23 | import java.util.Set; 24 | 25 | /** 26 | * A set of dependency exclusions. 27 | * 28 | * @author Andy Wilkinson 29 | */ 30 | class Exclusions { 31 | 32 | private final Map> exclusionsByDependency = new HashMap<>(); 33 | 34 | void add(String dependency, Collection exclusionsForDependency) { 35 | if (exclusionsForDependency.isEmpty()) { 36 | return; 37 | } 38 | this.exclusionsByDependency.computeIfAbsent(dependency, (key) -> new HashSet<>()) 39 | .addAll(exclusionsForDependency); 40 | } 41 | 42 | void addAll(Exclusions exclusions) { 43 | exclusions.exclusionsByDependency.forEach(this::add); 44 | } 45 | 46 | Set exclusionsForDependency(String dependency) { 47 | return this.exclusionsByDependency.get(dependency); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return this.exclusionsByDependency.toString(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/io/spring/gradle/dependencymanagement/VersionsPluginCompatibilityIntegerationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement; 18 | 19 | import org.gradle.testkit.runner.BuildResult; 20 | import org.gradle.testkit.runner.TaskOutcome; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.extension.RegisterExtension; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * Tests that verify the plugin's compatibility with the "); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/pom/PomResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.pom; 18 | 19 | import java.util.List; 20 | 21 | import io.spring.gradle.dependencymanagement.internal.properties.PropertySource; 22 | 23 | /** 24 | * A {@code PomResolver} creates {@link Pom Poms} from {@link PomReference PomReferences}. 25 | * 26 | * @author Andy Wilkinson 27 | */ 28 | public interface PomResolver { 29 | 30 | /** 31 | * Resolves the given {@code pomReferences}, failing if any references cannot be 32 | * resolved. 33 | * @param pomReferences the pom references to resolve 34 | * @param properties properties to apply to the resolution of each pom reference 35 | * @return the poms resolved from the references 36 | */ 37 | List resolvePoms(List pomReferences, PropertySource properties); 38 | 39 | /** 40 | * Resolves the given {@code pomReferences}, ignoring any references that cannot be 41 | * resolved. 42 | * @param pomReferences the pom references to resolve 43 | * @return the poms resolved from the references 44 | */ 45 | List resolvePomsLeniently(List pomReferences); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ci/scripts/stage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source $(dirname $0)/common.sh 5 | repository=$(pwd)/distribution-repository 6 | 7 | pushd git-repo > /dev/null 8 | git fetch --tags --all > /dev/null 9 | popd > /dev/null 10 | 11 | git clone git-repo stage-git-repo > /dev/null 12 | 13 | pushd stage-git-repo > /dev/null 14 | 15 | snapshotVersion=$( awk -F '=' '$1 == "version" { print $2 }' gradle.properties ) 16 | if [[ $RELEASE_TYPE = "M" ]]; then 17 | stageVersion=$( get_next_milestone_release $snapshotVersion) 18 | nextVersion=$snapshotVersion 19 | elif [[ $RELEASE_TYPE = "RC" ]]; then 20 | stageVersion=$( get_next_rc_release $snapshotVersion) 21 | nextVersion=$snapshotVersion 22 | elif [[ $RELEASE_TYPE = "RELEASE" ]]; then 23 | stageVersion=$( get_next_release $snapshotVersion) 24 | nextVersion=$( bump_version_number $snapshotVersion) 25 | else 26 | echo "Unknown release type $RELEASE_TYPE" >&2; exit 1; 27 | fi 28 | 29 | echo "Staging $stageVersion (next version will be $nextVersion)" 30 | sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties 31 | 32 | git config user.name "Spring Builds" > /dev/null 33 | git config user.email "spring-builds@users.noreply.github.com" > /dev/null 34 | git add gradle.properties > /dev/null 35 | git commit -m"Release v$stageVersion" > /dev/null 36 | git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null 37 | 38 | ulimit -n 65536 39 | ./gradlew --no-daemon -PdeploymentRepository=${repository} build publish 40 | 41 | git reset --hard HEAD^ > /dev/null 42 | if [[ $nextVersion != $snapshotVersion ]]; then 43 | echo "Setting next development version (v$nextVersion)" 44 | sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties 45 | git add gradle.properties > /dev/null 46 | git commit -m"Next development version (v$nextVersion)" > /dev/null 47 | fi 48 | 49 | echo "DONE" 50 | 51 | popd > /dev/null 52 | -------------------------------------------------------------------------------- /src/test/java/io/spring/gradle/dependencymanagement/internal/dsl/StandardMavenBomHandlerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | import groovy.lang.GString; 23 | import org.codehaus.groovy.runtime.GStringImpl; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | /** 29 | * Tests for {@link StandardMavenBomHandler}. 30 | * 31 | * @author Andy Wilkinson 32 | */ 33 | class StandardMavenBomHandlerTests { 34 | 35 | private final StandardMavenBomHandler handler = new StandardMavenBomHandler(); 36 | 37 | @Test 38 | @SuppressWarnings({ "rawtypes", "unchecked" }) 39 | void bomPropertiesCanBeConfiguredUsingAMapContainingGString() { 40 | Map properties = new HashMap(); 41 | properties.put(gstring("example.version"), gstring("1.0")); 42 | this.handler.bomProperties(properties); 43 | Object version = this.handler.getBomProperties().getProperty("example.version"); 44 | assertThat(version).isInstanceOf(String.class).isEqualTo("1.0"); 45 | } 46 | 47 | private GString gstring(String string) { 48 | return new GStringImpl(new Object[0], new String[] { string }); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/StandardMavenBomHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | import io.spring.gradle.dependencymanagement.dsl.MavenBomHandler; 23 | import io.spring.gradle.dependencymanagement.internal.properties.MapPropertySource; 24 | import io.spring.gradle.dependencymanagement.internal.properties.PropertySource; 25 | 26 | /** 27 | * Standard implementation of {@link MavenBomHandler}. 28 | * 29 | * @author Andy Wilkinson 30 | */ 31 | class StandardMavenBomHandler implements MavenBomHandler { 32 | 33 | private final Map bomProperties = new HashMap<>(); 34 | 35 | @Override 36 | public void bomProperty(String name, String value) { 37 | this.bomProperties.put(name, value); 38 | } 39 | 40 | @Override 41 | public void bomProperties(Map properties) { 42 | putAll(properties, this.bomProperties); 43 | } 44 | 45 | private void putAll(Map source, Map target) { 46 | source.forEach((key, value) -> target.put(key.toString(), value.toString())); 47 | } 48 | 49 | PropertySource getBomProperties() { 50 | return new MapPropertySource(this.bomProperties); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-with-constrained-transitive-dependency/1.0/platform-with-constrained-transitive-dependency-1.0.module: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": "1.1", 3 | "component": { 4 | "group": "test", 5 | "module": "platform-with-constrained-transitive-dependency", 6 | "version": "1.0", 7 | "attributes": { 8 | "org.gradle.status": "release" 9 | } 10 | }, 11 | "createdBy": { 12 | "gradle": { 13 | "version": "8.4" 14 | } 15 | }, 16 | "variants": [ 17 | { 18 | "name": "apiElements", 19 | "attributes": { 20 | "org.gradle.category": "platform", 21 | "org.gradle.usage": "java-api" 22 | }, 23 | "dependencies": [ 24 | { 25 | "group": "com.squareup.okhttp3", 26 | "module": "okhttp", 27 | "version": { 28 | "requires": "4.11.0" 29 | } 30 | } 31 | ], 32 | "dependencyConstraints": [ 33 | { 34 | "group": "com.squareup.okio", 35 | "module": "okio", 36 | "version": { 37 | "requires": "3.6.0", 38 | "prefers": "latest.release", 39 | "rejects": [ 40 | "3.2.0" 41 | ] 42 | } 43 | } 44 | ] 45 | }, 46 | { 47 | "name": "runtimeElements", 48 | "attributes": { 49 | "org.gradle.category": "platform", 50 | "org.gradle.usage": "java-runtime" 51 | }, 52 | "dependencies": [ 53 | { 54 | "group": "com.squareup.okhttp3", 55 | "module": "okhttp", 56 | "version": { 57 | "requires": "4.11.0" 58 | } 59 | } 60 | ], 61 | "dependencyConstraints": [ 62 | { 63 | "group": "com.squareup.okio", 64 | "module": "okio", 65 | "version": { 66 | "requires": "3.6.0", 67 | "prefers": "latest.release", 68 | "rejects": [ 69 | "3.2.0" 70 | ] 71 | } 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/ImportsHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import groovy.lang.Closure; 20 | import org.gradle.api.Action; 21 | 22 | /** 23 | * Handler for configuring dependency management imports. 24 | * 25 | * @author Andy Wilkinson 26 | * @see DependencyManagementHandler#imports(Closure) 27 | */ 28 | public interface ImportsHandler { 29 | 30 | /** 31 | * Imports the Maven bom with the given {@code coordinates} in the form 32 | * {@code group:name:version}. 33 | * @param coordinates the bom's coordinates 34 | */ 35 | void mavenBom(String coordinates); 36 | 37 | /** 38 | * Imports the Maven bom with the given {@code coordinates} in the form 39 | * {@code group:name:version}. The import is customized using the given 40 | * {@code closure} which is called with a {@link MavenBomHandler} as its delegate. 41 | * @param coordinates the bom's coordinates 42 | * @param closure the closure 43 | * @see MavenBomHandler 44 | */ 45 | void mavenBom(String coordinates, Closure closure); 46 | 47 | /** 48 | * Imports the Maven bom with the given {@code coordinates} in the form 49 | * {@code group:name:version}. The import is customized using the given 50 | * {@code action}. 51 | * @param coordinates the bom's coordinates 52 | * @param action the action 53 | */ 54 | void mavenBom(String coordinates, Action action); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/spring/gradle/dependencymanagement/internal/properties/ProjectPropertySourceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.properties; 18 | 19 | import org.gradle.api.Project; 20 | import org.gradle.testfixtures.ProjectBuilder; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | /** 26 | * Tests for {@link ProjectPropertySource}. 27 | * 28 | * @author Andy Wilkinson 29 | */ 30 | class ProjectPropertySourceTests { 31 | 32 | private final Project project = ProjectBuilder.builder().build(); 33 | 34 | private final ProjectPropertySource propertySource = new ProjectPropertySource(this.project); 35 | 36 | @Test 37 | void nullIsReturnedWhenProjectDoesNotHaveAProperty() { 38 | assertThat(this.propertySource.getProperty("does.not.exist")).isNull(); 39 | } 40 | 41 | @Test 42 | void propertyIsReturnedWhenProjectHasProperty() { 43 | this.project.getExtensions().getExtraProperties().set("alpha", "a"); 44 | assertThat(this.propertySource.getProperty("alpha")).isEqualTo("a"); 45 | } 46 | 47 | @Test 48 | void nullIsReturnedWhenProjectHasProperty() { 49 | this.project.getExtensions().getExtraProperties().set("alpha", null); 50 | assertThat(this.propertySource.getProperty("alpha")).isNull(); 51 | } 52 | 53 | @Test 54 | void nullIsReturnedWhenVersionPropertyIsRetrieved() { 55 | this.project.setVersion("1.2.3"); 56 | assertThat(this.propertySource.getProperty("version")).isNull(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/resources/io/spring/gradle/dependencymanagement/DMPIT/managedVersionsCanBeAccessedProgramatically.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.spring.dependency-management" 3 | id "java" 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE' 13 | } 14 | testRuntimeOnly { 15 | dependencies { 16 | dependency 'com.foo:bar:1.2.3' 17 | } 18 | } 19 | dependencies { 20 | dependencySet(group: 'com.alpha', version: '1.0') { 21 | entry 'bravo' 22 | entry 'charlie' 23 | } 24 | } 25 | } 26 | 27 | def verifyManagedVersion(def versions, def id, def expected) { 28 | def actual = versions[id] 29 | if (actual != expected) { 30 | throw new GradleException("Managed version for '${id}' was '${actual}' but '${expected}' was expected") 31 | } 32 | } 33 | 34 | 35 | task verify { 36 | doFirst { 37 | verifyManagedVersion(dependencyManagement.implementation.managedVersions, "org.springframework:spring-core", "4.0.6.RELEASE") 38 | verifyManagedVersion(dependencyManagement.testRuntimeOnly.managedVersions, "org.springframework:spring-core", "4.0.6.RELEASE") 39 | verifyManagedVersion(dependencyManagement.managedVersions, "org.springframework:spring-core", "4.0.6.RELEASE") 40 | 41 | verifyManagedVersion(dependencyManagement.implementation.managedVersions, "com.foo:bar", null) 42 | verifyManagedVersion(dependencyManagement.testRuntimeOnly.managedVersions, "com.foo:bar", "1.2.3") 43 | verifyManagedVersion(dependencyManagement.managedVersions, "com.foo:bar", null) 44 | 45 | verifyManagedVersion(dependencyManagement.implementation.managedVersions, "com.alpha:bravo", "1.0") 46 | verifyManagedVersion(dependencyManagement.testRuntimeOnly.managedVersions, "com.alpha:bravo", "1.0") 47 | verifyManagedVersion(dependencyManagement.managedVersions, "com.alpha:bravo", "1.0") 48 | 49 | verifyManagedVersion(dependencyManagement.implementation.managedVersions, "com.alpha:charlie", "1.0") 50 | verifyManagedVersion(dependencyManagement.testRuntimeOnly.managedVersions, "com.alpha:charlie", "1.0") 51 | verifyManagedVersion(dependencyManagement.managedVersions, "com.alpha:charlie", "1.0") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.github/actions/sync-to-maven-central/action.yml: -------------------------------------------------------------------------------- 1 | name: Sync to Maven Central 2 | description: Syncs a release to Maven Central and waits for it to be available for use 3 | inputs: 4 | jfrog-cli-config-token: 5 | description: 'Config token for the JFrog CLI' 6 | required: true 7 | version: 8 | description: 'The version that is being synced to Central' 9 | required: true 10 | ossrh-s01-token-username: 11 | description: 'Username for authentication with s01.oss.sonatype.org' 12 | required: true 13 | ossrh-s01-token-password: 14 | description: 'Password for authentication with s01.oss.sonatype.org' 15 | required: true 16 | ossrh-s01-staging-profile: 17 | description: 'Staging profile to use when syncing to Central' 18 | required: true 19 | runs: 20 | using: composite 21 | steps: 22 | - name: Set Up JFrog CLI 23 | uses: jfrog/setup-jfrog-cli@d82fe26823e1f25529250895d5673f65b02af085 # v4.0.1 24 | env: 25 | JF_ENV_SPRING: ${{ inputs.jfrog-cli-config-token }} 26 | - name: Download Release Artifacts 27 | shell: bash 28 | run: jf rt download --spec ${{ format('{0}/artifacts.spec', github.action_path) }} --spec-vars 'buildName=${{ format('dependency-management-plugin-{0}', inputs.version) }};buildNumber=${{ github.run_number }}' 29 | - name: Sync 30 | uses: spring-io/nexus-sync-action@42477a2230a2f694f9eaa4643fa9e76b99b7ab84 # v0.0.1 31 | with: 32 | username: ${{ inputs.ossrh-s01-token-username }} 33 | password: ${{ inputs.ossrh-s01-token-password }} 34 | staging-profile-name: ${{ inputs.ossrh-s01-staging-profile }} 35 | create: true 36 | upload: true 37 | close: true 38 | release: true 39 | generate-checksums: true 40 | - name: Await 41 | shell: bash 42 | run: | 43 | url=${{ format('https://repo.maven.apache.org/maven2/io/spring/gradle/dependency-management-plugin/{0}/dependency-management-plugin-{0}.jar', inputs.version) }} 44 | echo "Waiting for $url" 45 | until curl --fail --head --silent $url > /dev/null 46 | do 47 | echo "." 48 | sleep 60 49 | done 50 | echo "$url is available" 51 | -------------------------------------------------------------------------------- /git/hooks/prepare-forward-merge: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | require 'json' 3 | require 'net/http' 4 | require 'yaml' 5 | require 'logger' 6 | 7 | $main_branch = "1.1.x" 8 | 9 | $log = Logger.new(STDOUT) 10 | $log.level = Logger::WARN 11 | 12 | def get_fixed_issues() 13 | $log.debug "Searching for forward merge" 14 | rev=`git rev-parse -q --verify MERGE_HEAD`.strip 15 | $log.debug "Found #{rev} from git rev-parse" 16 | return nil unless rev 17 | fixed = [] 18 | message = `git log -1 --pretty=%B #{rev}` 19 | message.each_line do |line| 20 | $log.debug "Checking #{line} for message" 21 | fixed << line.strip if /^(?:Fixes|Closes) gh-(\d+)/.match(line) 22 | end 23 | $log.debug "Found fixed issues #{fixed}" 24 | return fixed; 25 | end 26 | 27 | def rewrite_message(message_file, fixed) 28 | current_branch = `git rev-parse --abbrev-ref HEAD`.strip 29 | if current_branch == "main" 30 | current_branch = $main_branch 31 | end 32 | rewritten_message = "" 33 | message = File.read(message_file) 34 | message.each_line do |line| 35 | match = /^Merge.*branch\ '(.*)'(?:\ into\ (.*))?$/.match(line) 36 | if match 37 | from_branch = match[1] 38 | if from_branch.include? "/" 39 | from_branch = from_branch.partition("/").last 40 | end 41 | to_brach = match[2] 42 | $log.debug "Rewriting merge message" 43 | line = "Merge branch '#{from_branch}'" + (to_brach ? " into #{to_brach}\n" : "\n") 44 | end 45 | if fixed and line.start_with?("#") 46 | $log.debug "Adding fixed" 47 | rewritten_message << "\n" 48 | fixed.each do |fixes| 49 | rewritten_message << "#{fixes} in #{current_branch}\n" 50 | end 51 | fixed = nil 52 | end 53 | rewritten_message << line 54 | end 55 | return rewritten_message 56 | end 57 | 58 | $log.debug "Running prepare-forward-merge hook script" 59 | 60 | message_file=ARGV[0] 61 | message_type=ARGV[1] 62 | 63 | if message_type != "merge" 64 | $log.debug "Not a merge commit" 65 | exit 0; 66 | end 67 | 68 | $log.debug "Searching for forward merge" 69 | fixed = get_fixed_issues() 70 | rewritten_message = rewrite_message(message_file, fixed) 71 | File.write(message_file, rewritten_message) 72 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/DependencySetHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import groovy.lang.Closure; 20 | import org.gradle.api.Action; 21 | 22 | /** 23 | * A handler for the configuration of a set of dependencies with a common group and 24 | * version. 25 | * 26 | * @author Andy Wilkinson 27 | * @see DependenciesHandler#dependencySet(java.util.Map, Closure) 28 | */ 29 | public interface DependencySetHandler { 30 | 31 | /** 32 | * Adds an entry to the set for the dependency with the given name. 33 | * @param name the name of the dependency 34 | */ 35 | void entry(String name); 36 | 37 | /** 38 | * Adds an entry to the set for the dependency with the given {@code name}. The 39 | * dependency management for the entry is further configured using the given 40 | * {@code closure} that is called with a {@link DependencyHandler} as its delegate. 41 | * @param name the name of the dependency 42 | * @param closure used to further configure the dependency management 43 | * @see DependencyHandler 44 | */ 45 | void entry(String name, Closure closure); 46 | 47 | /** 48 | * Adds an entry to the set for the dependency with the given {@code name}. The 49 | * dependency management for the entry is further configured using the given 50 | * {@code action}. 51 | * @param name the name of the dependency 52 | * @param action used to further configure the dependency management 53 | */ 54 | void entry(String name, Action action); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/dsl/DependencyManagementConfigurer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.dsl; 18 | 19 | import groovy.lang.Closure; 20 | import org.gradle.api.Action; 21 | 22 | /** 23 | * A {@code DependencyManagementConfigurer} provides methods for configuring dependency 24 | * management. 25 | * 26 | * @author Andy Wilkinson 27 | */ 28 | public interface DependencyManagementConfigurer { 29 | 30 | /** 31 | * Configures the dependency management imports using the given {@code closure}. The 32 | * closure is called with an {@link ImportsHandler} as its delegate. 33 | * @param closure the closure to execute to configure the imports 34 | * @see ImportsHandler 35 | */ 36 | void imports(Closure closure); 37 | 38 | /** 39 | * Configures the dependency management imports using the given {@code action}. 40 | * @param action the action to execute to configure the imports 41 | */ 42 | void imports(Action action); 43 | 44 | /** 45 | * Configures the managed dependencies using the given {@code closure}. The closure is 46 | * called with {@link DependenciesHandler} as its delegate. 47 | * @param closure the closure to execute to configure the dependencies 48 | * @see DependenciesHandler 49 | */ 50 | void dependencies(Closure closure); 51 | 52 | /** 53 | * Configures the managed dependencies using the given {@code action}. 54 | * @param action the action to execute to configure the dependencies 55 | */ 56 | void dependencies(Action action); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Dependency Management Plugin 2 | 3 | Dependency Management Plugin is released under the Apache 2.0 license. If you would like 4 | to contribute something, or simply want to work with the code, this document should help 5 | you to get started. 6 | 7 | ## Code of conduct 8 | 9 | This project adheres to the Contributor Covenant [code of conduct][1]. By participating, 10 | you are expected to uphold this code. Please report unacceptable behavior to 11 | spring-code-of-conduct@pivotal.io. 12 | 13 | ## Include a Signed-off-by Trailer 14 | 15 | All commits must include a _Signed-off-by_ trailer at the end of each commit message to 16 | indicate that the contributor agrees to the [Developer Certificate of Origin (DCO)][2]. 17 | For additional details, please refer to the ["Hello DCO, Goodbye CLA: Simplifying 18 | Contributions to Spring"][3] blog post. 19 | 20 | ## Code conventions and housekeeping 21 | 22 | None of these is essential for a pull request, but they will all help 23 | 24 | - Make sure all new `.groovy` files to have a simple Javadoc class comment with at least an 25 | `@author` tag identifying you, and preferably at least a paragraph on what the class is 26 | for. 27 | - Add the ASF license header comment to all new `.groovy` files (copy from existing files 28 | in the project) 29 | - Add yourself as an `@author` to the `.groovy` files that you modify substantially (more 30 | than cosmetic changes). 31 | - Add some Javadocs 32 | - Add unit tests that covers and new or modified functionality 33 | - Whenever possible, please rebase your branch against the current main (or other 34 | target branch in the main project). 35 | - When writing a commit message please follow [these conventions][4]. Also, if you are 36 | fixing an existing issue please add `Fixes gh-nnn` at the end of the commit message 37 | (where nnn is the issue number). 38 | 39 | ## Working with the code 40 | 41 | ### Building from source 42 | 43 | The code is built with Gradle: 44 | 45 | ``` 46 | $ ./gradlew build 47 | ``` 48 | 49 | [1]: CODE_OF_CONDUCT.md 50 | [2]: https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin 51 | [3]: https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring 52 | [4]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 53 | -------------------------------------------------------------------------------- /src/test/java/io/spring/gradle/dependencymanagement/MavenPublishPluginIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement; 18 | 19 | import java.nio.file.Paths; 20 | 21 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 22 | import org.junit.jupiter.api.Test; 23 | import org.junit.jupiter.api.extension.RegisterExtension; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | /** 28 | * Integration tests for interacting with the {@link MavenPublishPlugin}. 29 | * 30 | * @author Andy Wilkinson 31 | */ 32 | class MavenPublishPluginIntegrationTests { 33 | 34 | @RegisterExtension 35 | private final GradleBuild gradleBuild = new GradleBuild(); 36 | 37 | @Test 38 | void generatedPomsAreCustomized() { 39 | this.gradleBuild.runner().withArguments("generatePom").build(); 40 | assertThat(generatedPom()).nodeAtPath("//dependencyManagement").isNotNull(); 41 | } 42 | 43 | @Test 44 | void customizationOfGeneratedPomsCanBeDisabled() { 45 | this.gradleBuild.runner().withArguments("generatePom").build(); 46 | assertThat(generatedPom()).nodeAtPath("//dependencyManagement").isNull(); 47 | } 48 | 49 | @Test 50 | void usingImportedPropertiesDoesNotPreventFurtherConfigurationOfThePublishingExtension() { 51 | this.gradleBuild.runner().withArguments("generatePom").build(); 52 | assertThat(generatedPom()).nodeAtPath("//dependencyManagement").isNotNull(); 53 | } 54 | 55 | private NodeAssert generatedPom() { 56 | return new NodeAssert(this.gradleBuild.runner() 57 | .getProjectDir() 58 | .toPath() 59 | .resolve(Paths.get("build", "publications", "mavenJava", "pom-default.xml"))); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/pom/Coordinates.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.pom; 18 | 19 | /** 20 | * Coordinates (group ID, artifact ID, and version) for a Maven artifact. 21 | * 22 | * @author Andy Wilkinson 23 | */ 24 | public class Coordinates { 25 | 26 | private final String groupId; 27 | 28 | private final String artifactId; 29 | 30 | private final String version; 31 | 32 | /** 33 | * Creates a new {@code Coordinates} with the given {@code groupId}, 34 | * {@code artifactId}, and {@code version}. 35 | * @param groupId the group ID 36 | * @param artifactId the artifact ID 37 | * @param version the version 38 | */ 39 | public Coordinates(String groupId, String artifactId, String version) { 40 | this.groupId = groupId; 41 | this.artifactId = artifactId; 42 | this.version = version; 43 | } 44 | 45 | /** 46 | * Returns the coordinates' group ID. 47 | * @return the group ID 48 | */ 49 | public String getGroupId() { 50 | return this.groupId; 51 | } 52 | 53 | /** 54 | * Returns the coordinates' artifact ID. 55 | * @return the artifact ID 56 | */ 57 | public String getArtifactId() { 58 | return this.artifactId; 59 | } 60 | 61 | /** 62 | * Returns the coordinates' version. 63 | * @return the version 64 | */ 65 | public String getVersion() { 66 | return this.version; 67 | } 68 | 69 | public String getGroupAndArtifactId() { 70 | return String.format("%s:%s", getGroupId(), getArtifactId()); 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return String.format("%s:%s:%s", getGroupId(), getArtifactId(), getVersion()); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/StandardDependencyHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.Map; 22 | 23 | import io.spring.gradle.dependencymanagement.dsl.DependencyHandler; 24 | import io.spring.gradle.dependencymanagement.internal.Exclusion; 25 | import org.gradle.api.InvalidUserDataException; 26 | 27 | /** 28 | * Standard implementation of {@link DependencyHandler}. 29 | * 30 | * @author Andy Wilkinson 31 | */ 32 | final class StandardDependencyHandler implements DependencyHandler { 33 | 34 | private final List exclusions = new ArrayList<>(); 35 | 36 | @Override 37 | public void exclude(String exclusion) { 38 | String[] components = exclusion.split(":"); 39 | if (components.length != 2) { 40 | throw new InvalidUserDataException( 41 | "Exclusion '" + exclusion + "' is malformed. The required" + " form is 'group:name'"); 42 | } 43 | this.exclusions.add(new Exclusion(components[0], components[1])); 44 | } 45 | 46 | @Override 47 | public void exclude(Map exclusion) { 48 | String group = exclusion.get("group"); 49 | String name = exclusion.get("name"); 50 | if (!hasText(group) || !hasText(name)) { 51 | throw new InvalidUserDataException("An exclusion requires both a group and a name"); 52 | } 53 | this.exclusions.add(new Exclusion(group, name)); 54 | } 55 | 56 | List getExclusions() { 57 | return this.exclusions; 58 | } 59 | 60 | private boolean hasText(String string) { 61 | return (string != null) && string.trim().length() > 0; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/pom/PomReference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.pom; 18 | 19 | import java.util.Collections; 20 | 21 | import io.spring.gradle.dependencymanagement.internal.properties.MapPropertySource; 22 | import io.spring.gradle.dependencymanagement.internal.properties.PropertySource; 23 | 24 | /** 25 | * A reference to a Maven pom. 26 | * 27 | * @author Andy Wilkinson 28 | */ 29 | public final class PomReference { 30 | 31 | private final Coordinates coordinates; 32 | 33 | private final PropertySource properties; 34 | 35 | /** 36 | * Creates a new {@code PomReference}. 37 | * @param coordinates the coordinate of the referenced pom 38 | */ 39 | public PomReference(Coordinates coordinates) { 40 | this(coordinates, new MapPropertySource(Collections.emptyMap())); 41 | } 42 | 43 | /** 44 | * Creates a new {@code PomReference}. 45 | * @param coordinates the coordinates of the referenced pom 46 | * @param properties the properties that should be used when resolving the pom's 47 | * contents 48 | */ 49 | public PomReference(Coordinates coordinates, PropertySource properties) { 50 | this.coordinates = coordinates; 51 | this.properties = properties; 52 | } 53 | 54 | /** 55 | * Returns the coordinates of the referenced pom. 56 | * @return the coordinates 57 | */ 58 | public Coordinates getCoordinates() { 59 | return this.coordinates; 60 | } 61 | 62 | /** 63 | * Returns the properties that should be used when resolving the pom's contents. 64 | * @return the properties 65 | */ 66 | public PropertySource getProperties() { 67 | return this.properties; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/Exclusion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal; 18 | 19 | /** 20 | * An exclusion of an artifact by group ID and artifact ID. 21 | * 22 | * @author Andy Wilkinson 23 | */ 24 | public class Exclusion { 25 | 26 | private final String groupId; 27 | 28 | private final String artifactId; 29 | 30 | /** 31 | * Creates a new {@code Exclusion} using the given {@code groupId} and 32 | * {@code artifactId}. 33 | * @param groupId group ID 34 | * @param artifactId artifact ID 35 | */ 36 | public Exclusion(String groupId, String artifactId) { 37 | this.groupId = (groupId != null) ? groupId : ""; 38 | this.artifactId = (artifactId != null) ? artifactId : ""; 39 | } 40 | 41 | /** 42 | * Returns the group ID that is excluded. 43 | * @return the group ID 44 | */ 45 | public String getGroupId() { 46 | return this.groupId; 47 | } 48 | 49 | /** 50 | * Returns the artifact ID that is excluded. 51 | * @return the artifact ID 52 | */ 53 | public String getArtifactId() { 54 | return this.artifactId; 55 | } 56 | 57 | @Override 58 | public boolean equals(Object obj) { 59 | if (this == obj) { 60 | return true; 61 | } 62 | if ((obj == null) || (getClass() != obj.getClass())) { 63 | return false; 64 | } 65 | Exclusion other = (Exclusion) obj; 66 | boolean result = this.artifactId.equals(other.artifactId); 67 | result = result && this.groupId.equals(other.groupId); 68 | return result; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | int result = 1; 74 | result = 31 * result + this.artifactId.hashCode(); 75 | result = 31 * result + this.groupId.hashCode(); 76 | return result; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/io/spring/gradle/dependencymanagement/DependencyManagementPluginTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement; 18 | 19 | import java.io.File; 20 | 21 | import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension; 22 | import org.gradle.api.Project; 23 | import org.gradle.testfixtures.ProjectBuilder; 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | import org.junit.jupiter.api.io.TempDir; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | /** 31 | * Tests for {@link DependencyManagementPlugin}. 32 | * 33 | * @author Andy Wilkinson 34 | */ 35 | class DependencyManagementPluginTests { 36 | 37 | @TempDir 38 | private File projectDir; 39 | 40 | private Project project; 41 | 42 | @BeforeEach 43 | void setUp() { 44 | this.project = ProjectBuilder.builder().withProjectDir(this.projectDir).build(); 45 | } 46 | 47 | @Test 48 | void whenPluginIsAppliedThenDependencyManagementExtensionIsAdded() { 49 | this.project.getPlugins().apply(DependencyManagementPlugin.class); 50 | assertThat(this.project.getExtensions().findByType(DependencyManagementExtension.class)).isNotNull(); 51 | } 52 | 53 | @Test 54 | void whenPluginIsAppliedThenPomConfigurerIsAvailable() { 55 | this.project.getPlugins().apply(DependencyManagementPlugin.class); 56 | assertThat(this.project.getExtensions().findByType(DependencyManagementExtension.class).getPomConfigurer()) 57 | .isNotNull(); 58 | } 59 | 60 | @Test 61 | void whenPluginIsAppliedThenDependencyManagementReportTaskIsAdded() { 62 | this.project.getPlugins().apply(DependencyManagementPlugin.class); 63 | assertThat(this.project.getTasks().findByName("dependencyManagement")).isNotNull(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of fostering an open 4 | and welcoming community, we pledge to respect all people who contribute through reporting 5 | issues, posting feature requests, updating documentation, submitting pull requests or 6 | patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free experience for 9 | everyone, regardless of level of experience, gender, gender identity and expression, 10 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, 11 | religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic addresses, 20 | without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 24 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 25 | Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors 26 | that they deem inappropriate, threatening, offensive, or harmful. 27 | 28 | By adopting this Code of Conduct, project maintainers commit themselves to fairly and 29 | consistently applying these principles to every aspect of managing this project. Project 30 | maintainers who do not follow or enforce the Code of Conduct may be permanently removed 31 | from the project team. 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an 34 | individual is representing the project or its community. 35 | 36 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 37 | contacting a project maintainer at spring-code-of-conduct@pivotal.io. All complaints will 38 | be reviewed and investigated and will result in a response that is deemed necessary and 39 | appropriate to the circumstances. Maintainers are obligated to maintain confidentiality 40 | with regard to the reporter of an incident. 41 | 42 | This Code of Conduct is adapted from the [Contributor Covenant][1], version 1.3.0, available 43 | at [contributor-covenant.org/version/1/3/0/][2]. 44 | 45 | [1]: https://contributor-covenant.org 46 | [2]: https://contributor-covenant.org/version/1/3/0/ -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/CompoundDependencyManagementConfigurer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import java.util.List; 20 | import java.util.function.Consumer; 21 | 22 | import groovy.lang.Closure; 23 | import io.spring.gradle.dependencymanagement.dsl.DependenciesHandler; 24 | import io.spring.gradle.dependencymanagement.dsl.DependencyManagementConfigurer; 25 | import io.spring.gradle.dependencymanagement.dsl.ImportsHandler; 26 | import org.gradle.api.Action; 27 | 28 | /** 29 | * A {@link DependencyManagementConfigurer} that delegates to one or more 30 | * {@code DependencyManagementConfigurers} allowing the dependency management for multiple 31 | * configurations to be configured simultaneously. 32 | * 33 | * @author Andy Wilkinson 34 | */ 35 | class CompoundDependencyManagementConfigurer implements DependencyManagementConfigurer { 36 | 37 | private final List delegates; 38 | 39 | CompoundDependencyManagementConfigurer(List delegates) { 40 | this.delegates = delegates; 41 | } 42 | 43 | @Override 44 | public void imports(Closure closure) { 45 | doWithDelegates((delegate) -> delegate.imports(closure)); 46 | } 47 | 48 | @Override 49 | public void imports(Action action) { 50 | doWithDelegates((delegate) -> delegate.imports(action)); 51 | } 52 | 53 | @Override 54 | public void dependencies(Closure closure) { 55 | doWithDelegates((delegate) -> delegate.dependencies(closure)); 56 | } 57 | 58 | @Override 59 | public void dependencies(Action action) { 60 | doWithDelegates((delegate) -> delegate.dependencies(action)); 61 | } 62 | 63 | private void doWithDelegates(Consumer delegate) { 64 | this.delegates.forEach(delegate); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/pom/Pom.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.pom; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * A minimal representation of a Maven pom. 24 | * 25 | * @author Andy Wilkinson 26 | */ 27 | public class Pom { 28 | 29 | private final Coordinates coordinates; 30 | 31 | private final List managedDependencies; 32 | 33 | private final List dependencies; 34 | 35 | private final Map properties; 36 | 37 | /** 38 | * Creates a new pom. 39 | * @param coordinates the coordinates of the pom 40 | * @param managedDependencies the managed dependencies 41 | * @param dependencies the dependencies 42 | * @param properties the properties 43 | */ 44 | public Pom(Coordinates coordinates, List managedDependencies, List dependencies, 45 | Map properties) { 46 | this.coordinates = coordinates; 47 | this.managedDependencies = managedDependencies; 48 | this.dependencies = dependencies; 49 | this.properties = properties; 50 | } 51 | 52 | /** 53 | * Returns the pom's managed dependencies. 54 | * @return the managed dependencies 55 | */ 56 | public List getManagedDependencies() { 57 | return this.managedDependencies; 58 | } 59 | 60 | /** 61 | * Returns the pom's properties. 62 | * @return the properties 63 | */ 64 | public Map getProperties() { 65 | return this.properties; 66 | } 67 | 68 | /** 69 | * Returns the pom's coordinates. 70 | * @return the coordinates 71 | */ 72 | public Coordinates getCoordinates() { 73 | return this.coordinates; 74 | } 75 | 76 | /** 77 | * Returns the pom's dependencies. 78 | * @return the dependencies 79 | */ 80 | public List getDependencies() { 81 | return this.dependencies; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/test/resources/maven-repo/test/platform-consumer/1.0/platform-consumer-1.0.module: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": "1.1", 3 | "component": { 4 | "group": "test", 5 | "module": "platform-consumer", 6 | "version": "1.0", 7 | "attributes": { 8 | "org.gradle.status": "release" 9 | } 10 | }, 11 | "createdBy": { 12 | "gradle": { 13 | "version": "8.1.1" 14 | } 15 | }, 16 | "variants": [ 17 | { 18 | "name": "apiElements", 19 | "attributes": { 20 | "org.gradle.category": "library", 21 | "org.gradle.dependency.bundling": "external", 22 | "org.gradle.jvm.version": 8, 23 | "org.gradle.libraryelements": "jar", 24 | "org.gradle.usage": "java-api" 25 | }, 26 | "files": [ 27 | { 28 | "name": "platform-consumer-1.0.jar", 29 | "url": "platform-consumer-1.0.jar", 30 | "size": 261, 31 | "sha512": "86a5a26d8dc2dfe3e97ea8f8761a35cabe6b01025519f5427fe99b1709ca62f78b4e29a8e400b960135bc5fad3ea72fe96a04c3ebf7598ace72933c14e56a954", 32 | "sha256": "800949e7d33f8be22c0a11bbffb097a9035ab490b106da8918a9dee8d7ba99b1", 33 | "sha1": "61157ea5caf7ebdfba10833bfbb55eebd4c12a6d", 34 | "md5": "82d43140d8833264c949d20116b4d8bd" 35 | } 36 | ] 37 | }, 38 | { 39 | "name": "runtimeElements", 40 | "attributes": { 41 | "org.gradle.category": "library", 42 | "org.gradle.dependency.bundling": "external", 43 | "org.gradle.jvm.version": 8, 44 | "org.gradle.libraryelements": "jar", 45 | "org.gradle.usage": "java-runtime" 46 | }, 47 | "dependencies": [ 48 | { 49 | "group": "test", 50 | "module": "platform-b", 51 | "version": { 52 | "requires": "1.0" 53 | }, 54 | "attributes": { 55 | "org.gradle.category": "platform" 56 | }, 57 | "endorseStrictVersions": true 58 | }, 59 | { 60 | "group": "org.springframework", 61 | "module": "spring-core" 62 | } 63 | ], 64 | "files": [ 65 | { 66 | "name": "platform-consumer-1.0.jar", 67 | "url": "platform-consumer-1.0.jar", 68 | "size": 261, 69 | "sha512": "86a5a26d8dc2dfe3e97ea8f8761a35cabe6b01025519f5427fe99b1709ca62f78b4e29a8e400b960135bc5fad3ea72fe96a04c3ebf7598ace72933c14e56a954", 70 | "sha256": "800949e7d33f8be22c0a11bbffb097a9035ab490b106da8918a9dee8d7ba99b1", 71 | "sha1": "61157ea5caf7ebdfba10833bfbb55eebd4c12a6d", 72 | "md5": "82d43140d8833264c949d20116b4d8bd" 73 | } 74 | ] 75 | } 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/dsl/StandardDependencySetHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.dsl; 18 | 19 | import groovy.lang.Closure; 20 | import io.spring.gradle.dependencymanagement.dsl.DependencyHandler; 21 | import io.spring.gradle.dependencymanagement.dsl.DependencySetHandler; 22 | import io.spring.gradle.dependencymanagement.internal.DependencyManagementContainer; 23 | import org.gradle.api.Action; 24 | import org.gradle.api.artifacts.Configuration; 25 | 26 | /** 27 | * Standard implementation of {@link DependencySetHandler}. 28 | * 29 | * @author Andy Wilkinson 30 | */ 31 | final class StandardDependencySetHandler implements DependencySetHandler { 32 | 33 | private final String group; 34 | 35 | private final String version; 36 | 37 | private final DependencyManagementContainer dependencyManagementContainer; 38 | 39 | private final Configuration configuration; 40 | 41 | StandardDependencySetHandler(String group, String version, 42 | DependencyManagementContainer dependencyManagementContainer, Configuration configuration) { 43 | this.group = group; 44 | this.version = version; 45 | this.dependencyManagementContainer = dependencyManagementContainer; 46 | this.configuration = configuration; 47 | } 48 | 49 | @Override 50 | public void entry(String name) { 51 | entry(name, (Action) null); 52 | } 53 | 54 | @Override 55 | public void entry(String name, Closure closure) { 56 | entry(name, (dependencyHandler) -> { 57 | if (closure != null) { 58 | closure.setDelegate(dependencyHandler); 59 | closure.call(); 60 | } 61 | }); 62 | } 63 | 64 | @Override 65 | public void entry(String name, Action action) { 66 | StandardDependencyHandler dependencyHandler = new StandardDependencyHandler(); 67 | if (action != null) { 68 | action.execute(dependencyHandler); 69 | } 70 | this.dependencyManagementContainer.addManagedVersion(this.configuration, this.group, name, this.version, 71 | dependencyHandler.getExclusions()); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/spring/gradle/dependencymanagement/internal/maven/RelaxedModelValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.dependencymanagement.internal.maven; 18 | 19 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.Model; 20 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.building.ModelBuildingRequest; 21 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.building.ModelProblemCollector; 22 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.interpolation.DefaultModelVersionProcessor; 23 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.validation.DefaultModelValidator; 24 | import io.spring.gradle.dependencymanagement.org.apache.maven.model.validation.ModelValidator; 25 | import org.gradle.api.Action; 26 | 27 | /** 28 | * A {@link ModelValidator} that is more relaxed than {@link DefaultModelValidator}. 29 | * 30 | * @author Andy Wilkinson 31 | */ 32 | class RelaxedModelValidator extends DefaultModelValidator { 33 | 34 | RelaxedModelValidator() { 35 | super(new DefaultModelVersionProcessor()); 36 | } 37 | 38 | @Override 39 | public void validateRawModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) { 40 | withNoDistributionManagementStatus(model, 41 | (modifiedModel) -> RelaxedModelValidator.super.validateRawModel(modifiedModel, request, problems)); 42 | } 43 | 44 | @Override 45 | public void validateEffectiveModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) { 46 | withNoDistributionManagementStatus(model, 47 | (modifiedModel) -> RelaxedModelValidator.super.validateEffectiveModel(modifiedModel, request, 48 | problems)); 49 | } 50 | 51 | private void withNoDistributionManagementStatus(Model model, Action action) { 52 | if (model.getDistributionManagement() != null) { 53 | String status = model.getDistributionManagement().getStatus(); 54 | model.getDistributionManagement().setStatus(null); 55 | try { 56 | action.execute(model); 57 | } 58 | finally { 59 | model.getDistributionManagement().setStatus(status); 60 | } 61 | } 62 | else { 63 | action.execute(model); 64 | } 65 | } 66 | 67 | } 68 | --------------------------------------------------------------------------------