Switch to kong command-line parser (#66)

* Update workflows

Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2020-05-08 19:30:56 +02:00
committed by GitHub
parent 9c797f1616
commit ab56764464
15 changed files with 85 additions and 88 deletions

View File

@@ -44,19 +44,13 @@ jobs:
- -
# https://github.com/actions/setup-go # https://github.com/actions/setup-go
name: Set up Go name: Set up Go
uses: actions/setup-go@master uses: actions/setup-go@v2
with: with:
go-version: 1.13 go-version: 1.13
-
name: Set GOPATH
# temporary fix (see https://github.com/actions/setup-go/issues/14)
run: |
echo "##[set-env name=GOPATH;]$(dirname $GITHUB_WORKSPACE)"
echo "##[add-path]$(dirname $GITHUB_WORKSPACE)/bin"
- -
# https://github.com/actions/checkout # https://github.com/actions/checkout
name: Checkout name: Checkout
uses: actions/checkout@v1 uses: actions/checkout@v2
- -
# https://github.com/goreleaser/goreleaser-action # https://github.com/goreleaser/goreleaser-action
name: GoReleaser name: GoReleaser
@@ -122,12 +116,10 @@ jobs:
# https://github.com/crazy-max/ghaction-docker-buildx # https://github.com/crazy-max/ghaction-docker-buildx
name: Set up Docker Buildx name: Set up Docker Buildx
uses: crazy-max/ghaction-docker-buildx@v1 uses: crazy-max/ghaction-docker-buildx@v1
with:
version: latest
- -
# https://github.com/actions/checkout # https://github.com/actions/checkout
name: Checkout name: Checkout
uses: actions/checkout@v1 uses: actions/checkout@v2
- -
name: Docker Buildx (build) name: Docker Buildx (build)
run: | run: |

View File

@@ -16,11 +16,13 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v1 uses: actions/checkout@v2
- -
# https://github.com/actions/checkout/issues/6 # https://github.com/actions/setup-go
name: Fix detached HEAD name: Set up Go
run: git checkout ${GITHUB_REF#refs/heads/} uses: actions/setup-go@v2
with:
go-version: 1.13
- -
name: Tidy name: Tidy
run: | run: |

View File

@@ -15,11 +15,11 @@ jobs:
- -
# https://github.com/actions/checkout # https://github.com/actions/checkout
name: Checkout name: Checkout
uses: actions/checkout@v1 uses: actions/checkout@v2
- -
# https://github.com/crazy-max/ghaction-github-labeler # https://github.com/crazy-max/ghaction-github-labeler
name: Run Labeler name: Run Labeler
if: success() if: success()
uses: crazy-max/ghaction-github-labeler@v1 uses: crazy-max/ghaction-github-labeler@v2
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -49,7 +49,7 @@
* Add Docker provider (#3) * Add Docker provider (#3)
* Docker client v19.03.5 * Docker client v19.03.5
* Move `image` field to providers layer and rename it `static` * Move `image` field to providers layer and rename it `static`
* Update libs * Update deps
* Go 1.13.5 * Go 1.13.5
* Seconds field optional for schedule * Seconds field optional for schedule
@@ -59,7 +59,7 @@
## 1.4.1 (2019/10/20) ## 1.4.1 (2019/10/20)
* Update libs * Update deps
* Fix Docker labels * Fix Docker labels
## 1.4.0 (2019/10/01) ## 1.4.0 (2019/10/01)
@@ -90,13 +90,13 @@
## 1.2.0 (2019/08/18) ## 1.2.0 (2019/08/18)
* Update libs * Update deps
* Display containers/image logs * Display containers/image logs
* Fix registry options not setted (Issue #5) * Fix registry options not setted (Issue #5)
## 1.1.0 (2019/07/24) ## 1.1.0 (2019/07/24)
* Update libs * Update deps
## 1.0.2 (2019/07/01) ## 1.0.2 (2019/07/01)

View File

@@ -20,7 +20,7 @@
## Features ## Features
* Allow to watch a full Docker repository and report new tags * Allow to watch a Docker repository and report new tags
* Include and exclude filters with regular expression for tags * Include and exclude filters with regular expression for tags
* Internal cron implementation through go routines * Internal cron implementation through go routines
* Worker pool to parallelize analyses * Worker pool to parallelize analyses

View File

@@ -1,13 +1,14 @@
package main package main
import ( import (
"fmt"
"os" "os"
"os/signal" "os/signal"
"runtime" "runtime"
"syscall" "syscall"
"time" "time"
"github.com/alecthomas/kingpin" "github.com/alecthomas/kong"
"github.com/crazy-max/diun/internal/app" "github.com/crazy-max/diun/internal/app"
"github.com/crazy-max/diun/internal/config" "github.com/crazy-max/diun/internal/config"
"github.com/crazy-max/diun/internal/logging" "github.com/crazy-max/diun/internal/logging"
@@ -17,7 +18,7 @@ import (
var ( var (
diun *app.Diun diun *app.Diun
flags model.Flags cli model.Cli
version = "dev" version = "dev"
) )
@@ -25,24 +26,26 @@ func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
// Parse command line // Parse command line
kingpin.Flag("config", "Diun configuration file.").Envar("CONFIG").Required().StringVar(&flags.Cfgfile) _ = kong.Parse(&cli,
kingpin.Flag("timezone", "Timezone assigned to Diun.").Envar("TZ").Default("UTC").StringVar(&flags.Timezone) kong.Name("diun"),
kingpin.Flag("log-level", "Set log level.").Envar("LOG_LEVEL").Default("info").StringVar(&flags.LogLevel) kong.Description(`Docker image update notifier. More info: https://github.com/crazy-max/diun`),
kingpin.Flag("log-json", "Enable JSON logging output.").Envar("LOG_JSON").Default("false").BoolVar(&flags.LogJSON) kong.UsageOnError(),
kingpin.Flag("log-caller", "Enable to add file:line of the caller.").Envar("LOG_CALLER").Default("false").BoolVar(&flags.LogCaller) kong.Vars{
kingpin.UsageTemplate(kingpin.CompactUsageTemplate).Version(version).Author("CrazyMax") "version": fmt.Sprintf("%s", version),
kingpin.CommandLine.Name = "diun" },
kingpin.CommandLine.Help = `Docker image update notifier.\nMore info: https://github.com/crazy-max/diun` kong.ConfigureHelp(kong.HelpOptions{
kingpin.Parse() Compact: true,
Summary: true,
}))
// Load timezone location // Load timezone location
location, err := time.LoadLocation(flags.Timezone) location, err := time.LoadLocation(cli.Timezone)
if err != nil { if err != nil {
log.Panic().Err(err).Msgf("Cannot load timezone %s", flags.Timezone) log.Panic().Err(err).Msgf("Cannot load timezone %s", cli.Timezone)
} }
// Init // Init
logging.Configure(&flags, location) logging.Configure(&cli, location)
log.Info().Msgf("Starting Diun %s", version) log.Info().Msgf("Starting Diun %s", version)
// Handle os signals // Handle os signals
@@ -56,7 +59,7 @@ func main() {
}() }()
// Load and check configuration // Load and check configuration
cfg, err := config.Load(flags, version) cfg, err := config.Load(cli, version)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Cannot load configuration") log.Fatal().Err(err).Msg("Cannot load configuration")
} }

View File

@@ -16,20 +16,19 @@ After getting the binary, it can be tested with `./diun --help` or moved to a pe
``` ```
$ ./diun --help $ ./diun --help
usage: diun --config=CONFIG [<flags>] Usage: diun --config=STRING
Docker image update notifier. More info on https://github.com/crazy-max/diun Docker image update notifier. More info: https://github.com/crazy-max/diun
Flags: Flags:
--help Show context-sensitive help (also try --help-long and --help Show context-sensitive help.
--help-man). --version
--config=CONFIG Diun configuration file. --config=STRING Diun configuration file ($CONFIG).
--timezone="UTC" Timezone assigned to Diun. --timezone="UTC" Timezone assigned to Diun ($TZ).
--log-level="info" Set log level. --log-level="debug" Set log level ($LOG_LEVEL).
--log-json Enable JSON logging output. --log-json Enable JSON logging output ($LOG_JSON).
--log-caller Enable to add file:line of the caller. --log-caller Add file:line of the caller to log output
--docker Enable Docker mode. ($LOG_CALLER).
--version Show application version.
``` ```
## Server configuration ## Server configuration

View File

@@ -2,12 +2,12 @@
## Command line ## Command line
`diun --config=CONFIG [<flags>]` `diun --config=STRING`
* `--help`: Show help text and exit. * `--help`: Show help text and exit.
* `--version`: Show version and exit. * `--version`: Show version and exit.
* `--config <path>` : Diun YAML configuration file. **Required**. (example: `diun.yml`). * `--config <path>`: Diun YAML configuration file. **Required**. (e.g. `diun.yml`).
* `--timezone <timezone>` : Timezone assigned to Diun. (default: `UTC`). * `--timezone <timezone>`: Timezone assigned to Diun. (default `UTC`).
* `--log-level <level>` : Log level output. (default: `info`). * `--log-level <level>`: Log level output. (default `info`).
* `--log-json` : Enable JSON logging output. (default: `false`). * `--log-json`: Enable JSON logging output. (default `false`).
* `--log-caller` : Enable to add file:line of the caller. (default: `false`). * `--log-caller`: Add file:line of the caller to log output. (default `false`).

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/crazy-max/diun
go 1.13 go 1.13
require ( require (
github.com/alecthomas/kingpin v0.0.0-20190816080609-dce89ec0b9f1 github.com/alecthomas/kong v0.2.9
github.com/containers/image/v5 v5.4.0 github.com/containers/image/v5 v5.4.0
github.com/docker/docker v1.13.1 github.com/docker/docker v1.13.1
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0

6
go.sum
View File

@@ -28,11 +28,9 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/alecthomas/kingpin v0.0.0-20190816080609-dce89ec0b9f1 h1:mMQ7zXsR8Z+qu7xwkCkjv80btn4DMOnek8rX+STVDdo= github.com/alecthomas/kong v0.2.9 h1:WGuTS/N2/NQ/9LymVqpr1ifZ4EEkQPvwFHqZs6ak5IU=
github.com/alecthomas/kingpin v0.0.0-20190816080609-dce89ec0b9f1/go.mod h1:idxgS9pV6OOpAhZvx+gcoGRMX9/tt0iqkw/pNxI0C14= github.com/alecthomas/kong v0.2.9/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=

View File

@@ -18,7 +18,7 @@ import (
// Config holds configuration details // Config holds configuration details
type Config struct { type Config struct {
Flags model.Flags Cli model.Cli
App model.App App model.App
Db model.Db `yaml:"db,omitempty"` Db model.Db `yaml:"db,omitempty"`
Watch model.Watch `yaml:"watch,omitempty"` Watch model.Watch `yaml:"watch,omitempty"`
@@ -28,10 +28,10 @@ type Config struct {
} }
// Load returns Configuration struct // Load returns Configuration struct
func Load(flags model.Flags, version string) (*Config, error) { func Load(cli model.Cli, version string) (*Config, error) {
var err error var err error
var cfg = Config{ var cfg = Config{
Flags: flags, Cli: cli,
App: model.App{ App: model.App{
ID: "diun", ID: "diun",
Name: "Diun", Name: "Diun",
@@ -78,11 +78,11 @@ func Load(flags model.Flags, version string) (*Config, error) {
}, },
} }
if _, err = os.Lstat(flags.Cfgfile); err != nil { if _, err = os.Lstat(cli.Cfgfile); err != nil {
return nil, fmt.Errorf("unable to open config file, %s", err) return nil, fmt.Errorf("unable to open config file, %s", err)
} }
bytes, err := ioutil.ReadFile(flags.Cfgfile) bytes, err := ioutil.ReadFile(cli.Cfgfile)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to read config file, %s", err) return nil, fmt.Errorf("unable to read config file, %s", err)
} }

View File

@@ -11,29 +11,29 @@ import (
func TestLoad(t *testing.T) { func TestLoad(t *testing.T) {
cases := []struct { cases := []struct {
name string name string
flags model.Flags cli model.Cli
wantData *config.Config wantData *config.Config
wantErr bool wantErr bool
}{ }{
{ {
name: "Fail on non-existing file", name: "Fail on non-existing file",
flags: model.Flags{}, cli: model.Cli{},
wantErr: true, wantErr: true,
}, },
{ {
name: "Fail on wrong file format", name: "Fail on wrong file format",
flags: model.Flags{ cli: model.Cli{
Cfgfile: "config.invalid.yml", Cfgfile: "config.invalid.yml",
}, },
wantErr: true, wantErr: true,
}, },
{ {
name: "Success", name: "Success",
flags: model.Flags{ cli: model.Cli{
Cfgfile: "config.test.yml", Cfgfile: "config.test.yml",
}, },
wantData: &config.Config{ wantData: &config.Config{
Flags: model.Flags{ Cli: model.Cli{
Cfgfile: "config.test.yml", Cfgfile: "config.test.yml",
}, },
App: model.App{ App: model.App{
@@ -188,7 +188,7 @@ func TestLoad(t *testing.T) {
} }
for _, tt := range cases { for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
cfg, err := config.Load(tt.flags, "test") cfg, err := config.Load(tt.cli, "test")
assert.Equal(t, tt.wantData, cfg) assert.Equal(t, tt.wantData, cfg)
assert.Equal(t, tt.wantErr, err != nil) assert.Equal(t, tt.wantErr, err != nil)
}) })

View File

@@ -13,7 +13,7 @@ import (
) )
// Configure configures logger // Configure configures logger
func Configure(fl *model.Flags, location *time.Location) { func Configure(cli *model.Cli, location *time.Location) {
var err error var err error
var w io.Writer var w io.Writer
@@ -21,7 +21,7 @@ func Configure(fl *model.Flags, location *time.Location) {
return time.Now().In(location) return time.Now().In(location)
} }
if !fl.LogJSON { if !cli.LogJSON {
w = zerolog.ConsoleWriter{ w = zerolog.ConsoleWriter{
Out: os.Stdout, Out: os.Stdout,
TimeFormat: time.RFC1123, TimeFormat: time.RFC1123,
@@ -31,20 +31,20 @@ func Configure(fl *model.Flags, location *time.Location) {
} }
ctx := zerolog.New(w).With().Timestamp() ctx := zerolog.New(w).With().Timestamp()
if fl.LogCaller { if cli.LogCaller {
ctx = ctx.Caller() ctx = ctx.Caller()
} }
log.Logger = ctx.Logger() log.Logger = ctx.Logger()
logLevel, err := zerolog.ParseLevel(fl.LogLevel) logLevel, err := zerolog.ParseLevel(cli.LogLevel)
if err != nil { if err != nil {
log.Fatal().Err(err).Msgf("Unknown log level") log.Fatal().Err(err).Msgf("Unknown log level")
} else { } else {
zerolog.SetGlobalLevel(logLevel) zerolog.SetGlobalLevel(logLevel)
} }
logrusLevel, err := logrus.ParseLevel(fl.LogLevel) logrusLevel, err := logrus.ParseLevel(cli.LogLevel)
if err != nil { if err != nil {
log.Fatal().Err(err).Msgf("Unknown log level") log.Fatal().Err(err).Msgf("Unknown log level")
} else { } else {

13
internal/model/cli.go Normal file
View File

@@ -0,0 +1,13 @@
package model
import "github.com/alecthomas/kong"
// Cli holds command line args, flags and cmds
type Cli struct {
Version kong.VersionFlag
Cfgfile string `kong:"required,name='config',env='CONFIG',help='Diun configuration file.'"`
Timezone string `kong:"name='timezone',env='TZ',default='UTC',help='Timezone assigned to Diun.'"`
LogLevel string `kong:"name='log-level',env='LOG_LEVEL',default='debug',help='Set log level.'"`
LogJSON bool `kong:"name='log-json',env='LOG_JSON',default='false',help='Enable JSON logging output.'"`
LogCaller bool `kong:"name='log-caller',env='LOG_CALLER',default='false',help='Add file:line of the caller to log output.'"`
}

View File

@@ -1,10 +0,0 @@
package model
// Flags holds flags from command line
type Flags struct {
Cfgfile string
Timezone string
LogLevel string
LogJSON bool
LogCaller bool
}