Varying the module name or classifier

A couple of months ago, Peter suggested varying the module name or classifier as a substitute for Ivy branching. I’ve actually spent a lot of time eliminating our need for branches, but now I’m up against a use case, and the problem is, I’m not sure how to make this work in Gradle. My artifact currently gets published as follows:

IVY_HOME/.ivy2/local/com.example/project/latest/project-latest.jar

I’d like to change the project directory name to something like “project-branch”, so it would publish as:

IVY_HOME/.ivy2/local/com.example/project-branch/latest/project-branch-latest.jar

I can vary the group and version easily with the respective Project properties, but “name” is read-only. Changing “archivesBaseName” as suggested here allows me to rename the JAR, but the directory is still “project”. I’ve tried using the “artifacts” property to configure it, but can’t seem to get the syntax correct. The “classifier” property seems to be ignored by uploadArchives.

Is there some definitive recommendation for customizing the different parts of the directory/name of the archive?

Any ideas on how to address this use case? Is changing the Ivy modue name on publish outside Gradle best practice?

I’ve done some digging in the source on this issue, and happened upon this likely culprit inside ProjectInternalServiceRegistry:

protected DependencyMetaDataProvider createDependencyMetaDataProvider() {
    return new DependencyMetaDataProvider() {
          public Module getModule() {
            return new DefaultModule(project.getGroup().toString(), project.getName(), project.getVersion().toString(), project.getStatus().toString());
        }
    };
}

The DefaultConfiguration delegates to this method when the publisher asks for the module. I’m new to Gradle generally (and especially to the source code), so I’m not sure I see an easy way to replace this DependencyMetaDataProvider with something that would return a different module name. While group, version, and status are easily customizable, name is of course read-only, and it doesn’t appear there is an obvious way to change it for publishing.

I’m still wondering if I’m barking up the wrong tree here. I did end up figuring out how to publish with a different classifier, for example, but the ivy.xml file that gets published with it is still the same as with no classifier:

Published projectA to C:\temp\local/com.example/projectA/1.0/projectA-1.0-myClassifier.jar
Published ivy to C:\temp\local/com.example/projectA/1.0/ivy-1.0.xml

That will not work for branching. Is this a use case that anyone else has experience with? I could really use some advice here.

That definitely looks like a problem.

You can set the project name from a settings.gradle file. So one workaround might be to determine the branch in there and set the name. So in ‘settings.gradle’, something like…

rootProject.name += "-$branchName"

If it’s a multi project, you’ll have to loop through the children.

Docs on the settings API here.

Thank you, Luke! I wasn’t aware you could do that in the settings file, and it works well. For anyone reading, looping the child projects was as simple as:

try {
 rootProject.name += "-" + branch
 rootProject.children.each {
  it.name += "-" + branch
 }
} catch (MissingPropertyException e) {
 // there is no way to test for the existence of the branch property
 //
 so we swallow the exception if it doesn't exist, and publish
 //
 any artifacts with the default project name
}

Notice that based on this post there is no hasProperty() in Settings, so the only way to test for the existence of a branch property is to use try-catch.

Still, this is a bit of a hack just to change the published name. Is this something I should create an issue ticket for?

Glad it’s working.

I raised GRADLE-2412 for this.