-
Notifications
You must be signed in to change notification settings - Fork 75
Description
Sometimes it's very inconvenient to have one .go file per script: either because script is large enough or because we wanna reuse some code located in separate files or because our tools (LSP, linter) are not happy to see multiple files with func main() in same directory.
In these cases we wanna have a directory per script, usually inside some common "scripts/" directory:
$ mkdir scripts
$ cd scripts
$ go mod init scripts
go: creating new go.mod: module scripts
$ mkdir example
$ echo 'package main; func main() { println("Example!") }' > example/main.go
Now, we usually wanna run these scripts outside of scripts/ directory, e.g. in some project's root dir. And one more thing: this project may or may not use Go, but if it uses Go then we anyway don't wanna place scripts/ into same Go module as a project itself - to avoid adding scripts dependencies to project's go.mod located in a project's root dir.
$ cd .. # leave scripts/, now we're in a project's root dir
$ gorun ./scripts/example
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
error: failed to run go: exit status 1
The one workaround for this issue is to give file names to gorun instead of a directory, but this has many downsides: func main() must be in a first of provided files (so gorun ./scripts/example/*.go often won't work as expected), the real go.mod (used by LSP/linter while developing scripts) won't be used by gorun (and embedding go.mod inside a script means needs to keep both versions of go.mod in sync), and after all it's just inconvenient.
I propose to solve this issue using go.work file instead:
$ cd scripts
$ go work init
$ go work use .
Now everything works as expected:
$ cd .. # leave scripts/, now we're in a project's root dir
$ GOWORK=$PWD/scripts/go.work gorun ./scripts/example
Example!
The needs to set $GOWORK might be a lesser evil for many projects and can be done inside a Makefile/Taskfile/etc.
Also, this managing of GOWORK can be implemented by gorun itself to make it really convenient: gorun can create go.work file in a temporary directory in such cases automatically, so users won't have to create go.work files and set $GOWORK.