To allow executing Go tools without the need to install them. This is similar to how npx is operating. For example, using npx, you can invoke the following command, and npx will fetch snyk package and run it passing args:
$ npx snyk@v1 test --print-deps
I think similar behavior could be added to go run command. It already allows executing packages that are part of our GOPATH. When a given package isn't part of our module (or we are not within the module), we can create an ad-hoc module in user home directory, install the requested package there, and run it in the original directory for user profit.
$ go run github.com/cli/cli/v2/cmd/gh@v2 pr list --repo knative-sandbox/kn-plugin-event
What did you do?
To achieve that behavior with current Go, I use the following Bash functions:
# go.get-tool will 'go get' any package $2 and install it to $1. Replaces, can
# be set with $GO_GETTOOL_REPLACES.
function go.get-tool {
local tmp_dir
if ! [ -f "${1}" ]; then
tmp_dir="$(mktemp -d)"
# shellcheck disable=SC2064
trap "rm -rf ${tmp_dir}" EXIT
pushd "$tmp_dir" >/dev/null 2>&1
go mod init tmp
if [ -n "${GO_GETTOOL_REPLACES:-}" ]; then
go mod edit -replace "${GO_GETTOOL_REPLACES}"
fi
echo "Downloading ${2}"
GOBIN="$(dirname "${1}")" go get "${2}"
popd >/dev/null 2>&1
fi
echo "Using ${2} in ${1}"
}
# go.run-tool will 'go get' package $1 and install it to temp path. Replaces,
# can be set with $GO_GETTOOL_REPLACES. You could pass arguments to the tool by
# setting $2 and up.
function go.run-tool {
local path_id systmp_dir bin_dir package package_id bin
package="${1:?'Pass a GO executable package ref as arg[1]'}"
shift
path_id="$(echo "${BASH_SOURCE[0]:-$0}" | sha1sum - | awk '{print $1}')"
package_id="$(echo "$package" | sha1sum - | awk '{print $1}')"
systmp_dir="$(dirname "$(mktemp -d -u)")"
bin_dir="${systmp_dir}/go-run-tool/${path_id}/${package_id}"
mkdir -p "$bin_dir"
bin="${package%@*}"
bin="${bin_dir}/${bin##*/}"
go.get-tool "$bin" "$package"
"$bin" "$@"
}
By having those, I could execute command like:
$ go.run-tool \
github.com/cli/cli/v2/cmd/gh@v2.2.1-0.20211122114001-a3940020f938 \
pr list
What did you expect to see?
I'd like to have my Go tool fetched and executed, just as it does with my script wrapper go.run-tool.
What did you see instead?
package github.com/cli/cli/v2/cmd/gh@v2.2.1-0.20211122114001-a3940020f938: can only use path@version syntax with 'go get' and 'go install' in module-aware mode
or when outside of module
no required module provides package github.com/cli/cli/v2/cmd/gh: working directory is not part of a module
Proposal
To allow executing Go tools without the need to install them. This is similar to how npx is operating. For example, using npx, you can invoke the following command, and npx will fetch
snyk
package and run it passing args:I think similar behavior could be added to
go run
command. It already allows executing packages that are part of our GOPATH. When a given package isn't part of our module (or we are not within the module), we can create an ad-hoc module in user home directory, install the requested package there, and run it in the original directory for user profit.What did you do?
To achieve that behavior with current Go, I use the following Bash functions:
By having those, I could execute command like:
What did you expect to see?
I'd like to have my Go tool fetched and executed, just as it does with my script wrapper
go.run-tool
.What did you see instead?
or when outside of module