bwplotka / bingo

Like `go get` but for Go tools! CI Automating versioning of Go binaries in a nested, isolated Go modules.
Apache License 2.0
351 stars 29 forks source link

Support tools not using go get #140

Closed mem closed 3 months ago

mem commented 1 year ago

This is mentioned in the README, but I don't see an example of how to deal with tools that do not build with go get.

One concrete example is k3d (github.com/rancher/k3d).

In order to build it "correctly", you need to do something like:

git clone --depth 1 --branch v5.4.9 https://github.com/rancher/k3d
make build BINDIR=${PWD}/bin

This particular case is simple because it's just embedding a couple of version numbers using -ldflags.

Other cases are more involved, e.g. they need to pass particular values to -tags, and some authors solve that using make.

Is this something bingo can deal with, or are additional changes requires?

I would not mind working on something to address this, but I would like to hear opinions.

bwplotka commented 1 year ago

Sorry for lag, fair questions! If it's special build flags or even tags - this is already supported: https://github.com/bwplotka/bingo#advanced-techniques - however we could make it more easy to use (some extra flag "--params" to bingo get).

For git clone + custom script building this is more tricky. There is little guarantee that custom script does not require external dependencies or special architecture (rarely authors self-contain those deps). Not sure there is a solution to that, other than working with those CLI authors to make their CLI tools more accessible and self-contained Go code. Ideas welcome and if there are some popular patterns and use cases - I would be keen to learn (:

mem commented 1 year ago

Now it's me lagging behind.

I see what you mean.

In the example that I referenced, the makefile is going is grabbing the git tag and converting that to the appropriate format to pass thru ldflags so that the version number can be embedded in the resulting binary.

It would be relatively straightforward to duplicate that logic elsewhere, but the keyword is duplicate. This would need to be kept in sync with the makefile. It's unlikely that this will change, but unlikely does not mean impossible.

What I'm trying to say is that while I think individual cases have solutions, the general case doesn't. Think for example of a program that requires mage to build. The most that you can aspire to in that case is that there's a target that builds the binary and that you can control the output location. The other obvious problem is what I showed in my initial post: if something is not go-gettable, you probably need to clone a repository in order to build it.

So while I fully agree with the intuition that something that requires make to build will also require other dependencies, I think that's a problem that should be solved outside of bingo: as long as you can specify a "build script" that bingo could use, and some requirements are met, that script ought to make sure that those dependencies are available.

Does that make sense?

bwplotka commented 3 months ago

Bingo's main power is to strongly maintain the tools dependencies in the isolation, in a go.mod. I think having something custom like script/makefile generally means you need more dependencies, and thus different mechanism to guarantee them.

Some hybrid approach might work (best effort deps) for some cases, but it would make bingo get depend on other mechanism. It would be possible to change bingo to have some special tag on tools' mod file to indicate execution path and bingo would just run it, but then likely tool's go mod will be not used (script/executable would need to ensure this) and if you do this, you might as well maintain that tool via other mechanisms (brew/apt/devbox/install script).

I would keep it simple here and say this is out of scope for bingo for now, but happy to be convinced otherwise, and you're welcome to experiment! (: