Kevin Coppock
Kevin Coppock

Reputation: 134714

Specifying deployed filename for AAR artifact in Android library project

I'm trying to configure an Android library project to deploy multiple artifacts to a locally hosted Maven repository. I've gotten far enough such that both artifacts have their own POM generated, and it gets deployed properly to the repo, with the following script:

android {
    // Publish both debug and release
    publishNonDefault true
}

uploadArchives {
    repositories.mavenDeployer {
        def majorVersion = 1
        def minorVersion = 1
        def buildVersion = project.properties.get('RELEASE', '0').toInteger()

        addFilter('release') { artifact, file ->
            file.name.contains('release')
        }

        addFilter('debug') { artifact, file ->
            file.name.contains('debug')
        }

        activePomFilters.each { filter ->
            pom(filter.name) {
                groupId = 'com.redacted'
                artifactId = 'redacted'
                packaging = 'aar'
                version = "${majorVersion}.${minorVersion}.${buildVersion}"

                if (!project.hasProperty('RELEASE')) {
                    version += "-SNAPSHOT"
                }

                if (filter.name == 'debug') {
                    artifactId += '-debug'
                }
            }
        }
    }
}

The expected delivery is:

com/
    redacted/
        redacted/
            1.1.0-SNAPSHOT/
        redacted-debug/
            1.1.0-SNAPSHOT/

Which happens as expected, but it seems to publish the artifacts with an additional suffix (which breaks the dependency discovery), and I cannot figure out where it is coming from, or how to change it. What I see is:

com/redacted/redacted/1.1.0-SNAPSHOT/
    redacted-1.1.0-20150717.213849-1-release.aar
    redacted-1.1.0-20150717.213849-1-release.aar.md5
    redacted-1.1.0-20150717.213849-1-release.aar.sha1
    redacted-1.1.0-20150717.213849-1.pom
    redacted-1.1.0-20150717.213849-1.pom.md5
    redacted-1.1.0-20150717.213849-1.pom.sha1

For some reason, it's appending the date, as well as a -release suffix to only the AAR-related files, but not the POM files. If I manually rename these files, everything works as expected. For example, this is what I expect to be output:

com/redacted/redacted/1.1.0-SNAPSHOT/
    redacted-1.1.0-20150717.213849-1.aar
    redacted-1.1.0-20150717.213849-1.aar.md5
    redacted-1.1.0-20150717.213849-1.aar.sha1
    redacted-1.1.0-20150717.213849-1.pom
    redacted-1.1.0-20150717.213849-1.pom.md5
    redacted-1.1.0-20150717.213849-1.pom.sha1

How can I change how these files are delivered?

Upvotes: 5

Views: 2532

Answers (1)

Johan Stuyts
Johan Stuyts

Reputation: 3687

What you are running in to is this (emphasis mine):

Important: When enabling publishing of non default, the Maven publishing plugin will publish these additional variants as extra packages (with classifier). This means that this is not really compatible with publishing to a maven repository. You should either publish a single variant to a repository OR enable all config publishing for inter-project dependencies.

See the documentation: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

The suffixes release and debug that you see are the classifiers introduced by enabling publishing of non-default artifacts. The <artifact> elements in build/ivy.xml, which is used as the basis for the Maven configuration, contain these classifiers.

Iterating over the artifacts in the configurations and removing the classifier does not work. Although setting the classifier is allowed, its original value is kept.

But what does work is wrapping the original artifacts. The wrapper will always return null for a classifier. This does result in the release and debug artifact having the same fully-qualified ID (= name + classifier), which results in only one artifact being published. This can be fixed by using a different name for debug artifacts:

class UnclassifiedPublishArtifact implements PublishArtifact {

    private PublishArtifact delegatee;
    private boolean isDebugArtifact;

    UnclassifiedPublishArtifact(PublishArtifact delegatee, isDebugArtifact) {
        this.delegatee = delegatee
        this.isDebugArtifact = isDebugArtifact
    }

    @Override
    String getName() {
        return delegatee.name + (isDebugArtifact ? '-debug' : '')
    }

    @Override
    String getExtension() {
        return delegatee.extension
    }

    @Override
    String getType() {
        return delegatee.type
    }

    @Override
    String getClassifier() {
        return null
    }

    @Override
    File getFile() {
        return delegatee.file
    }

    @Override
    Date getDate() {
        return delegatee.date
    }

    @Override
    TaskDependency getBuildDependencies() {
        return delegatee.buildDependencies
    }
}

project.afterEvaluate {
    configurations.each { configuration ->
        def artifacts = configuration.artifacts
        if (!artifacts.isEmpty()) {
            def unclassifiedArtifacts = []
            unclassifiedArtifacts.addAll(artifacts.collect { classifiedArtifact ->
                new UnclassifiedPublishArtifact(classifiedArtifact, classifiedArtifact.classifier == 'debug')
            })
            artifacts.clear()
            artifacts.addAll(unclassifiedArtifacts)
        }
    }
}

I can't quite understand from the documentation what the consequences are for project dependencies, so you should check if these still work.

Upvotes: 3

Related Questions