void apply()

in grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/publishing/GrailsPublishGradlePlugin.groovy [113:414]


    void apply(Project project) {
        project.rootProject.logger.info("Applying Grails Publish Gradle Plugin for `${project.name}`...");
        if (project.extensions.findByName('grailsPublish') == null) {
            project.extensions.add('grailsPublish', new GrailsPublishExtension())
        }
        final String nexusPublishUrl = project.findProperty('nexusPublishUrl') ?: System.getenv('NEXUS_PUBLISH_URL') ?: ''
        final String nexusPublishSnapshotUrl = project.findProperty('nexusPublishSnapshotUrl') ?: System.getenv('NEXUS_PUBLISH_SNAPSHOT_URL') ?: ''
        final String nexusPublishUsername = project.findProperty('nexusPublishUsername') ?: System.getenv('NEXUS_PUBLISH_USERNAME') ?: ''
        final String nexusPublishPassword = project.findProperty('nexusPublishPassword') ?: System.getenv('NEXUS_PUBLISH_PASSWORD') ?: ''
        final String nexusPublishStagingProfileId = project.findProperty('nexusPublishStagingProfileId') ?: System.getenv('NEXUS_PUBLISH_STAGING_PROFILE_ID') ?: ''

        final ExtraPropertiesExtension extraPropertiesExtension = project.extensions.findByType(ExtraPropertiesExtension)

        extraPropertiesExtension.setProperty('signing.keyId', project.findProperty('signing.keyId') ?: System.getenv('SIGNING_KEY'))
        extraPropertiesExtension.setProperty('signing.password', project.findProperty('signing.password') ?: System.getenv('SIGNING_PASSPHRASE'))
        extraPropertiesExtension.setProperty('signing.secretKeyRingFile', project.findProperty('signing.secretKeyRingFile') ?: System.getenv('SIGNING_KEYRING'))

        PublishType snapshotPublishType = project.hasProperty(SNAPSHOT_PUBLISH_TYPE_PROPERTY) ? PublishType.valueOf(project.property(SNAPSHOT_PUBLISH_TYPE_PROPERTY) as String) : PublishType.MAVEN_PUBLISH
        PublishType releasePublishType = project.hasProperty(RELEASE_PUBLISH_TYPE_PROPERTY) ? PublishType.valueOf(project.property(RELEASE_PUBLISH_TYPE_PROPERTY) as String) : PublishType.NEXUS_PUBLISH

        boolean isSnapshot, isRelease
        if (System.getenv(ENVIRONMENT_VARIABLE_BASED_RELEASE) != null) {
            // Detect release state based on environment variables instead of versions
            isRelease = Boolean.parseBoolean(System.getenv(ENVIRONMENT_VARIABLE_BASED_RELEASE))
            isSnapshot = !isRelease

            project.rootProject.logger.lifecycle("Environment Variable `$ENVIRONMENT_VARIABLE_BASED_RELEASE` detected - using variable instead of project version.")
        } else {
            String detectedVersion = (project.version == Project.DEFAULT_VERSION ? (project.findProperty('projectVersion') ?: Project.DEFAULT_VERSION) : project.version) as String
            if (detectedVersion == Project.DEFAULT_VERSION) {
                throw new IllegalStateException("Project ${project.name} has an unspecified version (neither `version` or the property `projectVersion` is defined). Release state cannot be determined.")
            }
            project.rootProject.logger.info("Version $detectedVersion detected for project ${project.name}")

            isSnapshot = detectedVersion.endsWith('SNAPSHOT')
            isRelease = !isSnapshot

            if (project.version == Project.DEFAULT_VERSION) {
                if (isRelease) {
                    project.rootProject.logger.warn("Project ${project.name} does not have a version defined. Using the gradle property `projectVersion` to assume version is ${detectedVersion}.")
                } else {
                    project.rootProject.logger.info("Project ${project.name} does not have a version defined. Using the gradle property `projectVersion` to assume version is ${detectedVersion}.")
                }
            }
        }

        if (isSnapshot) {
            project.rootProject.logger.info("Project ${project.name} will be a snapshot.")
        }
        if (isRelease) {
            project.rootProject.logger.info("Project ${project.name} will be a release.")
        }

        boolean useMavenPublish = (isSnapshot && snapshotPublishType == PublishType.MAVEN_PUBLISH) || (isRelease && releasePublishType == PublishType.MAVEN_PUBLISH)
        if (useMavenPublish) {
            project.rootProject.logger.info("Maven Publish is enabled for project ${project.name}")
        }
        boolean useNexusPublish = (isSnapshot && snapshotPublishType == PublishType.NEXUS_PUBLISH) || (isRelease && releasePublishType == PublishType.NEXUS_PUBLISH)
        if (useNexusPublish) {
            project.rootProject.logger.info("Nexus Publish is enabled for project ${project.name}")
        }

        // Required for the pom always
        final PluginManager projectPluginManager = project.pluginManager
        projectPluginManager.apply(MavenPublishPlugin)

        if (isRelease || useNexusPublish) {
            if (project.pluginManager.hasPlugin(SIGNING_PLUGIN_ID)) {
                project.rootProject.logger.debug("Signing Plugin already applied to project {}", project.name)
            } else {
                projectPluginManager.apply(SigningPlugin)
            }

            project.tasks.withType(Sign).configureEach { Sign task ->
                task.onlyIf { isRelease }
            }
        }

        if (useNexusPublish) {
            // The nexus plugin is special since it must always be applied to the root project.
            // Handle when multiple subprojects exist and grailsPublish is defined in each one instead of at the root.
            final PluginManager rootProjectPluginManager = project.rootProject.pluginManager
            boolean hasNexusPublishApplied = rootProjectPluginManager.hasPlugin(NEXUS_PUBLISH_PLUGIN_ID)
            if (hasNexusPublishApplied) {
                project.rootProject.logger.debug("Nexus Publish Plugin already applied to root project")
            } else {
                rootProjectPluginManager.apply(NexusPublishPlugin)
            }

            if (isRelease) {
                project.rootProject.tasks.withType(InitializeNexusStagingRepository).configureEach { InitializeNexusStagingRepository task ->
                    task.shouldRunAfter = project.tasks.withType(Sign)
                }
            }

            if (!hasNexusPublishApplied) {
                project.rootProject.nexusPublishing {
                    repositories {
                        sonatype {
                            if (nexusPublishUrl) {
                                nexusUrl = project.uri(nexusPublishUrl)
                            }
                            if (nexusPublishSnapshotUrl) {
                                snapshotRepositoryUrl = project.uri(nexusPublishSnapshotUrl)
                            }
                            username = nexusPublishUsername
                            password = nexusPublishPassword
                            stagingProfileId = nexusPublishStagingProfileId
                        }
                    }
                }
            }
        }

        project.afterEvaluate {
            final ExtensionContainer extensionContainer = project.extensions

            validateProjectPublishable(project as Project)

            project.publishing {
                final def mavenPublishUrl = project.findProperty('mavenPublishUrl') ?: System.getenv('MAVEN_PUBLISH_URL')
                if (useMavenPublish) {
                    System.setProperty('org.gradle.internal.publish.checksums.insecure', true as String)

                    repositories {
                        maven {
                            final String mavenPublishUsername = project.findProperty('mavenPublishUsername') ?: System.getenv('MAVEN_PUBLISH_USERNAME')
                            final String mavenPublishPassword = project.findProperty('mavenPublishPassword') ?: System.getenv('MAVEN_PUBLISH_PASSWORD')
                            if (mavenPublishUsername && mavenPublishPassword) {
                                credentials {
                                    username = mavenPublishUsername
                                    password = mavenPublishPassword
                                }
                            }
                            url = mavenPublishUrl
                        }
                    }
                }

                final GrailsPublishExtension gpe = extensionContainer.findByType(GrailsPublishExtension)
                publications {
                    maven(MavenPublication) {
                        delegate.artifactId = gpe.artifactId ?: project.name
                        delegate.groupId = gpe.groupId ?: project.group

                        doAddArtefact(project, delegate)
                        def extraArtefact = getDefaultExtraArtifact(project)
                        if (extraArtefact) {
                            artifact extraArtefact
                        }

                        pom.withXml {
                            Node pomNode = asNode()

                            if (!project.extensions.findByType(JavaPlatformExtension)) {
                                // Prevent multiple dependencyManagement nodes
                                if (pomNode.dependencyManagement) {
                                    pomNode.dependencyManagement[0].replaceNode {}
                                }
                            }

                            if (gpe != null) {
                                pomNode.children().last() + {
                                    def title = gpe.title ?: project.name
                                    delegate.name title
                                    delegate.description gpe.desc ?: title

                                    def websiteUrl = gpe.websiteUrl ?: gpe.githubSlug ? "https://github.com/$gpe.githubSlug" : ''
                                    if (!websiteUrl) {
                                        throw new RuntimeException(getErrorMessage('websiteUrl'))
                                    }
                                    delegate.url websiteUrl

                                    def license = gpe.license
                                    if (license != null) {
                                        def concreteLicense = GrailsPublishExtension.License.LICENSES.get(license.name)
                                        if (concreteLicense != null) {
                                            delegate.licenses {
                                                delegate.license {
                                                    delegate.name concreteLicense.name
                                                    delegate.url concreteLicense.url
                                                    delegate.distribution concreteLicense.distribution
                                                }
                                            }
                                        } else if (license.name && license.url) {
                                            delegate.licenses {
                                                delegate.license {
                                                    delegate.name license.name
                                                    delegate.url license.url
                                                    delegate.distribution license.distribution
                                                }
                                            }
                                        }
                                    } else {
                                        throw new RuntimeException(getErrorMessage('license'))
                                    }

                                    if (gpe.githubSlug) {
                                        delegate.scm {
                                            delegate.url "https://github.com/$gpe.githubSlug"
                                            delegate.connection "scm:git@github.com:${gpe.githubSlug}.git"
                                            delegate.developerConnection "scm:git@github.com:${gpe.githubSlug}.git"
                                        }
                                        delegate.issueManagement {
                                            delegate.system 'Github Issues'
                                            delegate.url "https://github.com/$gpe.githubSlug/issues"
                                        }
                                    } else {
                                        if (gpe.vcsUrl) {
                                            delegate.scm {
                                                delegate.url gpe.vcsUrl
                                                delegate.connection "scm:$gpe.vcsUrl"
                                                delegate.developerConnection "scm:$gpe.vcsUrl"
                                            }
                                        } else {
                                            throw new RuntimeException(getErrorMessage('vcsUrl'))
                                        }

                                        if (gpe.issueTrackerUrl) {
                                            delegate.issueManagement {
                                                delegate.system 'Issue Tracker'
                                                delegate.url gpe.issueTrackerUrl
                                            }
                                        } else {
                                            throw new RuntimeException(getErrorMessage('issueTrackerUrl'))
                                        }
                                    }

                                    if (gpe.developers) {
                                        delegate.developers {
                                            for (entry in gpe.developers.entrySet()) {
                                                delegate.developer {
                                                    delegate.id entry.key
                                                    delegate.name entry.value
                                                }
                                            }
                                        }
                                    } else {
                                        throw new RuntimeException(getErrorMessage('developers'))
                                    }
                                }

                            }

                            if (gpe.pomCustomization) {
                                gpe.pomCustomization.delegate = delegate
                                gpe.pomCustomization.resolveStrategy = Closure.DELEGATE_FIRST
                                gpe.pomCustomization.call()
                            }

                            // fix dependencies without a version
                            def mavenPomNamespace = 'http://maven.apache.org/POM/4.0.0'
                            def dependenciesQName = new QName(mavenPomNamespace, 'dependencies')
                            def dependencyQName = new QName(mavenPomNamespace, 'dependency')
                            def versionQName = new QName(mavenPomNamespace, 'version')
                            def groupIdQName = new QName(mavenPomNamespace, 'groupId')
                            def artifactIdQName = new QName(mavenPomNamespace, 'artifactId')
                            def nodes = (pomNode.getAt(dependenciesQName) as NodeList)
                            if (nodes) {
                                def dependencyNodes = (nodes.first() as Node).getAt(dependencyQName)
                                dependencyNodes.findAll { dependencyNode ->
                                    def versionNodes = (dependencyNode as Node).getAt(versionQName)
                                    return versionNodes.size() == 0 || (versionNodes.first() as Node).text().isEmpty()
                                }.each { dependencyNode ->
                                    def groupId = ((dependencyNode as Node).getAt(groupIdQName).first() as Node).text()
                                    def artifactId = ((dependencyNode as Node).getAt(artifactIdQName).first() as Node).text()
                                    def resolvedArtifacts = project.configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts +
                                            project.configurations.runtimeClasspath.resolvedConfiguration.resolvedArtifacts
                                    if (project.configurations.hasProperty('testFixturesCompileClasspath')) {
                                        resolvedArtifacts += project.configurations.testFixturesCompileClasspath.resolvedConfiguration.resolvedArtifacts +
                                                project.configurations.testFixturesRuntimeClasspath.resolvedConfiguration.resolvedArtifacts
                                    }
                                    def managedVersion = resolvedArtifacts.find {
                                        it.moduleVersion.id.group == groupId &&
                                                it.moduleVersion.id.name == artifactId
                                    }?.moduleVersion?.id?.version
                                    if (!managedVersion) {
                                        throw new RuntimeException("No version found for dependency $groupId:$artifactId.")
                                    }
                                    def versionNode = (dependencyNode as Node).getAt(versionQName)
                                    if (versionNode) {
                                        (versionNode.first() as Node).value = managedVersion
                                    } else {
                                        (dependencyNode as Node).appendNode('version', managedVersion)
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (isRelease) {
                extensionContainer.configure(SigningExtension, {
                    it.required = isRelease
                    it.sign project.publishing.publications.maven
                })
            }

            addInstallTaskAliases(project)
        }
    }