Sharing code between subprojects build scripts

I am using Gradle to orchestrate build of multiple related projects that are in different technologies.

myproject
├── build.gradle.kts
├── buildSrc
├── service-0
├── gradle
├── gradlew
├── gradlew.bat
├── service-1
├── service-2
├── service-3
└── settings.gradle.kts

I have extracted some build logic into the plugins:
service-0/build.gradle.kts

plugins {
     mytemplate
}

renderTemplate {
    template = File()
    output = File()
    context = getContext()
}

What I would like to do now is to have a dev and prod profile. For that, I might have some utils code:

enum class Profile { DEV, PROD }
val currentProfile: Profile
   get() = System.getProperty(PROFILE_PROP).toProfile()

So then I can have some profile specific build logic:
service-0/build.gradle.kts

plugins {
     mytemplate
}

renderTemplate {
    template = File()
    output = File()
    context = when(currentProfile) {
         DEV -> getDevContext()
         PROD -> getProdContext()
    }
}

Also, I would like to reuse this profile utils in other subprojects.

As far as I know there is no way to expose code from within precompiled script plugins and the only way to archive this to have a separate project with utity code, create jar / upload to maven local and then add it as a buildscript dependency to all modules, which seems super cumbersome.

Am I missing something? Is there a better way to do this or is this not the way to approach profiles at all?

to maven local

Using mavenLocal is practically always questionable, so be super careful if you use it. Never have it without content filter, never as first repository, and better not at all. mavenLocal is broken by design in Maven already, and makes builds slow and flaky if not used very carefully. Here you can read about some of the problems with it: The case for mavenLocal().

Am I missing something?

You are right that you cannot put those things into precompiled script plugins, because as a simplification you can consider everything in a precompiled script plugin to be in the body of an enclosing class which roughly it what happens and so cannot properly be used outside.

But if you are having precompiled script plugins, you already do have a separate project where you build that and that you then probably use by includeBuild that build in your settings script. If you do not publish the precompiled script plugins and do not includeBuild them, you do not actually use precompiled script plugins.

But if you do have precompiled script plugins, you can in the same build also have normal .kt files for your enum and so on that you can then use in your other build scripts too.

This worked, thanks a lot!

1 Like