Open scorsi opened 4 years ago
Howdy,
I wonder if the shared project is also build by baur. If yes, could you elaborate on what kind of shared project it is, that other projects depend on the build inputs of the shared project instead of it's output?
If the shared project is not build by baur, it sounds like it could be achieved with an include file. We have some libraries in our monorepository that are included from multiple Apps during build time. To prevent that we have to specify the same inputs multiple times, we create an include file that defines those Build Inputs and include that file in the apps.
I wonder if the shared project is also build by baur. If yes, could you elaborate on what kind of shared project it is, that other projects depend on the build inputs of the shared project instead of it's output?
The dependencies are made thanks to gradle with a simple compile project(":shared")
. So if my-service
need shared
, it will build it by itself.
The problem is, my my-service
app did watch for its own inputs and if the shared
app is rebuilt, my-service
did not.
I have quite a lot of inter-dependencies inside my mono-repo.
If the shared project is not build by baur, it sounds like it could be achieved with an include file. We have some libraries in our monorepository that are included from multiple Apps during build time. To prevent that we have to specify the same inputs multiple times, we create an include file that defines those Build Inputs and include that file in the apps.
It's what I have now. But it's very verbose and it doesn't look like anything anymore.
What I'm proposing could correct that : trigger builds after the hooked apps did build and allow retrieving the baur output (complicated) or just watch the same inputs than the given apps and so let the user handle inter-dependencies (maybe less complicated ?).
Yes, I understand, having to manage a lot of input definitions and includes can become quite complex and also error-prone.
Another solution could be to have a build input resolver, similar to BuildInput.GolangSources
, for that kind of project / programming language.
baur runs the InputResolver and it returns a list of all source files that are required for the build.
To make it flexible, we could have a Generic Input Resolver that runs a command which prints filepaths and baur uses them as inputs.
This would fit well with the current approach of baur.
Would that work for you? Does gradle support to get a list of all source files of a project?
I would like to avoid implementing dependencies/triggers between apps. It would increase the complexity a lot, there are other build tools that follow a related approach like plz, bazel, pants and internally we currently do not have a need for it.
Another solution could be to have a build input resolver, similar to BuildInput.GolangSources, for that kind of project / programming language. baur runs the InputResolver and it returns a list of all source files that are required for the build. To make it flexible, we could have a Generic Input Resolver that runs a command which prints filepaths and baur uses them as inputs. This would fit well with the current approach of baur. Would that work for you? Does gradle support to get a list of all source files of a project?
In fact, as I said, Gradle handles dependencies by itself. So in my case my-service
does gradle build
to the shared
project thanks to the compile project(":shared")
statement, as it's Java behind the scene, it will use jars and linked them together (look it like a dynamic library). No need to specify each files.
To be honest, I don't really look at how the Build.Input.GolangSources
works since I didn't use that. But as you explained it, yes, recover inputs from something like baur ls inputs $appname
looks fine for me since it will mark shared
and any other dependent apps as pending
.
I would like to avoid implementing dependencies/triggers between apps. It would increase the complexity a lot, there are other build tools that follow a related approach like plz, bazel, pants and internally we currently do not have a need for it.
I totally understand. Baur manage mono-repo not dependencies, it's belong to the user-stuff here
@scorsi I don't know much about Gradle and Java builds either.
But as you explained it, yes, recover inputs from something like baur ls inputs $appname looks fine for me since it will mark shared and any other dependent apps as pending.
That I did not had in mind at all, invoking baur from baur to get the build inputs of another app this way would also solve it. Cool idea :-)
I'll explain how builds + Input Resolver worksfor Golang, then the idea might be more clear:
Golang has the command go list
. go list
can be run for a Golang Project to list all source files, including imports that are part of it (including imported libraries).
That output is basically used for Build.Input.GolangSources
.
Additionally Golang has a compile cache, if multiple projects use the same library the objects are retrieved from the cache and compilation is very fast.
I wonder if a similar approach is possible with Java+Gradle:
Has Gradle/Java a command to output all files that would be used in the build?
I think it doesn't. In Maven/Gradle you build every files presents in your sourceset
, basically src/**/*.{java,kt,groovy,scala,cl,...}
. And listing the files present in the sourceset may create issues since we can customize it (it's very rare to see that, but I did) in Gradle.
It's better using Build.Input.GitFiles
for that case.
If yes, maybe it also has a build cache so that it does not matter if the compiled Jar of the shared project exist or is created for every application again from the cache?
Gradle already use caches for every dependencies downloaded, presents in the /cache
directory in $GRADLE_USER_HOME
(recover as :$USER_HOME/.gradle
if not set) and also for every java/kotlin/whatever file.
Gradle handles it by its-own and it did it very well, no need to specify dependencies/cache since the dependencies are not set like my-dep >= 0.0.0
but like my-dep:0.42.4-SNAPSHOT
so if we want to upgrade our deps, we have to modify the build.gradle
file...
For the inter-dependencies, it works differently, each project has a build
directory where the jar file is written. So if I have project-A
depending of shared
, shared
will be built and then project-A
and link the jar file of shared
, if I have project-B
which also depends of shared
no need to build shared
since it was already done by project-A
but project-B
in itself need to be rebuilt to link the new jar file.
In short, looking to the build.gradle
+ the sourceset (often src/**
) of the project is enough and Build.Input.GitFiles
works like a charm.
Hello,
It's could be cool to refer to another app without specifying its own used path. I think example is better than talking.
The shared app:
The depending app:
Instead of:
So when the
BuildInput.GitFiles
(and every otherBuildInput.x
of course) of theshared
project will change, it will build theshared
app and after thatmy-service
app.I'm not talking about managing dependencies, but look that feature like a trigger which
my-service
hook on theshared
app. Ifshared
app did change, others hooked apps too.I don't know how easy it can be done in your codebase or if it can be done.
Thanks,