jdx / mise

dev tools, env vars, task runner
https://mise.jdx.dev
MIT License
9.78k stars 277 forks source link

go backend doesn't cleanly install tools without version (i.e. latest) #2766

Open davepgreene opened 1 week ago

davepgreene commented 1 week ago

The problem

Following on from discussion in https://github.com/jdx/mise/issues/2593, the go backend does a bunch of work swapping the v prefix in and out so that the user doesn't have to specify it. However, this limits the ability to simply target latest or install a git ref cleanly. I think, based on the conversation in #2593 and the PR https://github.com/jdx/mise/pull/2606, that the effort is generally to allow for listing versions by assuming a normal mod structure which makes sense.

Some tests

Installing from latest

❯ mise use -g go:github.com/mrtazz/checkmake/cmd/checkmake@latest
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
go: github.com/mrtazz/checkmake/cmd/checkmake@vlatest: github.com/mrtazz/checkmake/cmd/checkmake@vlatest: invalid version: unknown revision vlatest
mise ERROR go failed
go: github.com/mrtazz/checkmake/cmd/checkmake@vlatest: github.com/mrtazz/checkmake/cmd/checkmake@vlatest: invalid version: unknown revision vlatest
mise WARN  Failed to install, trying again without added 'v' prefix
mise go:github.com/mrtazz/checkmake/cmd/checkmake@latest ✓ installed
mise ~/.config/mise/config.toml tools: go:github.com/mrtazz/checkmake/cmd/checkmake@latest
❯ which checkmake
/home/dgreene/.local/share/mise/installs/go-github-com-mrtazz-checkmake-cmd-checkmake/latest/bin/checkmake

Installing from ref

❯ mise use -g go:github.com/mrtazz/checkmake/cmd/checkmake@849025d1621f96973658e682f4304d7972ee7b28
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
go: github.com/mrtazz/checkmake/cmd/checkmake@v849025d1621f96973658e682f4304d7972ee7b28: github.com/mrtazz/checkmake/cmd/checkmake@v849025d1621f96973658e682f4304d7972ee7b28: invalid version: unknown revision v849025d1621f96973658e682f4304d7972ee7b28
mise ERROR go failed
go: github.com/mrtazz/checkmake/cmd/checkmake@v849025d1621f96973658e682f4304d7972ee7b28: github.com/mrtazz/checkmake/cmd/checkmake@v849025d1621f96973658e682f4304d7972ee7b28: invalid version: unknown revision v849025d1621f96973658e682f4304d7972ee7b28
mise WARN  Failed to install, trying again without added 'v' prefix
mise go:github.com/mrtazz/checkmake/cmd/checkmake@849025d1621f96973658e682f4304d7972ee7b28 ✓ installed
mise ~/.config/mise/config.toml tools: go:github.com/mrtazz/checkmake/cmd/checkmake@849025d1621f96973658e682f4304d7972ee7b28
❯ which checkmake
/home/dgreene/.local/share/mise/installs/go-github-com-mrtazz-checkmake-cmd-checkmake/849025d1621f96973658e682f4304d7972ee7b28/bin/checkmake

So installation succeeds but with errors. Additionally, running mise ls adds a WARN at the top of the output:

❯ mise ls
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
mise WARN  No versions found for go:github.com/mrtazz/checkmake/cmd/checkmake
Tool                                          Version                                   Config Source              Requested
...
go:github.com/mrtazz/checkmake/cmd/checkmake  849025d1621f96973658e682f4304d7972ee7b28  ~/.config/mise/config.toml 849025d1621f96973658e682f4304d7972ee7b28
...

Obviously autocomplete doesn't know how to handle the version either which makes managing a bit of a bear although mise rm does work properly.

Curious to know what folks thoughts are around adjusting the logic to attempt to match a tag first, then a ref, then latest when listing and then not do any v prefixing logic on installation.

jdx commented 1 week ago

@roele do you think this would work? https://github.com/jdx/mise/issues/2402

If this information is meant to be used by a tool, I think the best bet would be to make a new temporary module, run go get pkg@version to resolve the package to the module, run go list -f '{{.Module.Path}} pkg to determine the module path for the packgage, and then run go list -m -versions mod to get the versions of the module containing the package.

seems like a lot of hoops to jump through under the hood, but sounds like it would get us the data we need since it would be pulling the version list using go instead of us trying to replicate it with similar logic

roele commented 1 week ago

This does not seem to help in getting a list of available versions but rather only resolves the latest version. And in case of invalid versioning shows v0.0.0 with a timestamp-hash suffix.

❯ mkdir go-mod-test
❯ cd go-mod-test/
❯ go mod init jdx/go-mod-tmp
go: creating new go.mod: module jdx/go-mod-tmp
❯ go get github.com/mrtazz/checkmake/cmd/checkmake@latest
go: downloading github.com/mrtazz/checkmake v0.0.0-20230817110936-bd26d7905e47
go: downloading github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
go: downloading github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: downloading github.com/go-ini/ini v1.11.0
go: added github.com/docopt/docopt-go v0.0.0-20141128170934-854c423c8108
go: added github.com/go-ini/ini v1.11.0
go: added github.com/mrtazz/checkmake v0.0.0-20230817110936-bd26d7905e47
go: added github.com/olekukonko/tablewriter v0.0.0-20150822215231-b9346ac189c5
❯ go list -f '{{.Module.Path}}' github.com/mrtazz/checkmake/cmd/checkmake
github.com/mrtazz/checkmake
❯ go list -m -versions -json github.com/mrtazz/checkmake
{
    "Path": "github.com/mrtazz/checkmake",
    "Version": "v0.0.0-20230817110936-bd26d7905e47",
    "Time": "2023-08-17T11:09:36Z",
    "Indirect": true,
    "Dir": "/Users/../go/pkg/mod/github.com/mrtazz/checkmake@v0.0.0-20230817110936-bd26d7905e47",
    "GoMod": "/Users/../go/pkg/mod/cache/download/github.com/mrtazz/checkmake/@v/v0.0.0-20230817110936-bd26d7905e47.mod",
    "GoVersion": "1.17",
    "Sum": "h1:rmQ0hKeAdGpokOFKiETzNz/rBo3hKbYk8o40ILnASj8=",
    "GoModSum": "h1:QmxUHDy3sMpsO8+VgE72n+3ksnWbYWXBoDHaYfMntKo="
}
davepgreene commented 1 week ago

Commenting here as an outsider to the project so take my opinion with a grain of salt: trying to figure out versions of a Go project is a fool's errand. Because of how Go works versioning isn't actually a versioned artifact, it's just a git ref. The best you get outside of that is the major version delineation in the import path but even that tracks against a tag.

I think a best effort such as listing tags but allowing an un-validated pass-through to go install satisfies enough of the backend's intent to avoid the level of complexity that y'all are talking about. Just my 2 cents.

jdx commented 1 week ago

ah ok, I was misled by the go list -m versions. I think maybe we could use this logic for latest_stable_version though.