Reputation: 11533
I know AppEngine does this, but I'm not coding for it.
I tried using Guard
from Ruby world, to listen on changes on .go
files, and execute the following commands:
killall foo
go build -race
./foo &
But it never sends foo
into background, it just hangs indefinitely.
How are you guys solving this problem? Solution has to be cross-platform too (GNU/Linux and Mac).
Upvotes: 49
Views: 67025
Reputation: 3876
While writing go in linux environment, you can watch the changed files and restart automatically without installing any additional programs in the local.
find . -name "*.go" | entr -r go run .
or
find . -type f \( -name '*.go' -o -name '*.gohtml' \) | entr -r sh -c 'go build -o /tmp/build ./cmd && /tmp/build'
or with docker
find . -type f \( -name '*.go' -o -name '*.gohtml' \) | entr -r sh -c 'make && docker logs --follow $(APP_NAME)'
Upvotes: 7
Reputation: 106
I tried to use Fresh and Realize but some error happened.
So I use Air and works great so far
Install with go install (for go v1.22 or higher)
go install github.com/cosmtrek/air
go to project directory and initialize .air.toml
default config file
air init
run air
air
More explanation available on Air github repository
Upvotes: 1
Reputation: 904
This method worked for me, maybe it will work for you too.
nodemon --exec go run index.go --signal SIGTERM
Upvotes: 1
Reputation: 552
Best option is to install nodejs on your machine and use nodemon
package
install nodemon with -g sudo npm install -g nodemon
Also use sudo to avoid any write permission
Now go to your program dir and run:
nodemon --watch './**/*.go' --signal SIGTERM --exec 'go' run path-to-the-main-file-of-go-program-with-extension
This will send SIGTERM every time any .go
files changes and will run go run main-go-file-of-program-with-extension
Fully cross platform. This will work for any programming language by just changing the command as
nodemon --watch './**/*.extension-of-programming-file-without-preceeding-dot' --signal SIGTERM --exec 'go' run path-to-the-main-file-of-program-with-extension
Upvotes: 6
Reputation: 2511
There is a go version of nodemon: https://github.com/mitranim/gow
go install github.com/mitranim/gow@latest
usage
# Start and restart on change
gow run .
# Pass args to the program
gow run . arg0 arg1 ...
# Run subdirectory
gow run ./subdir
# Vet and re-vet on change; verbose mode is recommended
gow -v vet
# Clear terminal on restart
gow -c run .
# Specify file extension to watch
gow -e=go,mod,html run .
# Help
gow -h
Upvotes: 26
Reputation: 1725
I used a tool called entr
To install brew install entr
(mac)
or, sudo apt-get install entr
(linux)
To recompile & run on .go
file changes, run the following command ...
ls **/*.go | entr go run main.go
Upvotes: 8
Reputation: 10060
Another option, if you have nodejs installed on your machine
install nodemon with -g npm i -g nodemon
go to your code dir and run:
nodemon --watch './**/*.go' --signal SIGTERM --exec 'go' run cmd/MyProgram/main.go
This will send SIGTERM every time any .go
files changes and will run go run cmd/Myprogram/main.go
Fully cross platform.
Upvotes: 52
Reputation: 2235
After scrolling through the internet in search of a simple solution that was using standard linux tools (inotify & bash), I ended up creating this simple bash script that does the job.
I tested it in a container running golang:1.12 and using go run .
to serve files. read the script before using it, as it kills the go run
processes depending on a folder name, and if there are conflicts with other processes that you run it might kill them.
#!/bin/bash
go run . &
while inotifywait --exclude .swp -e modify -r . ;
do
# find PID of the file generated by `go run .` to kill it. make sure the grep does not match other processes running on the system
IDS=$(ps ax | grep "/tmp/go-build" | grep "b001/exe/main" | grep -v "grep" | awk '{print $1}')
if [ ! -z "$IDS" ]
then
kill $IDS;
fi
go run . &
done;
Upvotes: 3
Reputation: 10007
there are 2 main contenders here in GO world fresh
& glide
But I will go with Fresh
https://github.com/gravityblast/fresh
Upvotes: 2
Reputation: 1189
You can use nodemon
for this. Simply create a nodemon.json file containing your configuration, files to watch, files to ignore, and command to execute when a file changes. Something like this configuration.
nodemon.json
{
"watch": ["*"],
"ext": "go graphql",
"ignore": ["*gen*.go"],
"exec": "go run scripts/gqlgen.go && (killall -9 server || true ) && go run ./server/server.go"
}
You do require nodejs for this to work.
But its far better then any other tool I've used so far that are go specific.
Upvotes: 4
Reputation: 1197
if anyone’s still looking for a solution, i wrote some shell scripts to do this and it’s usable via a docker environment, the repos at https://github.com/zephinzer/golang-dev
Upvotes: -1
Reputation: 4635
I've recently discovered a reflex tool. It's fast and works like a charm. It is very similar to nodemon (from nodejs world) and guard (from ruby world).
Most of the time I'm using it similar to below:
reflex -d none -s -R vendor. -r \.go$ -- go run cmd/server/main.go
But it maybe more convenient to have it's options in a file like .reflex, with contents like this:
-d none -s -R vendor. -r \.go$
So then you just run it like this
reflex $(cat .reflex) -- go run cmd/server/main.go
You can do same thing to "hot reload" tests:
reflex $(cat .reflex) -- go test ./... -v
There is also a config option where you can specify a number of commands you run same time, but I don't really use it.
Upvotes: 16
Reputation: 26469
You can also try out Gin by Codegangsta. It's fire and forget.
https://github.com/codegangsta/gin
EDIT: I prefer CompileDaemon nowadays. Gin sometimes won't accept requests
Upvotes: 15
Reputation: 412
A friend wrote a simple Compile Daemon for go, worked like a charm for my own small net/http-projects.
You can find the repository here: https://github.com/githubnemo/CompileDaemon
Upvotes: 29