Skip to content

Commit

Permalink
CLI: Body for parsing config from command-line args
Browse files Browse the repository at this point in the history
  • Loading branch information
joanlopez committed Sep 17, 2023
1 parent 1ee15bd commit 8e8750e
Show file tree
Hide file tree
Showing 11 changed files with 1,110 additions and 6 deletions.
19 changes: 13 additions & 6 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
run:
timeout: 2m
timeout: 5m

linters:
enable-all: true
disable:
# deprecations
- gomnd # deprecated (since v1.58.0) in favor of 'mnd'
- execinquery # deprecated (since v1.58.0) as it has been archived
# deprecations:
- gomnd # (since v1.58.0) in favor of 'mnd'
- execinquery # (since v1.58.0) as it has been archived
# we don't want that many whitespaces and white lines
- wsl
- nlreturn
# annoying linters that report many false positives
- depguard
- wrapcheck
# other
- depguard # not used (by default reports many false positives)
- wsl # we don't want that many whitespaces and white lines
- varnamelen # we want freedom for choosing variable names
- lll # we try (not force) to keep the lines at a reasonable length
- exhaustruct # why? isn't it against Go idiomatic zero-value behave?


linters-settings:
Expand Down
28 changes: 28 additions & 0 deletions cmd/gbounty/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
package bootstrap

import (
"os"

"github.com/bountysecurity/gbounty/internal/platform/cli"
)

func Run() error {
cfg, err := parseCLIArgs()
if err != nil || cfg.ShowHelp {
return err
}

return nil
}

func parseCLIArgs() (cli.Config, error) {
cliConfig, err := cli.Parse(os.Args)
if err != nil {
return cli.Config{}, err
}

if cliConfig.ShowHelp {
return cliConfig, nil
}

if err := cliConfig.Validate(); err != nil {
return cli.Config{}, err
}

return cliConfig, nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/bountysecurity/gbounty
go 1.22.5

require (
github.com/go-logfmt/logfmt v0.6.0
github.com/pterm/pterm v0.12.79
github.com/stretchr/testify v1.9.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
Expand Down
71 changes: 71 additions & 0 deletions internal/platform/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cli

import (
"flag"
"io"
"os"

"github.com/bountysecurity/gbounty/kit/getopt"
)

const (
Output = "output"
Debug = "debug"
)

func Parse(args []string) (Config, error) {
config := Config{}

fs := getopt.NewFlagSet(args[0], flag.ContinueOnError)
fs.SetOutput(io.Discard)

// No group
fs.BoolVar("", &config.ShowHelp, "help", false, "Show help")
fs.Alias("h", "help")

// Output
fs.InitGroup(Output, "OUTPUT OPTIONS:")
fs.StringVar(Output, &config.OutPath, "output", "", "Determines the path where the output file will be stored to\n\tBy default, the output file is formatted as plain text")
fs.Alias("o", "output")
json := fs.Bool(Output, "json", false, "If specified, the output file will be JSON-formatted\n\tBy default, the output file is formatted as plain text")
fs.Alias("j", "json")
markdown := fs.Bool(Output, "markdown", false, "If specified, the output file will be Markdown-formatted\n\tBy default, the output file is formatted as plain text")
fs.Alias("md", "markdown")

// Debug
fs.InitGroup(Debug, "DEBUG OPTIONS:")
fs.BoolVar(Debug, &config.Verbosity.Warn, "verbose", false, "If specified, the internal logger will write warning and error log messages")
fs.Alias("v", "verbose")
fs.BoolVar(Debug, &config.Verbosity.Info, "verbose-extra", false, "If specified, the internal logger will write info, warning and error log messages")
fs.Alias("vv", "verbose-extra")
fs.BoolVar(Debug, &config.Verbosity.Debug, "verbose-all", false, "If specified, the internal logger will write debug, info, warning and error log messages")
fs.Alias("vvv", "verbose-all")
fs.StringVar(Debug, &config.Verbosity.Output, "verbose-output", "", "If specified, the internal logger will write the log messages to a file")
fs.Alias("vout", "verbose-output")

fs.SetUsage(`
Usage:
gbounty [flags]
Flags:`)

if err := fs.Parse(os.Args[1:]); err != nil {
return Config{}, err
}

if config.ShowHelp {
fs.SetOutput(os.Stdout)
fs.PrintDefaults()
}

switch {
case *json:
config.OutFormat = "json"
case *markdown:
config.OutFormat = "markdown"
default:
config.OutFormat = "plain"
}

return config, nil
}
58 changes: 58 additions & 0 deletions internal/platform/cli/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package cli

import (
"net/http"

"github.com/bountysecurity/gbounty/kit/logger"
)

const (
defaultParamsSplit = 10
defaultParamsMethod = http.MethodGet
defaultParamsEncode = "url"
)

type Verbosity struct {
Debug bool
Info bool
Warn bool
Output string
}

func (v Verbosity) Level() logger.Level {
switch {
case v.Debug:
return logger.LevelDebug
case v.Info:
return logger.LevelInfo
case v.Warn:
return logger.LevelWarn
}

return logger.LevelDisabled
}

type Config struct {
// ShowHelp determines whether
// the help flag has been provided.
ShowHelp bool
// OutPath specifies the path where
// the scan output will be written to.
OutPath string
// OutFormat specifies the format
// the scan output will be written.
OutFormat string
// Verbosity determines the level of
// verbosity for the internal logger.
Verbosity Verbosity
}

func (cfg Config) Validate() error {
for _, validation := range []func() error{} {
if err := validation(); err != nil {
return err
}
}

return nil
}
Loading

0 comments on commit 8e8750e

Please sign in to comment.