Builds and restarts a Go project when it crashes or some watched file changes

gaper

Used to build and restart a Go project when it crashes or some watched file changes
Aimed to be used in development only.


Software License Linux - Build Status Windows - Build status Coverage Status Go Doc Go Report Card Powered By: GoReleaser

Changelog

See Releases for detailed history changes.

Installation

Using go tooling:

go get -u github.com/maxcnunes/gaper/cmd/gaper

Or, downloading the binary instead (example for version 1.0.3, make sure you are using the latest version though):

curl -SL https://github.com/maxcnunes/gaper/releases/download/v1.0.3/gaper_1.0.3_linux_amd64.tar.gz | tar -xvzf - -C "${GOPATH}/bin"

Usage

NAME:
   gaper - Used to build and restart a Go project when it crashes or some watched file changes

USAGE:
   gaper [global options] command [command options] [arguments...]

VERSION:
   version

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --bin-name value                 name for the binary built by gaper for the executed program (default current directory name)
   --build-path value               path to the program source code (default: ".")
   --build-args value               arguments used on building the program
   --program-args value             arguments used on executing the program
   --verbose                        turns on the verbose messages from gaper
   --disable-default-ignore         turns off default ignore for hidden files and folders, "*_test.go" files, and vendor folder
   --watch value, -w value          list of folders or files to watch for changes
   --ignore value, -i value         list of folders or files to ignore for changes
   --poll-interval value, -p value  how often in milliseconds to poll watched files for changes (default: 500)
   --extensions value, -e value     a comma-delimited list of file extensions to watch for changes (default: "go")
   --no-restart-on value, -n value  don't automatically restart the supervised program if it ends:
                                      if "error", an exit code of 0 will still restart.
                                      if "exit", no restart regardless of exit code.
                                      if "success", no restart only if exit code is 0.
   --help, -h                       show help
   --version, -v                    print the version

Watch and Ignore paths

For those options Gaper supports static paths (e.g. build/, seed.go) or glob paths (e.g. migrations/**/up.go, *_test.go).

On using a path to a directory please add a / at the end (e.g. build/) to make sure Gaper won't include other matches that starts with that same value (e.g. build/, build_settings.go).

Default ignore settings

Since in most projects there is no need to watch changes of:

  • hidden files and folders
  • test files (*_test.go)
  • vendor folder

Gaper by default ignores those cases already. Although, if you need Gaper to watch those files anyway it is possible to disable this setting with --disable-default-ignore argument.

Watch method

Currently Gaper uses polling to watch file changes. We have plans to support fs events though in a near future.

Examples

Using all defaults provided by Gaper:

gaper

Ignore watch over all test files:

no need for this if you have not disabled the default ignore settings --disable-default-ignore

--ignore './**/*_test.go'

Contributing

See the Contributing guide for steps on how to contribute to this project.

Reference

This package was heavily inspired by gin and node-supervisor.

Basically, Gaper is a mixing of those projects above. It started from gin code base and I rewrote it aiming to get something similar to node-supervisor (but simpler). A big thanks for those projects and for the people behind it! πŸ‘ πŸ‘

How is Gaper different of Gin

The main difference is that Gaper removes a layer of complexity from Gin which has a proxy running on top of the executed server. It allows to postpone a build and reload the server when the first call hits it. With Gaper we don't care about that feature, it just restarts your server whenever a change is made.

Owner
Max Claus Nunes
@maxcnunes on Twitter, Facebook, and etc.
Max Claus Nunes
Comments
  • Not working with different extensions

    Not working with different extensions

    I have a project which I would like to restart when a YAML file changes, but even if I pass the -w full path to that file or if I include its extension with --extensions='go,yaml' it still not detecting it has changed.

  • Error installing gaper

    Error installing gaper

    In case you are getting this error below, it is caused by a depency used by gaper, the github.com/urfave/cli which had a breaking change recently and broke the gaper build:

    # github.com/maxcnunes/gaper/cmd/gaper
    ../../maxcnunes/gaper/cmd/gaper/main.go:44:13: cannot use func literal (type func(*cli.Context)) as type cli.ActionFunc in assignment
    ../../maxcnunes/gaper/cmd/gaper/main.go:55:14: cannot make type cli.StringSlice
    ../../maxcnunes/gaper/cmd/gaper/main.go:62:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
            cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
    ../../maxcnunes/gaper/cmd/gaper/main.go:66:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
            cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
    ../../maxcnunes/gaper/cmd/gaper/main.go:71:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
            cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
    ../../maxcnunes/gaper/cmd/gaper/main.go:75:17: cannot use cli.StringFlag literal (type cli.StringFlag) as type cli.Flag in array or slice literal:
            cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver)
    ../../maxcnunes/gaper/cmd/gaper/main.go:79:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
            cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
    ../../maxcnunes/gaper/cmd/gaper/main.go:83:15: cannot use cli.BoolFlag literal (type cli.BoolFlag) as type cli.Flag in array or slice literal:
            cli.BoolFlag does not implement cli.Flag (Apply method has pointer receiver)
    

    I have changed gaper to use go modules and it now have locked versions for all depdencies. In order to use that fixing you will need to use a version of Go with Modules support and (>=1.11) and make sure you have Go Modules enabled, example:

    GO111MODULE=on go get -u github.com/maxcnunes/gaper/cmd/gaper
    
  • suggest add example

    suggest add example

    hi,

    for some reasons i have struggled to get it work. i suggest to put an example like

    gaper -w 'public/**' -w '*.go' -e js -e css -e html --verbose

  • Ignore *-go-tmp-umask

    Ignore *-go-tmp-umask

    [gaper] error on watching files: couldn't walk to path "web-service-go-tmp-umask": lstat web-service-go-tmp-umask: no such file or directory
    
  • invalid memory address or nil pointer dereference error

    invalid memory address or nil pointer dereference error

    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0xa0 pc=0x4d0ca6]
    
    goroutine 154 [running]:
    os/exec.(*Cmd).Wait(0x0, 0x5bc683, 0xc42000a060)
          /usr/local/go/src/os/exec/exec.go:453 +0x26
    github.com/maxcnunes/gaper.(*runner).runBin.func1(0xc4200b2000)
          /go/src/github.com/maxcnunes/gaper/runner.go:159 +0x2f
    created by github.com/maxcnunes/gaper.(*runner).runBin
          /go/src/github.com/maxcnunes/gaper/runner.go:158 +0x25d
    make: *** [Makefile:18: start] Error 2
    
  • Loop building and starting

    Loop building and starting

    Some times it enters in a loop building and starting the program. Improve error handler and maybe show more datails if the build restarted like 5 times in row (just a temporary solution to find out what is going on).

    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    [gaper] Starting program
    [gaper] Building program
    
  • Invalid memory during restart

    Invalid memory during restart

    I got this error today:

    [gaper] Building program
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x500de6]
    goroutine 15 [running]:
    github.com/maxcnunes/gaper.(*watcher).ignoreFile(0xc420450000, 0xc4201e82c0, 0x16, 0x0, 0x0, 0x0)
    /go/src/github.com/maxcnunes/gaper/watcher.go:144 +0x86
    github.com/maxcnunes/gaper.(*watcher).scanChange.func1(0xc4201e82c0, 0x16, 0x0, 0x0, 0x5bd4e0, 0xc42006cf90, 0x0, 0x0)
    /go/src/github.com/maxcnunes/gaper/watcher.go:120 +0x64
    path/filepath.walk(0x59d839, 0x1, 0x5bea20, 0xc4204f3380, 0xc42000a7c0, 0x0, 0x20)
    /usr/local/go/src/path/filepath/path.go:377 +0x20d
    path/filepath.Walk(0x59d839, 0x1, 0xc42000a7c0, 0x2, 0xc420080328)
    /usr/local/go/src/path/filepath/path.go:403 +0x106
    github.com/maxcnunes/gaper.(*watcher).scanChange(0xc420450000, 0x59d839, 0x1, 0x0, 0x0, 0x0, 0x0)
    /go/src/github.com/maxcnunes/gaper/watcher.go:119 +0x13a
    github.com/maxcnunes/gaper.(*watcher).Watch(0xc420450000)
    /go/src/github.com/maxcnunes/gaper/watcher.go:87 +0x72
    created by github.com/maxcnunes/gaper.run
    /go/src/github.com/maxcnunes/gaper/gaper.go:99 +0x23d
    make: *** [Makefile:19: start] Error 2
    
  • Fix extensions argument to support comma-delimited extension values

    Fix extensions argument to support comma-delimited extension values

    If we need to pass multiple extensions nowadays we have to provide one argument for each extension -e js -e html. It could be helpful to be able to pass a single argument `-e "js,html".

  • Some times gaper get stuck and don't rebuild or restart the application anymore

    Some times gaper get stuck and don't rebuild or restart the application anymore

    It seems to happen sometimes after there was a building error like:

    [gaper] Building program
    [gaper] Error building binary during a restart: build failed with exit status 2
    # github.com/project/api
    api/proxy.go:39:35: undefined: hs
    
  • Panic Hit (nil pointer dereference)

    Panic Hit (nil pointer dereference)

    gaper was rebuilding after a code update, and panicked:

    app    | [gaper] Building program
    app    | panic: runtime error: invalid memory address or nil pointer dereference
    app    | [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5071b2]
    app    |
    app    | goroutine 24 [running]:
    app   | github.com/maxcnunes/gaper.skipFile(0x0, 0x0, 0x9, 0x0)
    app   | 	/go/src/github.com/maxcnunes/gaper/watcher.go:243 +0x22
    app    | github.com/maxcnunes/gaper.(*watcher).scanChange.func1(0xc0003297a0, 0x9, 0x0, 0x0, 0x5cf2e0, 0xc000112480, 0x0, 0x0)
    app    | 	/go/src/github.com/maxcnunes/gaper/watcher.go:121 +0x196
    app    | path/filepath.walk(0x5a4fa9, 0x1, 0x5d0800, 0xc00027d5f0, 0xc000089300, 0x0, 0x20)
    app   | 	/usr/local/go/src/path/filepath/path.go:378 +0x21f
    app    | path/filepath.Walk(0x5a4fa9, 0x1, 0xc000089300, 0x2, 0xc0000a03a8)
    app    | 	/usr/local/go/src/path/filepath/path.go:404 +0x105
    app    | github.com/maxcnunes/gaper.(*watcher).scanChange(0xc00008a640, 0x5a4fa9, 0x1, 0x0, 0x0, 0x0, 0x0)
    app    | 	/go/src/github.com/maxcnunes/gaper/watcher.go:119 +0x131
    app    | github.com/maxcnunes/gaper.(*watcher).Watch(0xc00008a640)
    app    | 	/go/src/github.com/maxcnunes/gaper/watcher.go:87 +0x72
    app    | created by github.com/maxcnunes/gaper.run
    app    | 	/go/src/github.com/maxcnunes/gaper/gaper.go:99 +0x23d
    

    This was running in a docker container: golang:alpine

  • Use a single logger instance

    Use a single logger instance

    There are two instances of logger in cmd/gaper/main.go and gaper.go. The Verbose option is only set to cmd/gaper/main.go which is causing the verbose not work as expected.

  • Add fs event watcher support

    Add fs event watcher support

    Initially, this tool was implemented with polling support only because of my previous experience with Docker volumes and fs events weren't stable. Looks like it has changed and using Docker volumes with :delegated is stable nowadays. So, it makes sense adding support for fs events since it has a much better performance than polling.

  • The default settings is trying to watch not allowed files

    The default settings is trying to watch not allowed files

    [gaper] error on watching files: couldn't walk to path "loadtest/report/bzt.log": lstat loadtest/report/bzt.log: no such file or directory
    make: *** [Makefile:18: start] Error 1
    
Monitoring changes in the source file and automatically compile and run (restart).
Monitoring changes in the source file and automatically compile and run (restart).

dogo Monitoring changes in the source file and automatically compile and run (restart). δΈ­ζ–‡ Install go get github.com/liudng/dogo Create config Here's

Dec 28, 2022
GoReleaser builds Go binaries as fast and easily as possible
GoReleaser builds  Go binaries as fast and easily as possible

GoReleaser builds Go binaries for several platforms, creates a GitHub release and then pushes a Homebrew formula to a tap repository. All that wrapped in your favorite CI.

Jan 7, 2023
Please is a cross-language high-performance extensible build system for reproducible multi-language builds.

Please is a cross-language build system with an emphasis on high performance, extensibility and reproducibility. It supports a number of popular languages and can automate nearly any aspect of your build process.

Dec 30, 2022
A small utility that aims to automate and simplify some tasks related to software release cycles.

Stork is a small utility that aims to automate and simplify some tasks related to software release cycles such as reading the current version from a f

Nov 9, 2022
Moldy CLI the best project starter and manager of the world
Moldy CLI the best project starter and manager of the world

Moldy The best project starter of the world ?? What is Moldy ? Hey I present Moldy this beautiful tool that will solve your life in creating, managing

Oct 17, 2022
Frictionless way of managing project-specific commands
Frictionless way of managing project-specific commands

1build is an automation tool used for research and development projects that arms you with the convenience to configure project-local command line ali

Dec 25, 2022
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.

#1 Golang live reload and task runner Content - ⭐️ Top Features - ???? Get started - ?? Config sample - ?? Commands List - ?? Support and Suggestions

Jan 6, 2023
Various tools for usage with Golang like installer, github tool and cloud features.

Gopei2 (Go Programming Environment Installer) Gopei shell install Go compiler, LiteIDE and configure for you the entire environment, variables, paths,

Dec 23, 2022
a build tool for Go, with a focus on cross-compiling, packaging and deployment

goxc NOTE: goxc has long been in maintenance mode. Ever since Go1.5 supported simple cross-compilation, this tool lost much of its value. There are st

Dec 9, 2022
An extremely fast JavaScript bundler and minifier
An extremely fast JavaScript bundler and minifier

An extremely fast JavaScript bundler and minifier

Jan 4, 2023
Build system and task runner for Go projects
Build system and task runner for Go projects

Gilbert is task runner that aims to provide declarative way to define and run tasks like in other projects like Gradle, Maven and etc.

Dec 21, 2022
Build and (re)start go web apps after saving/creating/deleting source files.

unmaintained Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web f

Jan 2, 2023
NFPM is Not FPM - a simple deb, rpm and apk packager written in Go

NFPM NFPM is Not FPM - a simple deb, rpm and apk packager written in Go. Why While fpm is great, for me, it is a bummer that it depends on ruby, tar a

Jan 1, 2023
KintoHub is an open source build and deployment platform designed with a developer-friendly interface for Kubernetes.
KintoHub is an open source build and deployment platform designed with a developer-friendly interface for Kubernetes.

What is Kintohub? KintoHub is an open source build and deployment platform designed with a developer-friendly interface for Kubernetes. Build your cod

Jun 7, 2022
A command line tool that builds and (re)starts your web application everytime you save a Go or template fileA command line tool that builds and (re)starts your web application everytime you save a Go or template file

# Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web framework yo

Nov 22, 2021
apicompat checks recent changes to a Go project for backwards incompatible changes

Introduction apicompat is a tool to check for the introduction of backwards incompatible changes. apicompat: Guarantees that all consumers of a librar

Dec 24, 2022
Oct 1, 2021
A demo project that automatically restarts with a trio of docker, redis and go and transmits page visits.
A demo project that automatically restarts with a trio of docker, redis and go and transmits page visits.

A demo project that automatically restarts with a trio of docker, redis and go and transmits page visits.

Feb 6, 2022
Monitor & detect crashes in your Kubernetes(K8s) cluster
Monitor & detect crashes in your Kubernetes(K8s) cluster

kwatch kwatch helps you monitor all changes in your Kubernetes(K8s) cluster, detects crashes in your running apps in realtime, and publishes notificat

Dec 28, 2022