I have a monorepo setup for my go project. I would love it if I could find a way to use go build (or similar internal tool) to get a list of targets that need to be re-built.
Here is an example of what I am looking for:
...
├── pkg //shared code across mono repo
│ └── math
│ └── common_operations.go
└── cmd // individual packages to be built
├── package1
│ └── main.go
└── package2
└── main.go
The package1 program calls a subtract function from the math shared library. The package2 program calls an add function.
- If I change the package1 code, only the package1 target is listed
- If I change the package2 code, only the package2 target is listed
- If I change the add function in the shared library, only the package2 target is listed
- If I change the subtract function in the shared library, only the package1 target is listed
- If I change all the functions in the shared library, both package1 and package2 rebuilds.
I would be perfectly happy to use use the internal build package and get the list programatically. I am just am unfamiliar with it.
What I have tried:
Bazel has an option for this but I would prefer to avoid using bazel if at all possible.
the bazel command: bazel build cmd/some-target --check_up_to_date
returns error code 0 if it is up to date, otherwise it returns error code 1.
Which is technically a solution, but my need, as you might have inferred, is ci/cd based. And I want to avoid integrating Bazel into that process as much as possible.
CodePudding user response:
Not really sure of the use case here, are you OK with actually compiling the packages as well? In that case maybe go build -v
can do the job for you. From go help build
:
-v
print the names of packages as they are compiled.
CodePudding user response:
My desire was to find something similar to a go build option that would basically spit out a true or false if a target package was up-to-date. I would be happy if someone out there found a tool ( Earthly I am looking at you right now) that could solve this.
The closest thing to a solution I could find to solve my issue was to run this command:
go build -n cmd/some-target
And if the output is:
touch some-target
Then, it must be up-to-date. If the output is a long list of commands, then it isn't. If it is not up-to-date. You could then get the package name using:
go build -v
To get the name of the package and move it to the next stage of the CI process (building target, testing target, building image, etc).
Obviously it is a little hacky and requires self-rolling a solution and specifics would likely need to be changed on your exact needs. It also requires, as @zacho314 mentioned, saving the state of the go build cache, but most modern CI technologies have a solution for that. I am sure I will do something similar to this for now.