Configure war task in root project with subproject specific variables

Hello!

I searched around quite a while on this issue but did not find a clear solution to my problem. Also I am not quite sure whether it is a gradle behaviour or a “problem” of the plugin (at.bxm.svntools).

Problem is:
I have a multi module project with subprojects creating jars or wars. For the war projects I wanted to extend information in the manifest basically with the same information. My first version of the setup used a duplicated configuration for the manifest attributes in all war projects. I wanted to clean that up a bit by defining a global task configuration.

So this is my project layout

root
build.gradle
settings.gradle
-- jarProject
   build.gradle
-- warProject1
   build.gradle
-- warProject2
   build.gradle

In the root project I have defined plugins and a configuration for war tasks to set manifest attributes. Those attributes are basically the same for all war projects.

plugins {
   id 'at.bxm.svntools' version '3.1' apply true
}

subprojects {
   tasks.withType(War).configureEach {
      manifest {
         attributes(
            'Implementation-Version': project.version
            'SVN-Revision': "$svntools.info.revisionNumber"
            ...
         )
      }
   }
}

In the subprojects - e.g. warProject1 - I configure the war task to set the archiveFileName and add some additional project specific manifest attributes

war {
   archiveFileName = 'warProject1.war'
   manifest {
      attributes(
         'ProjectSpecific': 'someSpecificInfo'
      )
   }
}

So far everything works as expected. But there is the problem with $svntools which basically is the same in all subprojects so I wanted to set it only once in the root project with the plugin also only used in root.
But while project.version is giving the correct information for the particular subproject, the SVN-Revision is always providing the information from the root project - so the value of SVN-Revision is the root projects revision in all war projects.
Somehow in contrast to project the $svntools property is locally scoped or so.

Right now I would have to go with the same approach as with ProjectSpecific attribute in manifest but this would mean to basically use plugin and duplicate attribute in all war projects build file.

Is there a way that I can use $svntools in root but that it is executed within the scope of the particular project?

Thx!
Rob

To start with, you should not use subprojects { ... } or allprojects { ... } ever anyway. They are highly discouraged. They immediately introduce project coupling, disturbing more sophisticated Gradle features. Also they make builds less clear, less readable and less maintainable. Instead you should use convention plugins, for example implemented as precompiled script plugins.

When you have switched to convention plugins, your other problem should probably also have vanished.

But just in case you prefer to continue following the bad practice, I don’t really understand your expectation. Within the subprojects { ... } block you are in the scope of the subproject you are configuring, so project.version of course returns its version. Also svntools would be taken from that subproject if it would exist there. But as it does not exist on the subproject as you only apply that plugin to the root project, the root project extension is used and so the revision number of the root project is put to the manifest. If you want the subproject info, you need to apply the plugin to the subproject.
With using the dreaded subprojects { ... } you would then also use the legacy and discouraged plugin application method using apply(...) instead of the plugins { ... } block.

Thank you! I see the issue now.
Just adding id 'at.bxm.svntools' to the war subprojects plugins { ... }was enough. Not optimal, yes. Either that or “apply” it in subprojects. I do not use the latter in my projects and favour plugins { ... } block instead; and I do not want to introduce it just for that.

As for the subprojects { ... } and allprojects { ... }: Thanks for pointing that out.

In my case on the project I only have a small subprojects block with one or two task definitions. Introducing a buildSrc Project just for that seems bit of an overhead to me.

Well, it is not. :slight_smile: