Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Build.Input.Apps options #154

Open
scorsi opened this issue Jun 16, 2020 · 6 comments
Open

Add a Build.Input.Apps options #154

scorsi opened this issue Jun 16, 2020 · 6 comments

Comments

@scorsi
Copy link

scorsi commented Jun 16, 2020

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:

name = "shared"
[Build]
  command = "..."
  [Build.Input]
    [Build.Input.GitFiles]
      paths = ["..."]

The depending app:

name = "my-service"
[Build]
  command = "..."
  [Build.Input]
    [Build.Input.GitFiles]
      paths = ["..."]
    [Build.Input.Apps]
      apps = ["shared"]

Instead of:

name = "my-service"
[Build]
  command = "..."
  [Build.Input]
    [Build.Input.GitFiles]
      paths = ["..."] # + BuildInput.GitFiles of shared app relative to the actual directory
    # + other BuildInput of shared app relative to the actual directory

So when the BuildInput.GitFiles (and every other BuildInput.x of course) of the shared project will change, it will build the shared app and after that my-service app.


I'm not talking about managing dependencies, but look that feature like a trigger which my-service hook on the shared app. If shared 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,

@fho
Copy link
Collaborator

fho commented Jun 16, 2020

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.

@scorsi
Copy link
Author

scorsi commented Jun 16, 2020

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 ?).

@fho
Copy link
Collaborator

fho commented Jun 17, 2020

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.

@scorsi
Copy link
Author

scorsi commented Jun 17, 2020

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

@fho
Copy link
Collaborator

fho commented Jun 17, 2020

@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?
  • 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?

@scorsi
Copy link
Author

scorsi commented Jun 17, 2020

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.

@scorsi scorsi changed the title Add a BuildInput.Apps options Add a Build.Input.Apps options Jun 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants