diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2e94e051..8fe25746 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,6 +45,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: ‘2’ - name: Setup Go uses: actions/setup-go@v2 diff --git a/README.md b/README.md index db483e7e..ed774d7f 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Usage: woke [globs ...] [flags] Flags: - -c, --config string YAML file with list of rules + -c, --config string Config file (default is .woke.yaml in current directory, or $HOME) --debug Enable debug logging --exit-1-on-failure Exit with exit code 1 on failures -h, --help help for woke @@ -186,8 +186,12 @@ This has whitelist from stdin A set of default rules is provided in [`pkg/rule/default.go`](https://github.com/get-woke/woke/blob/main/pkg/rule/default.go). -Configure your custom rules config in `.woke.yaml` or `.woke.yml`, `woke` will pick up one of these files in the cwd of where you run `woke` from. -This file will be picked up automatically up your customizations automatically! +Configure your custom rules config in `.woke.yaml` or `.woke.yml`. `woke` uses the following precedence order. Each item takes precedence over the item below it: + +- `current working directory` +- `$HOME` + +This file will be picked up automatically up your customizations without needing to supply it with the `-c` flag. See [example.yaml](https://github.com/get-woke/woke/blob/main/example.yaml) for an example of adding custom rules. You can also supply your own rules with `-c path/to/rules.yaml` if you want to handle different rulesets. diff --git a/cmd/root.go b/cmd/root.go index ca7f0458..1b7ee4fc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -35,15 +35,17 @@ import ( "github.com/get-woke/woke/pkg/parser" "github.com/get-woke/woke/pkg/printer" + "github.com/mitchellh/go-homedir" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/spf13/viper" ) var ( // flags exitOneOnFailure bool - ruleConfig string + cfgFile string debug bool stdin bool outputName string @@ -72,7 +74,7 @@ Provide a list file globs for files you'd like to check.`, } func rootRunE(cmd *cobra.Command, args []string) error { - setLogLevel() + setDebugLogLevel() runtime.GOMAXPROCS(runtime.NumCPU()) log.Debug().Msg(getVersion("default")) @@ -84,11 +86,7 @@ func rootRunE(cmd *cobra.Command, args []string) error { Msg("woke completed") }() - if len(args) == 0 { - args = parser.DefaultPath - } - - cfg, err := config.NewConfig(ruleConfig) + cfg, err := config.NewConfig(viper.ConfigFileUsed()) if err != nil { return err } @@ -100,16 +98,12 @@ func rootRunE(cmd *cobra.Command, args []string) error { p := parser.NewParser(cfg.Rules, ignorer) - if stdin { - args = []string{os.Stdin.Name()} - } - print, err := printer.NewPrinter(outputName) if err != nil { return err } - violations := p.ParsePaths(print, args...) + violations := p.ParsePaths(print, parseArgs(args)...) if exitOneOnFailure && violations > 0 { // We intentionally return an error if exitOneOnFailure is true, but don't want to show usage @@ -131,9 +125,10 @@ func Execute() error { } func init() { + cobra.OnInitialize(initConfig) rootCmd.Version = getVersion("short") - rootCmd.PersistentFlags().StringVarP(&ruleConfig, "config", "c", "", "YAML file with list of rules") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file (default is .woke.yaml in current directory, or $HOME)") rootCmd.PersistentFlags().BoolVar(&exitOneOnFailure, "exit-1-on-failure", false, "Exit with exit code 1 on failures") rootCmd.PersistentFlags().BoolVar(&stdin, "stdin", false, "Read from stdin") rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Enable debug logging") @@ -141,9 +136,19 @@ func init() { rootCmd.PersistentFlags().StringVarP(&outputName, "output", "o", printer.OutFormatText, fmt.Sprintf("Output type [%s]", printer.OutFormatsString)) } -func setLogLevel() { - // Default level for this example is info, unless debug flag is present - zerolog.SetGlobalLevel(zerolog.InfoLevel) +func parseArgs(args []string) []string { + if len(args) == 0 { + args = parser.DefaultPath + } + + if stdin { + args = []string{os.Stdin.Name()} + } + + return args +} + +func setDebugLogLevel() { if debug { zerolog.SetGlobalLevel(zerolog.DebugLevel) } @@ -157,3 +162,28 @@ func getVersion(t string) string { return fmt.Sprintf("woke version %s built from %s on %s", Version, Commit, Date) } } + +func initConfig() { + // Require yaml for now, since the unmarshaling of the config only + // supports yaml. The config loading will need to be refactored to + // support viper unmarshaling. + viper.SetConfigType("yaml") + + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Search config in working directory, then home directory with name ".woke.[yml|yaml]" + viper.SetConfigName(".woke") + viper.AddConfigPath(".") + + // Find home directory. + if home, err := homedir.Dir(); err == nil { + viper.AddConfigPath(home) + } + } + + if err := viper.ReadInConfig(); err == nil { + log.Debug().Msgf("Using config file: %s", viper.ConfigFileUsed()) + } +} diff --git a/cmd/root_test.go b/cmd/root_test.go index e85750a2..50874506 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -2,10 +2,12 @@ package cmd import ( "bytes" + "os" "regexp" "testing" "github.com/get-woke/woke/pkg/output" + "github.com/get-woke/woke/pkg/parser" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" @@ -23,6 +25,35 @@ func BenchmarkExecute(b *testing.B) { } } +func TestInitConfig(t *testing.T) { + t.Cleanup(func() { + cfgFile = "" + debug = false + }) + debug = true + t.Run("good config", func(t *testing.T) { + cfgFile = "../testdata/good.yml" + initConfig() + }) + + t.Run("no config", func(t *testing.T) { + cfgFile = "" + initConfig() + }) +} + +func TestParseArgs(t *testing.T) { + t.Cleanup(func() { + stdin = false + }) + assert.Equal(t, parser.DefaultPath, parseArgs([]string{})) + assert.Equal(t, []string{"../.."}, parseArgs([]string{"../.."})) + + stdin = true + assert.Equal(t, []string{os.Stdin.Name()}, parseArgs([]string{})) + assert.Equal(t, []string{os.Stdin.Name()}, parseArgs([]string{"../.."})) +} + func TestRunE(t *testing.T) { origStdout := output.Stdout t.Cleanup(func() { diff --git a/go.mod b/go.mod index dfe85ee3..207ea0cc 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,16 @@ module github.com/get-woke/woke -go 1.14 +go 1.15 require ( github.com/fatih/color v1.10.0 github.com/get-woke/fastwalk v1.0.0 github.com/get-woke/go-gitignore v1.1.1 github.com/mattn/go-colorable v0.1.8 + github.com/mitchellh/go-homedir v1.1.0 github.com/rs/zerolog v1.20.0 github.com/spf13/cobra v1.1.1 + github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 9946335d..3d82b93e 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,7 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -39,6 +40,7 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/get-woke/fastwalk v1.0.0 h1:Ti8z9nf231TUhLzBuJQV/rh/b5qiuyPunYun4FpEshQ= github.com/get-woke/fastwalk v1.0.0/go.mod h1:WTDsePalrkZGMzdzn5YabupFqFmU/MjxGM2CSSc9sOo= @@ -70,6 +72,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -90,6 +93,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -100,6 +104,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -111,6 +116,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= @@ -122,17 +128,20 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -158,28 +167,34 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -252,6 +267,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepx golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -269,7 +285,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74 h1:4cFkmztxtMslUX2SctSl+blCyXfpzhGOy9LhKAqSMA4= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -302,6 +317,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/main.go b/main.go index bd7440fa..b7cd2a08 100644 --- a/main.go +++ b/main.go @@ -33,6 +33,7 @@ import ( func main() { log.Logger = log.Output(zerolog.ConsoleWriter{Out: colorable.NewColorableStdout(), TimeFormat: time.RFC3339}) + zerolog.SetGlobalLevel(zerolog.InfoLevel) err := cmd.Execute() if err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index 4b0a12da..19175af9 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -3,6 +3,7 @@ package config import ( "io/ioutil" "os" + "path/filepath" "github.com/get-woke/woke/pkg/rule" @@ -11,8 +12,6 @@ import ( "gopkg.in/yaml.v2" ) -var defaultConfigFilenames = []string{".woke.yaml", ".woke.yml"} - // Config contains a list of rules type Config struct { Rules []*rule.Rule `yaml:"rules"` @@ -22,17 +21,17 @@ type Config struct { // NewConfig returns a new Config func NewConfig(filename string) (*Config, error) { var c Config - - if filename != "" { - if err := c.load(filename); err != nil { + if len(filename) > 0 { + var err error + c, err = loadConfig(filename) + if err != nil { return nil, err } - // Ignore the config filename, it will always match on its own rules - c.IgnoreFiles = append(c.IgnoreFiles, filename) - } else if defaultCfg := loadDefaultConfigFiles(); defaultCfg != nil { - c = *defaultCfg - c.IgnoreFiles = append(c.IgnoreFiles, defaultConfigFilenames...) + log.Debug().Str("config", filename).Msg("loaded config file") + + // Ignore the config filename, it will always match on its own rules + c.IgnoreFiles = append(c.IgnoreFiles, relative(filename)) } c.ConfigureRules() @@ -71,38 +70,23 @@ func (c *Config) ConfigureRules() { } } -func (c *Config) load(filename string) error { - cfg, err := loadConfig(filename) - if err != nil { - return err - } - *c = *cfg - return nil -} - -func loadConfig(filename string) (*Config, error) { +func loadConfig(filename string) (c Config, err error) { yamlFile, err := ioutil.ReadFile(filename) if err != nil { - return nil, err + return c, err } - var c Config - err = yaml.Unmarshal(yamlFile, &c) - return &c, err + return c, yaml.Unmarshal(yamlFile, &c) } -func loadDefaultConfigFiles() (cfg *Config) { - for _, file := range defaultConfigFilenames { - if _, err := os.Stat(file); os.IsNotExist(err) { - log.Debug().Str("cfg", file).Err(err).Msg("tried default config file") - continue - } - var err error - cfg, err = loadConfig(file) - if err == nil && cfg != nil { - log.Debug().Str("cfg", file).Msg("found default config file!") - return +func relative(filename string) string { + // viper provides an absolute path to the config file, but we want the relative + // path to the config file from the current directory to make it easy for woke to ignore it + if filepath.IsAbs(filename) { + cwd, _ := os.Getwd() + if relfilename, err := filepath.Rel(cwd, filename); err == nil { + return relfilename } } - return + return filename } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 03b61539..2044b923 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -3,6 +3,8 @@ package config import ( "bytes" "fmt" + "os" + "path/filepath" "strings" "testing" @@ -27,7 +29,7 @@ func TestNewConfig(t *testing.T) { } assert.Equal(t, - fmt.Sprintf(`{"level":"debug","rules":[%s],"message":"rules enabled"}`, strings.Join(enabledRules, ","))+"\n", + fmt.Sprintf(`{"level":"debug","config":"testdata/good.yaml","message":"loaded config file"}`+"\n"+`{"level":"debug","rules":[%s],"message":"rules enabled"}`, strings.Join(enabledRules, ","))+"\n", out.String()) }) @@ -74,11 +76,6 @@ func TestNewConfig(t *testing.T) { IgnoreFiles: []string(nil), } assert.Equal(t, expectedEmpty, c) - - defaultConfigFilenames = []string{"testdata/default.yaml"} - c, err = NewConfig("") - assert.NoError(t, err) - assert.EqualValues(t, defaultConfigFilenames, c.IgnoreFiles) }) t.Run("config-missing", func(t *testing.T) { @@ -88,3 +85,12 @@ func TestNewConfig(t *testing.T) { assert.Nil(t, c) }) } + +func Test_relative(t *testing.T) { + cwd, err := os.Getwd() + assert.NoError(t, err) + + assert.Equal(t, ".woke.yml", relative(filepath.Join(cwd, ".woke.yml"))) + assert.Equal(t, ".woke.yml", relative(".woke.yml")) + assert.Equal(t, "dir/.woke.yml", relative("dir/.woke.yml")) +}