diff --git a/Makefile b/Makefile index 3a9ac2f..040c1b9 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all: clean build run run: @echo "==> Running" - @${BIN} + @${BIN} run build: deps fmt @echo "==> Building for prod" diff --git a/cmd/parser.go b/cmd/parser.go new file mode 100644 index 0000000..9d4a45f --- /dev/null +++ b/cmd/parser.go @@ -0,0 +1,10 @@ +package cmd + +import "github.com/jessevdk/go-flags" + +// Parser will parse command line +var Parser *flags.Parser + +func init() { + Parser = flags.NewParser(nil, flags.Default) +} diff --git a/cmd/run.go b/cmd/run.go new file mode 100644 index 0000000..af1d70a --- /dev/null +++ b/cmd/run.go @@ -0,0 +1,29 @@ +package cmd + +import ( + "fmt" + "time" + + "github.com/Neur0toxine/demo-web-service-go/internal" + "github.com/brianvoe/gofakeit/v6" +) + +func init() { + _, err := Parser.AddCommand("run", "Run the application", "", &RunCommand{}) + if err != nil { + panic(err) + } +} + +// RunCommand is used to run the server +type RunCommand struct{} + +func (c *RunCommand) Execute(args []string) error { + gofakeit.Seed(time.Now().UnixNano()) + go internal.ProcessSignals() + r := internal.Router() + if err := r.Run(":8080"); err != nil { + return fmt.Errorf("cannot start the server on :8080 > %w", err) + } + return nil +} diff --git a/go.mod b/go.mod index 6d33340..afde7e9 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/brianvoe/gofakeit/v6 v6.7.1 github.com/gin-gonic/gin v1.7.4 + github.com/jessevdk/go-flags v1.5.0 github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index 30a4f29..02800fd 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -77,6 +79,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= diff --git a/handlers.go b/internal/handlers.go similarity index 71% rename from handlers.go rename to internal/handlers.go index c1d5fbf..682b8f1 100644 --- a/handlers.go +++ b/internal/handlers.go @@ -1,4 +1,4 @@ -package main +package internal import ( "net/http" @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" ) +// AuthorsHandler will return formatted JSOn response with authors func AuthorsHandler(c *gin.Context) { c.IndentedJSON(http.StatusOK, repository.Authors()) } diff --git a/handlers_test.go b/internal/handlers_test.go similarity index 96% rename from handlers_test.go rename to internal/handlers_test.go index 2b5955c..a322658 100644 --- a/handlers_test.go +++ b/internal/handlers_test.go @@ -1,4 +1,4 @@ -package main +package internal import ( "encoding/json" @@ -16,7 +16,7 @@ func TestAuthorsHandler(t *testing.T) { req, err := http.NewRequest(http.MethodGet, "/authors", nil) require.NoError(t, err) - r := router() + r := Router() rec := httptest.NewRecorder() r.ServeHTTP(rec, req) diff --git a/internal/router.go b/internal/router.go new file mode 100644 index 0000000..daa4c0f --- /dev/null +++ b/internal/router.go @@ -0,0 +1,12 @@ +package internal + +import ( + "github.com/gin-gonic/gin" +) + +// Router controls the routes +func Router() (r *gin.Engine) { + r = gin.New() + r.GET("/authors", AuthorsHandler) + return +} diff --git a/internal/signals.go b/internal/signals.go new file mode 100644 index 0000000..7a54b8c --- /dev/null +++ b/internal/signals.go @@ -0,0 +1,22 @@ +package internal + +import ( + "log" + "os" + "os/signal" + "syscall" +) + +// ProcessSignals will react to app termination. It doesn't do much for now, but it can be useful later. +// For example, we can close active DB or WebSocket connections here, or perform any other actions +// related to the graceful shutdown. +func ProcessSignals() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) + + for { + <-c + log.Println("Quitting...") + os.Exit(0) + } +} diff --git a/main.go b/main.go index 56725b6..a0128cf 100644 --- a/main.go +++ b/main.go @@ -1,17 +1,17 @@ package main import ( - "log" - "time" + "os" - "github.com/brianvoe/gofakeit/v6" + "github.com/Neur0toxine/demo-web-service-go/cmd" + "github.com/jessevdk/go-flags" ) func main() { - gofakeit.Seed(time.Now().UnixNano()) - go processSignals() - r := router() - if err := r.Run(":8080"); err != nil { - log.Fatalf("cannot start the server on :8080 > %s", err) + if _, err := cmd.Parser.Parse(); err != nil { + if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp { + os.Exit(0) + } + os.Exit(-1) } } diff --git a/router.go b/router.go deleted file mode 100644 index 3e4f68a..0000000 --- a/router.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import "github.com/gin-gonic/gin" - -func router() (r *gin.Engine) { - r = gin.New() - r.GET("/authors", AuthorsHandler) - return -} diff --git a/signals.go b/signals.go deleted file mode 100644 index b13b1a9..0000000 --- a/signals.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "log" - "os" - "os/signal" - "syscall" -) - -func processSignals() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) - - for { - <-c - log.Println("Quitting...") - os.Exit(0) - } -}