From 7ac8106f8a113da3640401db3736fe747ea27482 Mon Sep 17 00:00:00 2001 From: Nish Krishnan Date: Tue, 6 Apr 2021 12:02:25 -0700 Subject: [PATCH] Add structured logger (#54) (#1467) This is two changes: Replacing all usages of SimpleLogger with it's interface SimpleLogging which makes it easier to swap out loggers going forward Nukes SimpleLogger in favor of StructuredLogger which allows us to better analyze logs in our log management system we choose. --- cmd/server.go | 2 +- cmd/server_test.go | 69 ++-- go.mod | 25 +- go.sum | 145 ++++++-- main.go | 10 +- server/events/apply_command_runner_test.go | 3 +- server/events/command_context.go | 2 +- server/events/command_runner.go | 12 +- server/events/command_runner_test.go | 24 +- server/events/delete_lock_command.go | 2 +- server/events/delete_lock_command_test.go | 14 +- server/events/git_cred_writer.go | 2 +- server/events/git_cred_writer_test.go | 2 +- server/events/github_app_working_dir.go | 2 +- server/events/github_app_working_dir_test.go | 11 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/events/mock_workingdir_test.go | 12 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/events/mocks/mock_project_lock.go | 12 +- server/events/mocks/mock_webhooks_sender.go | 12 +- server/events/mocks/mock_working_dir.go | 12 +- server/events/models/models.go | 2 +- .../pre_workflow_hooks_command_runner_test.go | 2 +- .../project_command_builder_internal_test.go | 31 +- server/events/project_command_builder_test.go | 44 ++- server/events/project_command_runner.go | 2 +- server/events/project_command_runner_test.go | 6 +- server/events/project_finder.go | 8 +- server/events/project_finder_test.go | 4 +- server/events/project_locker.go | 4 +- server/events/project_locker_test.go | 6 +- server/events/pull_updater.go | 2 +- .../events/runtime/apply_step_runner_test.go | 23 +- server/events/runtime/env_step_runner_test.go | 2 +- server/events/runtime/executor.go | 2 +- .../events/runtime/init_step_runner_test.go | 15 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- .../mocks/mock_versionedexecutorworkflow.go | 12 +- .../events/runtime/plan_step_runner_test.go | 30 +- .../events/runtime/policy/conftest_client.go | 4 +- .../runtime/policy/conftest_client_test.go | 4 +- .../runtime/policy_check_step_runner_test.go | 2 +- .../runtime/pre_workflow_hook_runner_test.go | 2 +- server/events/runtime/run_step_runner_test.go | 2 +- server/events/runtime/runtime.go | 6 +- .../events/runtime/show_step_runner_test.go | 2 +- .../matchers/ptr_to_logging_simplelogger.go | 12 +- .../terraform/mocks/mock_terraform_client.go | 24 +- server/events/terraform/terraform_client.go | 16 +- .../terraform_client_internal_test.go | 17 +- .../events/terraform/terraform_client_test.go | 42 ++- server/events/vcs/github_client.go | 4 +- .../events/vcs/github_client_internal_test.go | 5 +- server/events/vcs/github_client_test.go | 26 +- server/events/vcs/github_credentials_test.go | 7 +- server/events/vcs/gitlab_client.go | 2 +- server/events/vcs/gitlab_client_test.go | 4 +- .../matchers/ptr_to_logging_simplelogger.go | 18 +- server/events/webhooks/mocks/mock_sender.go | 12 +- server/events/webhooks/slack.go | 2 +- server/events/webhooks/slack_test.go | 4 +- server/events/webhooks/webhooks.go | 4 +- server/events/webhooks/webhooks_test.go | 4 +- server/events/working_dir.go | 8 +- server/events/working_dir_test.go | 23 +- server/events/yaml/valid/global_cfg_test.go | 4 +- server/events_controller.go | 2 +- server/events_controller_e2e_test.go | 11 +- server/events_controller_test.go | 13 +- server/github_app_controller.go | 2 +- server/locks_controller.go | 2 +- server/locks_controller_test.go | 34 +- server/logging/logging_test.go | 20 +- .../mocks/matchers/logging_loglevel.go | 15 +- .../mocks/matchers/logging_simplelogging.go | 33 ++ .../matchers/ptr_to_logging_simplelogger.go | 12 +- server/logging/mocks/mock_simple_logging.go | 200 +++++++---- server/logging/simple_logger.go | 340 +++++++++--------- server/middleware.go | 4 +- server/server.go | 11 +- server/server_test.go | 2 + server/status_controller.go | 2 +- server/status_controller_test.go | 6 +- 83 files changed, 931 insertions(+), 642 deletions(-) create mode 100644 server/logging/mocks/matchers/logging_simplelogging.go diff --git a/cmd/server.go b/cmd/server.go index 0220e2247..23a91abd6 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -406,7 +406,7 @@ type ServerCmd struct { // Useful for testing to keep the logs clean. SilenceOutput bool AtlantisVersion string - Logger *logging.SimpleLogger + Logger logging.SimpleLogging } // ServerCreator creates servers. diff --git a/cmd/server_test.go b/cmd/server_test.go index c98c5c0bd..f80b32513 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -24,6 +24,7 @@ import ( homedir "github.com/mitchellh/go-homedir" "github.com/runatlantis/atlantis/server" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -111,7 +112,7 @@ func TestExecute_Defaults(t *testing.T) { GHUserFlag: "user", GHTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -155,7 +156,7 @@ func TestExecute_Defaults(t *testing.T) { func TestExecute_Flags(t *testing.T) { t.Log("Should use all flags that are set.") - c := setup(testFlags) + c := setup(testFlags, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -173,7 +174,7 @@ func TestExecute_ConfigFile(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setup(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -188,7 +189,7 @@ func TestExecute_EnvironmentVariables(t *testing.T) { os.Setenv(envKey, fmt.Sprintf("%v", value)) // nolint: errcheck defer func(key string) { os.Unsetenv(key) }(envKey) } - c := setup(nil) + c := setup(nil, t) err := c.Execute() Ok(t, err) for flag, exp := range testFlags { @@ -200,7 +201,7 @@ func TestExecute_NoConfigFlag(t *testing.T) { t.Log("If there is no config flag specified Execute should return nil.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "", - }) + }, t) err := c.Execute() Ok(t, err) } @@ -209,7 +210,7 @@ func TestExecute_ConfigFileExtension(t *testing.T) { t.Log("If the config file doesn't have an extension then error.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "does-not-exist", - }) + }, t) err := c.Execute() Equals(t, "invalid config: reading does-not-exist: Unsupported Config Type \"\"", err.Error()) } @@ -218,7 +219,7 @@ func TestExecute_ConfigFileMissing(t *testing.T) { t.Log("If the config file doesn't exist then error.") c := setupWithDefaults(map[string]interface{}{ ConfigFlag: "does-not-exist.yaml", - }) + }, t) err := c.Execute() Equals(t, "invalid config: reading does-not-exist.yaml: open does-not-exist.yaml: no such file or directory", err.Error()) } @@ -229,7 +230,7 @@ func TestExecute_ConfigFileExists(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setupWithDefaults(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Ok(t, err) } @@ -240,7 +241,7 @@ func TestExecute_InvalidConfig(t *testing.T) { defer os.Remove(tmpFile) // nolint: errcheck c := setupWithDefaults(map[string]interface{}{ ConfigFlag: tmpFile, - }) + }, t) err := c.Execute() Assert(t, strings.Contains(err.Error(), "unmarshal errors"), "should be an unmarshal error") } @@ -251,7 +252,7 @@ func TestExecute_RepoAllowlistScheme(t *testing.T) { GHUserFlag: "user", GHTokenFlag: "token", RepoAllowlistFlag: "http://github.com/*", - }) + }, t) err := c.Execute() Assert(t, err != nil, "should be an error") Equals(t, "--repo-allowlist cannot contain ://, should be hostnames only", err.Error()) @@ -280,7 +281,7 @@ func TestExecute_ValidateLogLevel(t *testing.T) { } for _, testCase := range cases { t.Log("Should validate log level when " + testCase.description) - c := setupWithDefaults(testCase.flags) + c := setupWithDefaults(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -293,7 +294,7 @@ func TestExecute_ValidateLogLevel(t *testing.T) { func TestExecute_ValidateCheckoutStrategy(t *testing.T) { c := setupWithDefaults(map[string]interface{}{ CheckoutStrategyFlag: "invalid", - }) + }, t) err := c.Execute() ErrEquals(t, "invalid checkout strategy: not one of branch or merge", err) } @@ -335,7 +336,7 @@ func TestExecute_ValidateSSLConfig(t *testing.T) { } for _, testCase := range cases { t.Log("Should validate ssl config when " + testCase.description) - c := setupWithDefaults(testCase.flags) + c := setupWithDefaults(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -511,7 +512,7 @@ func TestExecute_ValidateVCSConfig(t *testing.T) { t.Log("Should validate vcs config when " + testCase.description) testCase.flags[RepoAllowlistFlag] = "*" - c := setup(testCase.flags) + c := setup(testCase.flags, t) err := c.Execute() if testCase.expectError { Assert(t, err != nil, "should be an error") @@ -529,7 +530,7 @@ func TestExecute_ExpandHomeInDataDir(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "*", DataDirFlag: "~/this/is/a/path", - }) + }, t) err := c.Execute() Ok(t, err) @@ -542,7 +543,7 @@ func TestExecute_RelativeDataDir(t *testing.T) { t.Log("Should convert relative dir to absolute.") c := setupWithDefaults(map[string]interface{}{ DataDirFlag: "../", - }) + }, t) // Figure out what ../ should be as an absolute path. expectedAbsolutePath, err := filepath.Abs("../") @@ -559,7 +560,7 @@ func TestExecute_GithubUser(t *testing.T) { GHUserFlag: "@user", GHTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -572,7 +573,7 @@ func TestExecute_GithubApp(t *testing.T) { GHAppKeyFileFlag: "key.pem", GHAppIDFlag: "1", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -585,7 +586,7 @@ func TestExecute_GitlabUser(t *testing.T) { GitlabUserFlag: "@user", GitlabTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -598,7 +599,7 @@ func TestExecute_BitbucketUser(t *testing.T) { BitbucketUserFlag: "@user", BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -611,7 +612,7 @@ func TestExecute_ADUser(t *testing.T) { ADUserFlag: "@user", ADTokenFlag: "token", RepoAllowlistFlag: "*", - }) + }, t) err := c.Execute() Ok(t, err) @@ -625,7 +626,7 @@ func TestExecute_BitbucketCloudWithWebhookSecret(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketWebhookSecretFlag: "my secret", - }) + }, t) err := c.Execute() ErrEquals(t, "--bitbucket-webhook-secret cannot be specified for Bitbucket Cloud because it is not supported by Bitbucket", err) } @@ -637,7 +638,7 @@ func TestExecute_BitbucketServerBaseURLScheme(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "mydomain.com", - }) + }, t) ErrEquals(t, "--bitbucket-base-url must have http:// or https://, got \"mydomain.com\"", c.Execute()) c = setup(map[string]interface{}{ @@ -645,7 +646,7 @@ func TestExecute_BitbucketServerBaseURLScheme(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "://mydomain.com", - }) + }, t) ErrEquals(t, "error parsing --bitbucket-webhook-secret flag value \"://mydomain.com\": parse \"://mydomain.com\": missing protocol scheme", c.Execute()) } @@ -656,7 +657,7 @@ func TestExecute_BitbucketServerBaseURLPort(t *testing.T) { BitbucketTokenFlag: "token", RepoAllowlistFlag: "*", BitbucketBaseURLFlag: "http://mydomain.com:7990", - }) + }, t) Ok(t, c.Execute()) Equals(t, "http://mydomain.com:7990", passedConfig.BitbucketBaseURL) } @@ -669,7 +670,7 @@ func TestExecute_RepoCfgFlags(t *testing.T) { RepoAllowlistFlag: "github.com", RepoConfigFlag: "repos.yaml", RepoConfigJSONFlag: "{}", - }) + }, t) err := c.Execute() ErrEquals(t, "cannot use --repo-config and --repo-config-json at the same time", err) } @@ -681,7 +682,7 @@ func TestExecute_TFEHostnameOnly(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "github.com", TFEHostnameFlag: "not-app.terraform.io", - }) + }, t) err := c.Execute() ErrEquals(t, "if setting --tfe-hostname, must set --tfe-token", err) } @@ -693,7 +694,7 @@ func TestExecute_BothAllowAndWhitelist(t *testing.T) { GHTokenFlag: "token", RepoAllowlistFlag: "github.com", RepoWhitelistFlag: "github.com", - }) + }, t) err := c.Execute() ErrEquals(t, "both --repo-allowlist and --repo-whitelist cannot be set–use --repo-allowlist", err) } @@ -703,7 +704,7 @@ func TestExecute_AllowAndWhitelist(t *testing.T) { c := setup(map[string]interface{}{ GHUserFlag: "user", GHTokenFlag: "token", - }) + }, t) err := c.Execute() ErrEquals(t, "--repo-allowlist must be set for security purposes", err) } @@ -716,7 +717,7 @@ func TestExecute_BothSilenceAllowAndWhitelistErrors(t *testing.T) { RepoAllowlistFlag: "*", SilenceWhitelistErrorsFlag: true, SilenceAllowlistErrorsFlag: true, - }) + }, t) err := c.Execute() ErrEquals(t, "both --silence-allowlist-errors and --silence-whitelist-errors cannot be set–use --silence-allowlist-errors", err) } @@ -729,14 +730,14 @@ func TestExecute_RepoWhitelistDeprecation(t *testing.T) { GHTokenFlag: "token", RepoWhitelistFlag: "*", SilenceWhitelistErrorsFlag: true, - }) + }, t) err := c.Execute() Ok(t, err) Equals(t, true, passedConfig.SilenceAllowlistErrors) Equals(t, "*", passedConfig.RepoAllowlist) } -func setup(flags map[string]interface{}) *cobra.Command { +func setup(flags map[string]interface{}, t *testing.T) *cobra.Command { vipr := viper.New() for k, v := range flags { vipr.Set(k, v) @@ -745,11 +746,12 @@ func setup(flags map[string]interface{}) *cobra.Command { ServerCreator: &ServerCreatorMock{}, Viper: vipr, SilenceOutput: true, + Logger: logging.NewNoopLogger(t), } return c.Init() } -func setupWithDefaults(flags map[string]interface{}) *cobra.Command { +func setupWithDefaults(flags map[string]interface{}, t *testing.T) *cobra.Command { vipr := viper.New() flags[GHUserFlag] = "user" flags[GHTokenFlag] = "token" @@ -762,6 +764,7 @@ func setupWithDefaults(flags map[string]interface{}) *cobra.Command { ServerCreator: &ServerCreatorMock{}, Viper: vipr, SilenceOutput: true, + Logger: logging.NewNoopLogger(t), } return c.Init() } diff --git a/go.mod b/go.mod index 68fd6edee..22af4dd0b 100644 --- a/go.mod +++ b/go.mod @@ -2,59 +2,70 @@ module github.com/runatlantis/atlantis go 1.16 +replace google.golang.org/grpc => google.golang.org/grpc v1.29.1 + require ( github.com/Laisky/graphql v1.0.5 github.com/Masterminds/sprig/v3 v3.2.2 github.com/agext/levenshtein v1.2.3 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect - github.com/aws/aws-sdk-go v1.17.14 // indirect + github.com/aws/aws-sdk-go v1.31.15 // indirect github.com/bradleyfalzon/ghinstallation v1.1.1 github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5 - github.com/davecgh/go-spew v1.1.1 + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/docker/docker v0.0.0-20180620051407-e2593239d949 github.com/elazarl/go-bindata-assetfs v1.0.1 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 + github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52 // indirect github.com/go-ozzo/ozzo-validation v0.0.0-20170913164239-85dcd8368eba github.com/go-playground/locales v0.12.1 // indirect github.com/go-playground/universal-translator v0.16.0 // indirect github.com/go-test/deep v1.0.7 github.com/google/go-cmp v0.5.2 // indirect github.com/google/go-github/v31 v31.0.0 + github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f // indirect github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-getter v1.5.2 github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/hcl/v2 v2.6.0 // indirect github.com/hashicorp/terraform-config-inspect v0.0.0-20200806211835-c481b8bfa41e github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5 // indirect + github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect + github.com/lyft/gostats v0.4.5 github.com/mcdafydd/go-azuredevops v0.12.0 github.com/microcosm-cc/bluemonday v1.0.5 github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 github.com/mitchellh/go-homedir v1.1.0 github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb github.com/nlopes/slack v0.4.0 - github.com/onsi/ginkgo v1.9.0 // indirect - github.com/onsi/gomega v1.4.3 // indirect github.com/petergtz/pegomock v2.9.0+incompatible github.com/pkg/errors v0.9.1 github.com/remeh/sizedwaitgroup v1.0.0 github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0 github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect + github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f // indirect github.com/spf13/cobra v0.0.0-20170905172051-b78744579491 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.1 + github.com/stretchr/testify v1.6.1 github.com/urfave/cli v1.22.5 github.com/urfave/negroni v0.3.0 github.com/xanzy/go-gitlab v0.47.0 github.com/zclconf/go-cty v1.5.1 // indirect go.etcd.io/bbolt v1.3.5 - golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 - golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect + go.opencensus.io v0.22.3 // indirect + go.uber.org/zap v1.15.0 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20191122200657-5d9234df094c // indirect - golang.org/x/text v0.3.3 // indirect + golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 // indirect google.golang.org/appengine v1.6.5 // indirect + google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31 // indirect + google.golang.org/grpc v1.30.0 // indirect + google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/go-playground/validator.v9 v9.31.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 4008e09c1..a497d0b68 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= @@ -45,8 +44,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= -github.com/aws/aws-sdk-go v1.17.14 h1:IjqZDIQoLyZ48A93BxVrZOaIGgZPRi4nXt6WQUMJplY= -github.com/aws/aws-sdk-go v1.17.14/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.31.15 h1:1Ahi6nvJLg5cjO5i3U7BWh91/zOw//tqOTLpLnIeyss= +github.com/aws/aws-sdk-go v1.31.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -59,11 +58,12 @@ github.com/bradleyfalzon/ghinstallation v1.1.1 h1:pmBXkxgM1WeF8QYvDLT5kuQiHMcmf+ github.com/bradleyfalzon/ghinstallation v1.1.1/go.mod h1:vyCmHTciHx/uuyN82Zc3rXN3X2KTK8nUTCrTMwAhcug= github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5 h1:osZyZB7J4kE1tKLeaUjV6+uZVBfS835T0I/RxmwWw1w= github.com/briandowns/spinner v0.0.0-20170614154858-48dbb65d7bd5/go.mod h1:hw/JEQBIE+c/BLI4aKM8UU8v+ZqrD3h7HC27kKt8JQU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -74,6 +74,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -81,12 +83,17 @@ github.com/docker/docker v0.0.0-20180620051407-e2593239d949 h1:La/qO5ApRpiO4c0wG github.com/docker/docker v0.0.0-20180620051407-e2593239d949/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw= github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI= github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= 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/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52 h1:0NmERxogGTU8hgzOhRKNoKivtBZkDW29GeuJtK9e0sc= +github.com/fsnotify/fsnotify v1.4.10-0.20200417215612-7f4cf4dd2b52/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -98,28 +105,41 @@ github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotf github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts= @@ -133,8 +153,9 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f h1:qa1wFcvZzVLbFVPdsdTsWL6k5IP6BEmFmd9SeahRQ5s= +github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -177,7 +198,6 @@ github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pB github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -200,8 +220,9 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5 h1:1G6l+WClVmbflmgW0Wsr6a50KeKCQcYKv/vUjtQUHuw= +github.com/jmespath/go-jmespath v0.3.1-0.20200310193758-2437e8417af5/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= 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 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= @@ -209,11 +230,13 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 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/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5 h1:TW7YQVw105jR4B+n/tAlkKNbYFSdWRK1RyLL5YYruso= +github.com/kelseyhightower/envconfig v1.4.1-0.20200624135755-c974cae29cf5/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -228,6 +251,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= +github.com/lyft/gostats v0.4.5 h1:2KYdjsz+RfxeJAWqOpYUlyXgFgYd0SxPFUSFm9PdXM4= +github.com/lyft/gostats v0.4.5/go.mod h1:7ECvCenOq0N9BE6Tn+dtwFoS6xAwbvsx4tVSETO/hmc= 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 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= @@ -269,12 +294,16 @@ github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwd github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nlopes/slack v0.4.0 h1:OVnHm7lv5gGT5gkcHsZAyw++oHVFihbjWbL3UceUpiA= github.com/nlopes/slack v0.4.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.9.0 h1:SZjF721BByVj8QH636/8S2DnX4n0Re3SteMmw3N+tzc= -github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= @@ -292,6 +321,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -315,8 +345,10 @@ github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXk github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f h1:qqqIhBDFUBrbMezIyJkKWIpf+E5CdObleGMjW1s19Hg= +github.com/sirupsen/logrus v1.6.1-0.20200528085638-6699a89a232f/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 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= @@ -343,8 +375,9 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ 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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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/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= @@ -358,6 +391,7 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac github.com/xanzy/go-gitlab v0.47.0 h1:nC35CNaGr9skHkJq1HMYZ58R7gZsy7SO37SkA2RIHbM= github.com/xanzy/go-gitlab v0.47.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.5.1 h1:oALUZX+aJeEBUe2a1+uD2+UTaYfEjnKFDEMRydkGvWE= @@ -366,20 +400,32 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -388,7 +434,6 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -400,9 +445,10 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -417,8 +463,10 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -430,10 +478,10 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -447,8 +495,15 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -460,7 +515,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -468,17 +522,24 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 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-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6 h1:rbvTkL9AkFts1cgI78+gG6Yu1pwaqX6hjSJAatB78E4= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -500,12 +561,24 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31 h1:Of4QP8bfRqzDROen6+s2j/p0jCPgzvQRd9nHiactfn4= +google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860 h1:tL2Vm8k2K9M9JSKg64klrDP2WV6W4cW7THc8GfJyBsQ= +google.golang.org/protobuf v1.25.1-0.20200622203222-a9513ebdb860/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -514,6 +587,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= @@ -530,11 +604,14 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go index dc4307941..43841b549 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,8 @@ package main import ( + "fmt" + "github.com/runatlantis/atlantis/cmd" "github.com/runatlantis/atlantis/server/logging" "github.com/spf13/viper" @@ -25,13 +27,19 @@ const atlantisVersion = "0.17.0-beta" func main() { v := viper.New() + logger, err := logging.NewStructuredLogger() + + if err != nil { + panic(fmt.Sprintf("unable to initialize logger. %s", err.Error())) + } + // We're creating commands manually here rather than using init() functions // (as recommended by cobra) because it makes testing easier. server := &cmd.ServerCmd{ ServerCreator: &cmd.DefaultServerCreator{}, Viper: v, AtlantisVersion: atlantisVersion, - Logger: logging.NewSimpleLogger("cmd", false, logging.Info), + Logger: logger, } version := &cmd.VersionCmd{AtlantisVersion: atlantisVersion} testdrive := &cmd.TestdriveCmd{} diff --git a/server/events/apply_command_runner_test.go b/server/events/apply_command_runner_test.go index 9a17e7658..49b171c2e 100644 --- a/server/events/apply_command_runner_test.go +++ b/server/events/apply_command_runner_test.go @@ -10,6 +10,7 @@ import ( "github.com/runatlantis/atlantis/server/events/locking" "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/models/fixtures" + "github.com/runatlantis/atlantis/server/logging" ) func TestApplyCommandRunner_IsLocked(t *testing.T) { @@ -54,7 +55,7 @@ func TestApplyCommandRunner_IsLocked(t *testing.T) { ctx := &events.CommandContext{ User: fixtures.User, - Log: noopLogger, + Log: logging.NewNoopLogger(t), Pull: modelPull, HeadRepo: fixtures.GithubRepo, Trigger: events.Comment, diff --git a/server/events/command_context.go b/server/events/command_context.go index 16c4abf67..de48295dd 100644 --- a/server/events/command_context.go +++ b/server/events/command_context.go @@ -39,7 +39,7 @@ type CommandContext struct { Pull models.PullRequest // User is the user that triggered this command. User models.User - Log *logging.SimpleLogger + Log logging.SimpleLogging // PullMergeable is true if Pull is able to be merged. This is available in // the CommandContext because we want to collect this information before we // set our own build statuses which can affect mergeability if users have diff --git a/server/events/command_runner.go b/server/events/command_runner.go index 5d78eebe3..a851b85cb 100644 --- a/server/events/command_runner.go +++ b/server/events/command_runner.go @@ -15,6 +15,7 @@ package events import ( "fmt" + "strconv" "github.com/google/go-github/v31/github" "github.com/mcdafydd/go-azuredevops/azuredevops" @@ -238,9 +239,12 @@ func (c *DefaultCommandRunner) getAzureDevopsData(baseRepo models.Repo, pullNum return pull, headRepo, nil } -func (c *DefaultCommandRunner) buildLogger(repoFullName string, pullNum int) *logging.SimpleLogger { - src := fmt.Sprintf("%s#%d", repoFullName, pullNum) - return c.Logger.NewLogger(src, true, c.Logger.GetLevel()) +func (c *DefaultCommandRunner) buildLogger(repoFullName string, pullNum int) logging.SimpleLogging { + + return c.Logger.WithHistory( + "repo", repoFullName, + "pull", strconv.Itoa(pullNum), + ) } func (c *DefaultCommandRunner) ensureValidRepoMetadata( @@ -249,7 +253,7 @@ func (c *DefaultCommandRunner) ensureValidRepoMetadata( maybePull *models.PullRequest, user models.User, pullNum int, - log *logging.SimpleLogger, + log logging.SimpleLogging, ) (headRepo models.Repo, pull models.PullRequest, err error) { if maybeHeadRepo != nil { headRepo = *maybeHeadRepo diff --git a/server/events/command_runner_test.go b/server/events/command_runner_test.go index 048ca2511..15d97be5f 100644 --- a/server/events/command_runner_test.go +++ b/server/events/command_runner_test.go @@ -33,7 +33,6 @@ import ( "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/models/fixtures" vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" - logmocks "github.com/runatlantis/atlantis/server/logging/mocks" . "github.com/runatlantis/atlantis/testing" ) @@ -44,7 +43,6 @@ var azuredevopsGetter *mocks.MockAzureDevopsPullGetter var githubGetter *mocks.MockGithubPullGetter var gitlabGetter *mocks.MockGitlabMergeRequestGetter var ch events.DefaultCommandRunner -var pullLogger *logging.SimpleLogger var workingDir events.WorkingDir var pendingPlanFinder *mocks.MockPendingPlanFinder var drainer *events.Drainer @@ -73,8 +71,7 @@ func setup(t *testing.T) *vcsmocks.MockClient { githubGetter = mocks.NewMockGithubPullGetter() gitlabGetter = mocks.NewMockGitlabMergeRequestGetter() azuredevopsGetter = mocks.NewMockAzureDevopsPullGetter() - logger := logmocks.NewMockSimpleLogging() - pullLogger = logging.NewSimpleLogger("runatlantis/atlantis#1", true, logging.Info) + logger = logging.NewNoopLogger(t) projectCommandRunner = mocks.NewMockProjectCommandRunner() workingDir = mocks.NewMockWorkingDir() pendingPlanFinder = mocks.NewMockPendingPlanFinder() @@ -88,9 +85,6 @@ func setup(t *testing.T) *vcsmocks.MockClient { drainer = &events.Drainer{} deleteLockCommand = eventmocks.NewMockDeleteLockCommand() applyLockChecker = lockingmocks.NewMockApplyLockChecker() - When(logger.GetLevel()).ThenReturn(logging.Info) - When(logger.NewLogger("runatlantis/atlantis#1", true, logging.Info)). - ThenReturn(pullLogger) dbUpdater = &events.DBUpdater{ DB: defaultBoltDB, @@ -194,22 +188,6 @@ func TestRunCommentCommand_LogPanics(t *testing.T) { Assert(t, strings.Contains(comment, "Error: goroutine panic"), fmt.Sprintf("comment should be about a goroutine panic but was %q", comment)) } -func TestRunCommentCommand_NoGithubPullGetter(t *testing.T) { - t.Log("if DefaultCommandRunner was constructed with a nil GithubPullGetter an error should be logged") - setup(t) - ch.GithubPullGetter = nil - ch.RunCommentCommand(fixtures.GithubRepo, &fixtures.GithubRepo, nil, fixtures.User, 1, nil) - Equals(t, "[EROR] Atlantis not configured to support GitHub\n", pullLogger.History.String()) -} - -func TestRunCommentCommand_NoGitlabMergeGetter(t *testing.T) { - t.Log("if DefaultCommandRunner was constructed with a nil GitlabMergeRequestGetter an error should be logged") - setup(t) - ch.GitlabMergeRequestGetter = nil - ch.RunCommentCommand(fixtures.GitlabRepo, &fixtures.GitlabRepo, nil, fixtures.User, 1, nil) - Equals(t, "[EROR] Atlantis not configured to support GitLab\n", pullLogger.History.String()) -} - func TestRunCommentCommand_GithubPullErr(t *testing.T) { t.Log("if getting the github pull request fails an error should be logged") vcsClient := setup(t) diff --git a/server/events/delete_lock_command.go b/server/events/delete_lock_command.go index 5ed05f0bc..ff3cfd168 100644 --- a/server/events/delete_lock_command.go +++ b/server/events/delete_lock_command.go @@ -18,7 +18,7 @@ type DeleteLockCommand interface { // DefaultDeleteLockCommand deletes a specific lock after a request from the LocksController. type DefaultDeleteLockCommand struct { Locker locking.Locker - Logger *logging.SimpleLogger + Logger logging.SimpleLogging WorkingDir WorkingDir WorkingDirLocker WorkingDirLocker DB *db.BoltDB diff --git a/server/events/delete_lock_command_test.go b/server/events/delete_lock_command_test.go index ba2acd8c0..9c34e8003 100644 --- a/server/events/delete_lock_command_test.go +++ b/server/events/delete_lock_command_test.go @@ -20,7 +20,7 @@ func TestDeleteLock_LockerErr(t *testing.T) { When(l.Unlock("id")).ThenReturn(nil, errors.New("err")) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } _, err := dlc.DeleteLock("id") ErrEquals(t, "err", err) @@ -33,7 +33,7 @@ func TestDeleteLock_None(t *testing.T) { When(l.Unlock("id")).ThenReturn(nil, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lock, err := dlc.DeleteLock("id") Ok(t, err) @@ -47,7 +47,7 @@ func TestDeleteLock_OldFormat(t *testing.T) { When(l.Unlock("id")).ThenReturn(&models.ProjectLock{}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lock, err := dlc.DeleteLock("id") Ok(t, err) @@ -78,7 +78,7 @@ func TestDeleteLock_Success(t *testing.T) { Ok(t, err) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), DB: db, WorkingDirLocker: workingDirLocker, WorkingDir: workingDir, @@ -98,7 +98,7 @@ func TestDeleteLocksByPull_LockerErr(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn(nil, errors.New("err")) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) ErrEquals(t, "err", err) @@ -113,7 +113,7 @@ func TestDeleteLocksByPull_None(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn([]models.ProjectLock{}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) Ok(t, err) @@ -128,7 +128,7 @@ func TestDeleteLocksByPull_OldFormat(t *testing.T) { When(l.UnlockByPull(repoName, pullNum)).ThenReturn([]models.ProjectLock{{}}, nil) dlc := events.DefaultDeleteLockCommand{ Locker: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } err := dlc.DeleteLocksByPull(repoName, pullNum) Ok(t, err) diff --git a/server/events/git_cred_writer.go b/server/events/git_cred_writer.go index ab92d038c..1eea384c2 100644 --- a/server/events/git_cred_writer.go +++ b/server/events/git_cred_writer.go @@ -16,7 +16,7 @@ import ( // used for authenticating with git over HTTPS // It will create the file in home/.git-credentials // If ghAccessToken is true we will look for a line starting with https://x-access-token and ending with gitHostname and replace it. -func WriteGitCreds(gitUser string, gitToken string, gitHostname string, home string, logger *logging.SimpleLogger, ghAccessToken bool) error { +func WriteGitCreds(gitUser string, gitToken string, gitHostname string, home string, logger logging.SimpleLogging, ghAccessToken bool) error { const credsFilename = ".git-credentials" credsFile := filepath.Join(home, credsFilename) credsFileContentsPattern := `https://%s:%s@%s` diff --git a/server/events/git_cred_writer_test.go b/server/events/git_cred_writer_test.go index 3e881666a..c8fc9a2cc 100644 --- a/server/events/git_cred_writer_test.go +++ b/server/events/git_cred_writer_test.go @@ -12,7 +12,7 @@ import ( . "github.com/runatlantis/atlantis/testing" ) -var logger *logging.SimpleLogger +var logger logging.SimpleLogging // Test that we write the file as expected func TestWriteGitCreds_WriteFile(t *testing.T) { diff --git a/server/events/github_app_working_dir.go b/server/events/github_app_working_dir.go index 9e364eb41..05e2055e3 100644 --- a/server/events/github_app_working_dir.go +++ b/server/events/github_app_working_dir.go @@ -21,7 +21,7 @@ type GithubAppWorkingDir struct { } // Clone writes a fresh token for Github App authentication -func (g *GithubAppWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (g *GithubAppWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { log.Info("Refreshing git tokens for Github App") diff --git a/server/events/github_app_working_dir_test.go b/server/events/github_app_working_dir_test.go index 9dbcbd77b..25dd64da7 100644 --- a/server/events/github_app_working_dir_test.go +++ b/server/events/github_app_working_dir_test.go @@ -11,6 +11,7 @@ import ( "github.com/runatlantis/atlantis/server/events/vcs" "github.com/runatlantis/atlantis/server/events/vcs/fixtures" vcsMocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -49,7 +50,9 @@ func TestClone_GithubAppNoneExisting(t *testing.T) { GithubHostname: testServer, } - cloneDir, _, err := gwd.Clone(nil, models.Repo{}, models.PullRequest{ + logger := logging.NewNoopLogger(t) + + cloneDir, _, err := gwd.Clone(logger, models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -81,6 +84,8 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) { "", ) + logger := logging.NewNoopLogger(t) + headRepo := baseRepo modifiedBaseRepo := baseRepo @@ -88,11 +93,11 @@ func TestClone_GithubAppSetsCorrectUrl(t *testing.T) { modifiedBaseRepo.SanitizedCloneURL = "https://x-access-token:@github.com/runatlantis/atlantis.git" When(credentials.GetToken()).ThenReturn("token", nil) - When(workingDir.Clone(nil, modifiedBaseRepo, models.PullRequest{BaseRepo: modifiedBaseRepo}, "default")).ThenReturn( + When(workingDir.Clone(logger, modifiedBaseRepo, models.PullRequest{BaseRepo: modifiedBaseRepo}, "default")).ThenReturn( "", true, nil, ) - _, success, _ := ghAppWorkingDir.Clone(nil, headRepo, models.PullRequest{BaseRepo: baseRepo}, "default") + _, success, _ := ghAppWorkingDir.Clone(logger, headRepo, models.PullRequest{BaseRepo: baseRepo}, "default") Assert(t, success == true, "clone url mutation error") } diff --git a/server/events/matchers/ptr_to_logging_simplelogger.go b/server/events/matchers/ptr_to_logging_simplelogger.go index 04c72791b..cf9bb5453 100644 --- a/server/events/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/mock_workingdir_test.go b/server/events/mock_workingdir_test.go index 41608a535..163d3549b 100644 --- a/server/events/mock_workingdir_test.go +++ b/server/events/mock_workingdir_test.go @@ -27,7 +27,7 @@ func NewMockWorkingDir(options ...pegomock.Option) *MockWorkingDir { func (mock *MockWorkingDir) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWorkingDir) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (mock *MockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWorkingDir().") } @@ -155,7 +155,7 @@ type VerifierMockWorkingDir struct { timeout time.Duration } -func (verifier *VerifierMockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { +func (verifier *VerifierMockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { params := []pegomock.Param{log, headRepo, p, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Clone", params, verifier.timeout) return &MockWorkingDir_Clone_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -166,17 +166,17 @@ type MockWorkingDir_Clone_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.Repo, models.PullRequest, string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.Repo, models.PullRequest, string) { log, headRepo, p, workspace := c.GetAllCapturedArguments() return log[len(log)-1], headRepo[len(headRepo)-1], p[len(p)-1], workspace[len(workspace)-1] } -func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.Repo, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791b..cf9bb5453 100644 --- a/server/events/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/mocks/mock_project_lock.go b/server/events/mocks/mock_project_lock.go index 7515468aa..5674a361c 100644 --- a/server/events/mocks/mock_project_lock.go +++ b/server/events/mocks/mock_project_lock.go @@ -27,7 +27,7 @@ func NewMockProjectLocker(options ...pegomock.Option) *MockProjectLocker { func (mock *MockProjectLocker) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockProjectLocker) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*events.TryLockResponse, error) { +func (mock *MockProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*events.TryLockResponse, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockProjectLocker().") } @@ -83,7 +83,7 @@ type VerifierMockProjectLocker struct { timeout time.Duration } -func (verifier *VerifierMockProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) *MockProjectLocker_TryLock_OngoingVerification { +func (verifier *VerifierMockProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) *MockProjectLocker_TryLock_OngoingVerification { params := []pegomock.Param{log, pull, user, workspace, project} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "TryLock", params, verifier.timeout) return &MockProjectLocker_TryLock_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -94,17 +94,17 @@ type MockProjectLocker_TryLock_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockProjectLocker_TryLock_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.PullRequest, models.User, string, models.Project) { +func (c *MockProjectLocker_TryLock_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.PullRequest, models.User, string, models.Project) { log, pull, user, workspace, project := c.GetAllCapturedArguments() return log[len(log)-1], pull[len(pull)-1], user[len(user)-1], workspace[len(workspace)-1], project[len(project)-1] } -func (c *MockProjectLocker_TryLock_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.PullRequest, _param2 []models.User, _param3 []string, _param4 []models.Project) { +func (c *MockProjectLocker_TryLock_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.PullRequest, _param2 []models.User, _param3 []string, _param4 []models.Project) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.PullRequest, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/mock_webhooks_sender.go b/server/events/mocks/mock_webhooks_sender.go index 2be91b089..8f3562458 100644 --- a/server/events/mocks/mock_webhooks_sender.go +++ b/server/events/mocks/mock_webhooks_sender.go @@ -26,7 +26,7 @@ func NewMockWebhooksSender(options ...pegomock.Option) *MockWebhooksSender { func (mock *MockWebhooksSender) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWebhooksSender) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWebhooksSender) Send(log *logging.SimpleLogger, res webhooks.ApplyResult) error { +func (mock *MockWebhooksSender) Send(log logging.SimpleLogging, res webhooks.ApplyResult) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWebhooksSender().") } @@ -78,7 +78,7 @@ type VerifierMockWebhooksSender struct { timeout time.Duration } -func (verifier *VerifierMockWebhooksSender) Send(log *logging.SimpleLogger, res webhooks.ApplyResult) *MockWebhooksSender_Send_OngoingVerification { +func (verifier *VerifierMockWebhooksSender) Send(log logging.SimpleLogging, res webhooks.ApplyResult) *MockWebhooksSender_Send_OngoingVerification { params := []pegomock.Param{log, res} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Send", params, verifier.timeout) return &MockWebhooksSender_Send_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -89,17 +89,17 @@ type MockWebhooksSender_Send_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWebhooksSender_Send_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, webhooks.ApplyResult) { +func (c *MockWebhooksSender_Send_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, webhooks.ApplyResult) { log, res := c.GetAllCapturedArguments() return log[len(log)-1], res[len(res)-1] } -func (c *MockWebhooksSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []webhooks.ApplyResult) { +func (c *MockWebhooksSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []webhooks.ApplyResult) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]webhooks.ApplyResult, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/mocks/mock_working_dir.go b/server/events/mocks/mock_working_dir.go index 4ad6467fd..30e756d87 100644 --- a/server/events/mocks/mock_working_dir.go +++ b/server/events/mocks/mock_working_dir.go @@ -26,7 +26,7 @@ func NewMockWorkingDir(options ...pegomock.Option) *MockWorkingDir { func (mock *MockWorkingDir) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockWorkingDir) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { +func (mock *MockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockWorkingDir().") } @@ -154,7 +154,7 @@ type VerifierMockWorkingDir struct { timeout time.Duration } -func (verifier *VerifierMockWorkingDir) Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { +func (verifier *VerifierMockWorkingDir) Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) *MockWorkingDir_Clone_OngoingVerification { params := []pegomock.Param{log, headRepo, p, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Clone", params, verifier.timeout) return &MockWorkingDir_Clone_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -165,17 +165,17 @@ type MockWorkingDir_Clone_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, models.Repo, models.PullRequest, string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, models.Repo, models.PullRequest, string) { log, headRepo, p, workspace := c.GetAllCapturedArguments() return log[len(log)-1], headRepo[len(headRepo)-1], p[len(p)-1], workspace[len(workspace)-1] } -func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { +func (c *MockWorkingDir_Clone_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []models.Repo, _param2 []models.PullRequest, _param3 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]models.Repo, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/models/models.go b/server/events/models/models.go index 6ce327125..4e449a364 100644 --- a/server/events/models/models.go +++ b/server/events/models/models.go @@ -355,7 +355,7 @@ type ProjectCommandContext struct { // be the same as BaseRepo. HeadRepo Repo // Log is a logger that's been set up for this context. - Log *logging.SimpleLogger + Log logging.SimpleLogging // PullMergeable is true if the pull request for this project is able to be merged. PullMergeable bool // Pull is the pull request we're responding to. diff --git a/server/events/pre_workflow_hooks_command_runner_test.go b/server/events/pre_workflow_hooks_command_runner_test.go index b0c3a7dc9..0b9fd48cf 100644 --- a/server/events/pre_workflow_hooks_command_runner_test.go +++ b/server/events/pre_workflow_hooks_command_runner_test.go @@ -42,7 +42,7 @@ func newBool(b bool) *bool { func TestRunPreHooks_Clone(t *testing.T) { - log := logging.NewNoopLogger() + log := logging.NewNoopLogger(t) var newPull = fixtures.Pull newPull.BaseRepo = fixtures.GithubRepo diff --git a/server/events/project_command_builder_internal_test.go b/server/events/project_command_builder_internal_test.go index 3bb07fcc4..f721dff6b 100644 --- a/server/events/project_command_builder_internal_test.go +++ b/server/events/project_command_builder_internal_test.go @@ -12,11 +12,14 @@ import ( vcsmocks "github.com/runatlantis/atlantis/server/events/vcs/mocks" "github.com/runatlantis/atlantis/server/events/yaml" "github.com/runatlantis/atlantis/server/events/yaml/valid" + "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) // Test different permutations of global and repo config. func TestBuildProjectCmdCtx(t *testing.T) { + logger := logging.NewNoopLogger(t) emptyPolicySets := valid.PolicySets{ Version: nil, PolicySets: []valid.PolicySet{}, @@ -62,7 +65,7 @@ workflows: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -112,7 +115,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -164,7 +167,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -224,7 +227,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -371,7 +374,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -427,7 +430,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -486,7 +489,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -529,7 +532,7 @@ projects: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -595,6 +598,7 @@ projects: for _, cmd := range []models.CommandName{models.PlanCommand, models.ApplyCommand} { t.Run(cmd.String(), func(t *testing.T) { ctxs, err := builder.buildProjectCommandCtx(&CommandContext{ + Log: logger, Pull: models.PullRequest{ BaseRepo: baseRepo, }, @@ -713,7 +717,7 @@ projects: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logging.NewNoopLogger(t), PullMergeable: true, Pull: pull, ProjectName: "myproject_1", @@ -747,7 +751,7 @@ projects: defer cleanup() workingDir := NewMockWorkingDir() - When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil) + When(workingDir.Clone(logging_matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil) vcsClient := vcsmocks.NewMockClient() When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil) @@ -783,6 +787,7 @@ projects: Pull: models.PullRequest{ BaseRepo: baseRepo, }, + Log: logging.NewNoopLogger(t), PullMergeable: true, }, cmd, "myproject_[1-2]", []string{"flag"}, tmp, "project1", "myworkspace", true) @@ -827,6 +832,7 @@ projects: } func TestBuildProjectCmdCtx_WithPolicCheckEnabled(t *testing.T) { + logger := logging.NewNoopLogger(t) emptyPolicySets := valid.PolicySets{ Version: nil, PolicySets: []valid.PolicySet{}, @@ -862,7 +868,7 @@ repos: AutomergeEnabled: false, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -917,7 +923,7 @@ workflows: AutomergeEnabled: true, AutoplanEnabled: true, HeadRepo: models.Repo{}, - Log: nil, + Log: logger, PullMergeable: true, Pull: pull, ProjectName: "", @@ -982,6 +988,7 @@ workflows: cmd := models.PolicyCheckCommand t.Run(cmd.String(), func(t *testing.T) { ctxs, err := builder.buildProjectCommandCtx(&CommandContext{ + Log: logger, Pull: models.PullRequest{ BaseRepo: baseRepo, }, diff --git a/server/events/project_command_builder_test.go b/server/events/project_command_builder_test.go index 781e3a253..5c59f8cd4 100644 --- a/server/events/project_command_builder_test.go +++ b/server/events/project_command_builder_test.go @@ -117,6 +117,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { t.Run(c.Description, func(t *testing.T) { RegisterMockTestingT(t) @@ -150,6 +152,7 @@ projects: ctxs, err := builder.BuildAutoplanCommands(&events.CommandContext{ PullMergeable: true, + Log: logger, }) Ok(t, err) Equals(t, len(c.exp), len(ctxs)) @@ -340,6 +343,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { // NOTE: we're testing both plan and apply here. for _, cmdName := range []models.CommandName{models.PlanCommand, models.ApplyCommand} { @@ -377,9 +382,11 @@ projects: var actCtxs []models.ProjectCommandContext var err error if cmdName == models.PlanCommand { - actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{}, &c.Cmd) + actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{ + Log: logger, + }, &c.Cmd) } else { - actCtxs, err = builder.BuildApplyCommands(&events.CommandContext{}, &c.Cmd) + actCtxs, err = builder.BuildApplyCommands(&events.CommandContext{Log: logger}, &c.Cmd) } if c.ExpErr != "" { @@ -481,6 +488,8 @@ projects: }, }, } + + logger := logging.NewNoopLogger(t) for name, c := range cases { t.Run(name, func(t *testing.T) { RegisterMockTestingT(t) @@ -512,7 +521,9 @@ projects: ) ctxs, err := builder.BuildPlanCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -572,6 +583,8 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) { matchers.AnyModelsPullRequest())). ThenReturn(tmpDir, nil) + logger := logging.NewNoopLogger(t) + builder := events.NewProjectCommandBuilder( false, &yaml.ParserValidator{}, @@ -587,7 +600,9 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) { ) ctxs, err := builder.BuildApplyCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -660,7 +675,7 @@ projects: HeadRepo: models.Repo{}, Pull: models.PullRequest{}, User: models.User{}, - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), } _, err = builder.BuildPlanCommands(ctx, &events.CommentCommand{ RepoRelDir: ".", @@ -693,6 +708,8 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) { }, } + logger := logging.NewNoopLogger(t) + for _, c := range cases { t.Run(strings.Join(c.ExtraArgs, " "), func(t *testing.T) { RegisterMockTestingT(t) @@ -723,7 +740,9 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) { var actCtxs []models.ProjectCommandContext var err error - actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{}, &events.CommentCommand{ + actCtxs, err = builder.BuildPlanCommands(&events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: ".", Flags: c.ExtraArgs, Name: models.PlanCommand, @@ -852,6 +871,8 @@ projects: }, } + logger := logging.NewNoopLogger(t) + for name, testCase := range testCases { t.Run(name, func(t *testing.T) { RegisterMockTestingT(t) @@ -889,7 +910,9 @@ projects: ) actCtxs, err := builder.BuildPlanCommands( - &events.CommandContext{}, + &events.CommandContext{ + Log: logger, + }, &events.CommentCommand{ RepoRelDir: "", Flags: nil, @@ -925,6 +948,8 @@ projects: When(vcsClient.DownloadRepoConfigFile(matchers.AnyModelsPullRequest())).ThenReturn(true, []byte(atlantisYAML), nil) workingDir := mocks.NewMockWorkingDir() + logger := logging.NewNoopLogger(t) + builder := events.NewProjectCommandBuilder( false, &yaml.ParserValidator{}, @@ -945,7 +970,7 @@ projects: HeadRepo: models.Repo{}, Pull: models.PullRequest{}, User: models.User{}, - Log: nil, + Log: logger, PullMergeable: true, }) Ok(t, err) @@ -960,6 +985,8 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman }) defer cleanup() + logger := logging.NewNoopLogger(t) + workingDir := mocks.NewMockWorkingDir() When(workingDir.Clone(matchers.AnyPtrToLoggingSimpleLogger(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmpDir, false, nil) vcsClient := vcsmocks.NewMockClient() @@ -982,6 +1009,7 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman ctxs, err := builder.BuildAutoplanCommands(&events.CommandContext{ PullMergeable: true, + Log: logger, }) Ok(t, err) diff --git a/server/events/project_command_runner.go b/server/events/project_command_runner.go index e10c41f8c..3d3d72a83 100644 --- a/server/events/project_command_runner.go +++ b/server/events/project_command_runner.go @@ -75,7 +75,7 @@ type EnvStepRunner interface { // WebhooksSender sends webhook. type WebhooksSender interface { // Send sends the webhook. - Send(log *logging.SimpleLogger, res webhooks.ApplyResult) error + Send(log logging.SimpleLogging, res webhooks.ApplyResult) error } //go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_project_command_runner.go ProjectCommandRunner diff --git a/server/events/project_command_runner_test.go b/server/events/project_command_runner_test.go index b6739d82d..a51b09118 100644 --- a/server/events/project_command_runner_test.go +++ b/server/events/project_command_runner_test.go @@ -79,7 +79,7 @@ func TestDefaultProjectCommandRunner_Plan(t *testing.T) { "name": "value", } ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: []valid.Step{ { StepName: "env", @@ -298,7 +298,7 @@ func TestDefaultProjectCommandRunner_Apply(t *testing.T) { )).ThenReturn(repoDir, nil) ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: c.steps, Workspace: "default", ApplyRequirements: c.applyReqs, @@ -387,7 +387,7 @@ func TestDefaultProjectCommandRunner_RunEnvSteps(t *testing.T) { }, nil) ctx := models.ProjectCommandContext{ - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Steps: []valid.Step{ { StepName: "run", diff --git a/server/events/project_finder.go b/server/events/project_finder.go index 3dcaf762c..679df16f8 100644 --- a/server/events/project_finder.go +++ b/server/events/project_finder.go @@ -34,11 +34,11 @@ type ProjectFinder interface { // DetermineProjects returns the list of projects that were modified based on // the modifiedFiles. The list will be de-duplicated. // absRepoDir is the path to the cloned repo on disk. - DetermineProjects(log *logging.SimpleLogger, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project + DetermineProjects(log logging.SimpleLogging, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project // DetermineProjectsViaConfig returns the list of projects that were modified // based on modifiedFiles and the repo's config. // absRepoDir is the path to the cloned repo on disk. - DetermineProjectsViaConfig(log *logging.SimpleLogger, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) + DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) } // ignoredFilenameFragments contains filename fragments to ignore while looking at changes @@ -48,7 +48,7 @@ var ignoredFilenameFragments = []string{"terraform.tfstate", "terraform.tfstate. type DefaultProjectFinder struct{} // See ProjectFinder.DetermineProjects. -func (p *DefaultProjectFinder) DetermineProjects(log *logging.SimpleLogger, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project { +func (p *DefaultProjectFinder) DetermineProjects(log logging.SimpleLogging, modifiedFiles []string, repoFullName string, absRepoDir string) []models.Project { var projects []models.Project modifiedTerraformFiles := p.filterToTerraform(modifiedFiles) @@ -82,7 +82,7 @@ func (p *DefaultProjectFinder) DetermineProjects(log *logging.SimpleLogger, modi } // See ProjectFinder.DetermineProjectsViaConfig. -func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log *logging.SimpleLogger, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) { +func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) { var projects []valid.Project for _, project := range config.Projects { log.Debug("checking if project at dir %q workspace %q was modified", project.Dir, project.Workspace) diff --git a/server/events/project_finder_test.go b/server/events/project_finder_test.go index d2c01bfa7..4f218371c 100644 --- a/server/events/project_finder_test.go +++ b/server/events/project_finder_test.go @@ -25,7 +25,6 @@ import ( . "github.com/runatlantis/atlantis/testing" ) -var noopLogger = logging.NewNoopLogger() var modifiedRepo = "owner/repo" var m = events.DefaultProjectFinder{} var nestedModules1 string @@ -105,6 +104,7 @@ func setupTmpRepos(t *testing.T) { } func TestDetermineProjects(t *testing.T) { + noopLogger := logging.NewNoopLogger(t) setupTmpRepos(t) cases := []struct { @@ -459,7 +459,7 @@ func TestDefaultProjectFinder_DetermineProjectsViaConfig(t *testing.T) { for _, c := range cases { t.Run(c.description, func(t *testing.T) { pf := events.DefaultProjectFinder{} - projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(), c.modified, c.config, tmpDir) + projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(t), c.modified, c.config, tmpDir) Ok(t, err) Equals(t, len(c.expProjPaths), len(projects)) for i, proj := range projects { diff --git a/server/events/project_locker.go b/server/events/project_locker.go index 92aa64b0c..bfffd0feb 100644 --- a/server/events/project_locker.go +++ b/server/events/project_locker.go @@ -33,7 +33,7 @@ type ProjectLocker interface { // The third return value is a function that can be called to unlock the // lock. It will only be set if the lock was acquired. Any errors will set // error. - TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) + TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) } // DefaultProjectLocker implements ProjectLocker. @@ -58,7 +58,7 @@ type TryLockResponse struct { } // TryLock implements ProjectLocker.TryLock. -func (p *DefaultProjectLocker) TryLock(log *logging.SimpleLogger, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) { +func (p *DefaultProjectLocker) TryLock(log logging.SimpleLogging, pull models.PullRequest, user models.User, workspace string, project models.Project) (*TryLockResponse, error) { lockAttempt, err := p.Locker.TryLock(project, workspace, pull, user) if err != nil { return nil, err diff --git a/server/events/project_locker_test.go b/server/events/project_locker_test.go index ba78f4718..ce5af7c97 100644 --- a/server/events/project_locker_test.go +++ b/server/events/project_locker_test.go @@ -53,7 +53,7 @@ func TestDefaultProjectLocker_TryLockWhenLocked(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) link, _ := mockClient.MarkdownPullLink(lockingPull) Ok(t, err) Equals(t, &events.TryLockResponse{ @@ -90,7 +90,7 @@ func TestDefaultProjectLocker_TryLockWhenLockedSamePull(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) Ok(t, err) Equals(t, true, res.LockAcquired) @@ -129,7 +129,7 @@ func TestDefaultProjectLocker_TryLockUnlocked(t *testing.T) { }, nil, ) - res, err := locker.TryLock(logging.NewNoopLogger(), expPull, expUser, expWorkspace, expProject) + res, err := locker.TryLock(logging.NewNoopLogger(t), expPull, expUser, expWorkspace, expProject) Ok(t, err) Equals(t, true, res.LockAcquired) diff --git a/server/events/pull_updater.go b/server/events/pull_updater.go index 418f91711..bab993877 100644 --- a/server/events/pull_updater.go +++ b/server/events/pull_updater.go @@ -25,7 +25,7 @@ func (c *PullUpdater) updatePull(ctx *CommandContext, command PullCommand, res C } } - comment := c.MarkdownRenderer.Render(res, command.CommandName(), ctx.Log.History.String(), command.IsVerbose(), ctx.Pull.BaseRepo.VCSHost.Type) + comment := c.MarkdownRenderer.Render(res, command.CommandName(), ctx.Log.GetHistory(), command.IsVerbose(), ctx.Pull.BaseRepo.VCSHost.Type) if err := c.VCSClient.CreateComment(ctx.Pull.BaseRepo, ctx.Pull.Num, comment, command.CommandName().String()); err != nil { ctx.Log.Err("unable to comment: %s", err) } diff --git a/server/events/runtime/apply_step_runner_test.go b/server/events/runtime/apply_step_runner_test.go index 386857a17..aec19d98f 100644 --- a/server/events/runtime/apply_step_runner_test.go +++ b/server/events/runtime/apply_step_runner_test.go @@ -20,6 +20,7 @@ import ( "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -59,17 +60,19 @@ func TestRun_Success(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "workspace") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -87,10 +90,12 @@ func TestRun_AppliesCorrectProjectPlan(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "default", RepoRelDir: ".", ProjectName: "projectname", @@ -98,7 +103,7 @@ func TestRun_AppliesCorrectProjectPlan(t *testing.T) { }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "default") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), nil, "default") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -115,19 +120,21 @@ func TestRun_UsesConfiguredTFVersion(t *testing.T) { o := runtime.ApplyStepRunner{ TerraformExecutor: terraform, } + logger := logging.NewNoopLogger(t) tfVersion, _ := version.NewVersion("0.11.0") - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := o.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, TerraformVersion: tfVersion, + Log: logger, }, []string{"extra", "args"}, tmpDir, map[string]string(nil)) Ok(t, err) Equals(t, "output", output) - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), tfVersion, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, tmpDir, []string{"apply", "-input=false", "-no-color", "extra", "args", "comment", "args", fmt.Sprintf("%q", planPath)}, map[string]string(nil), tfVersion, "workspace") _, err = os.Stat(planPath) Assert(t, os.IsNotExist(err), "planfile should be deleted") } @@ -135,6 +142,7 @@ func TestRun_UsesConfiguredTFVersion(t *testing.T) { // Apply ignores the -target flag when used with a planfile so we should give // an error if it's being used with -target. func TestRun_UsingTarget(t *testing.T) { + logger := logging.NewNoopLogger(t) cases := []struct { commentFlags []string extraArgs []string @@ -197,6 +205,7 @@ func TestRun_UsingTarget(t *testing.T) { } output, err := step.Run(models.ProjectCommandContext{ + Log: logger, Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: c.commentFlags, @@ -240,7 +249,7 @@ Plan: 0 to add, 0 to change, 1 to destroy.` } tfVersion, _ := version.NewVersion("0.11.0") ctx := models.ProjectCommandContext{ - Log: logging.NewSimpleLogger("testing", false, logging.Debug), + Log: logging.NewNoopLogger(t), Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, @@ -302,7 +311,7 @@ Plan: 0 to add, 0 to change, 1 to destroy.` tfVersion, _ := version.NewVersion("0.11.0") output, err := o.Run(models.ProjectCommandContext{ - Log: logging.NewSimpleLogger("testing", false, logging.Debug), + Log: logging.NewNoopLogger(t), Workspace: "workspace", RepoRelDir: ".", EscapedCommentArgs: []string{"comment", "args"}, @@ -356,7 +365,7 @@ type remoteApplyMock struct { } // RunCommandAsync fakes out running terraform async. -func (r *remoteApplyMock) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { +func (r *remoteApplyMock) RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { r.CalledArgs = args in := make(chan string) diff --git a/server/events/runtime/env_step_runner_test.go b/server/events/runtime/env_step_runner_test.go index 62b6f255f..112016653 100644 --- a/server/events/runtime/env_step_runner_test.go +++ b/server/events/runtime/env_step_runner_test.go @@ -68,7 +68,7 @@ func TestEnvStepRunner_Run(t *testing.T) { User: models.User{ Username: "acme-user", }, - Log: logging.NewNoopLogger(), + Log: logging.NewNoopLogger(t), Workspace: "myworkspace", RepoRelDir: "mydir", TerraformVersion: tfVersion, diff --git a/server/events/runtime/executor.go b/server/events/runtime/executor.go index 80cf3f096..fc06b0a09 100644 --- a/server/events/runtime/executor.go +++ b/server/events/runtime/executor.go @@ -21,5 +21,5 @@ type Executor interface { // ExecutorVersionEnsurer ensures a given version exists and outputs a path to the executable type ExecutorVersionEnsurer interface { - EnsureExecutorVersion(log *logging.SimpleLogger, v *version.Version) (string, error) + EnsureExecutorVersion(log logging.SimpleLogging, v *version.Version) (string, error) } diff --git a/server/events/runtime/init_step_runner_test.go b/server/events/runtime/init_step_runner_test.go index 01e2eafa2..47c9f39a4 100644 --- a/server/events/runtime/init_step_runner_test.go +++ b/server/events/runtime/init_step_runner_test.go @@ -6,11 +6,13 @@ import ( version "github.com/hashicorp/go-version" . "github.com/petergtz/pegomock" "github.com/pkg/errors" - "github.com/runatlantis/atlantis/server/events/mocks/matchers" + "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/runtime" "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" + "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -42,17 +44,20 @@ func TestRun_UsesGetOrInitForRightVersion(t *testing.T) { t.Run(c.version, func(t *testing.T) { terraform := mocks.NewMockClient() + logger := logging.NewNoopLogger(t) + tfVersion, _ := version.NewVersion(c.version) iso := runtime.InitStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := iso.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", + Log: logger, }, []string{"extra", "args"}, "/path", map[string]string(nil)) Ok(t, err) // When there is no error, should not return init output to PR. @@ -63,7 +68,7 @@ func TestRun_UsesGetOrInitForRightVersion(t *testing.T) { if c.expCmd == "get" { expArgs = []string{c.expCmd, "-no-color", "-upgrade", "extra", "args"} } - terraform.VerifyWasCalledOnce().RunCommandWithVersion(nil, "/path", expArgs, map[string]string(nil), tfVersion, "workspace") + terraform.VerifyWasCalledOnce().RunCommandWithVersion(logger, "/path", expArgs, map[string]string(nil), tfVersion, "workspace") }) } } @@ -72,7 +77,8 @@ func TestRun_ShowInitOutputOnError(t *testing.T) { // If there was an error during init then we want the output to be returned. RegisterMockTestingT(t) tfClient := mocks.NewMockClient() - When(tfClient.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + logger := logging.NewNoopLogger(t) + When(tfClient.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", errors.New("error")) tfVersion, _ := version.NewVersion("0.11.0") @@ -84,6 +90,7 @@ func TestRun_ShowInitOutputOnError(t *testing.T) { output, err := iso.Run(models.ProjectCommandContext{ Workspace: "workspace", RepoRelDir: ".", + Log: logger, }, nil, "/path", map[string]string(nil)) ErrEquals(t, "error", err) Equals(t, "output", output) diff --git a/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791b..cf9bb5453 100644 --- a/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/runtime/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/runtime/mocks/mock_versionedexecutorworkflow.go b/server/events/runtime/mocks/mock_versionedexecutorworkflow.go index f566d289e..cfe6556d7 100644 --- a/server/events/runtime/mocks/mock_versionedexecutorworkflow.go +++ b/server/events/runtime/mocks/mock_versionedexecutorworkflow.go @@ -27,7 +27,7 @@ func NewMockVersionedExecutorWorkflow(options ...pegomock.Option) *MockVersioned func (mock *MockVersionedExecutorWorkflow) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockVersionedExecutorWorkflow) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockVersionedExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *go_version.Version) (string, error) { +func (mock *MockVersionedExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *go_version.Version) (string, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockVersionedExecutorWorkflow().") } @@ -102,7 +102,7 @@ type VerifierMockVersionedExecutorWorkflow struct { timeout time.Duration } -func (verifier *VerifierMockVersionedExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *go_version.Version) *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification { +func (verifier *VerifierMockVersionedExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *go_version.Version) *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification { params := []pegomock.Param{log, v} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "EnsureExecutorVersion", params, verifier.timeout) return &MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -113,17 +113,17 @@ type MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification str methodInvocations []pegomock.MethodInvocation } -func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, *go_version.Version) { +func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, *go_version.Version) { log, v := c.GetAllCapturedArguments() return log[len(log)-1], v[len(v)-1] } -func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []*go_version.Version) { +func (c *MockVersionedExecutorWorkflow_EnsureExecutorVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []*go_version.Version) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]*go_version.Version, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/runtime/plan_step_runner_test.go b/server/events/runtime/plan_step_runner_test.go index 740a895d0..03e8e63e1 100644 --- a/server/events/runtime/plan_step_runner_test.go +++ b/server/events/runtime/plan_step_runner_test.go @@ -20,6 +20,7 @@ import ( "github.com/runatlantis/atlantis/server/events/terraform/mocks" matchers2 "github.com/runatlantis/atlantis/server/events/terraform/mocks/matchers" "github.com/runatlantis/atlantis/server/logging" + logging_matchers "github.com/runatlantis/atlantis/server/logging/mocks/matchers" . "github.com/runatlantis/atlantis/testing" ) @@ -29,14 +30,14 @@ func TestRun_NoWorkspaceIn08(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.8") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "default" s := runtime.PlanStepRunner{ DefaultTFVersion: tfVersion, TerraformExecutor: terraform, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -111,14 +112,14 @@ func TestRun_ErrWorkspaceIn08(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.8") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "notdefault" s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) _, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -159,14 +160,14 @@ func TestRun_SwitchesWorkspace(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion(c.tfVersion) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, } - When(terraform.RunCommandWithVersion(matchers.AnyPtrToLoggingSimpleLogger(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). + When(terraform.RunCommandWithVersion(logging_matchers.AnyLoggingSimpleLogging(), AnyString(), AnyStringSlice(), matchers2.AnyMapOfStringToString(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). ThenReturn("output", nil) output, err := s.Run(models.ProjectCommandContext{ Log: logger, @@ -255,7 +256,7 @@ func TestRun_CreatesWorkspace(t *testing.T) { t.Run(c.tfVersion, func(t *testing.T) { terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion(c.tfVersion) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -321,7 +322,7 @@ func TestRun_NoWorkspaceSwitchIfNotNecessary(t *testing.T) { RegisterMockTestingT(t) terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -390,7 +391,7 @@ func TestRun_AddsEnvVarFile(t *testing.T) { // Using version >= 0.10 here so we don't expect any env commands. tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -450,7 +451,7 @@ func TestRun_UsesDiffPathForProject(t *testing.T) { RegisterMockTestingT(t) terraform := mocks.NewMockClient() tfVersion, _ := version.NewVersion("0.10.0") - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) s := runtime.PlanStepRunner{ TerraformExecutor: terraform, DefaultTFVersion: tfVersion, @@ -705,6 +706,8 @@ locally at this time. for name, remoteOpsErr := range cases { t.Run(name, func(t *testing.T) { + logger := logging.NewNoopLogger(t) + RegisterMockTestingT(t) terraform := mocks.NewMockClient() asyncTf := &remotePlanMock{} @@ -722,7 +725,7 @@ locally at this time. // First, terraform workspace gets run. When(terraform.RunCommandWithVersion( - nil, + logger, absProjectPath, []string{"workspace", "show"}, map[string]string(nil), @@ -755,11 +758,12 @@ locally at this time. planErr := errors.New("exit status 1: err") planOutput := "\n" + remoteOpsErr asyncTf.LinesToSend = remotePlanOutput - When(terraform.RunCommandWithVersion(nil, absProjectPath, expPlanArgs, map[string]string(nil), tfVersion, "default")). + When(terraform.RunCommandWithVersion(logger, absProjectPath, expPlanArgs, map[string]string(nil), tfVersion, "default")). ThenReturn(planOutput, planErr) // Now that mocking is set up, we're ready to run the plan. ctx := models.ProjectCommandContext{ + Log: logger, Workspace: "default", RepoRelDir: ".", User: models.User{Username: "username"}, @@ -886,7 +890,7 @@ type remotePlanMock struct { CalledArgs []string } -func (r *remotePlanMock) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { +func (r *remotePlanMock) RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) { r.CalledArgs = args in := make(chan string) out := make(chan terraform.Line) diff --git a/server/events/runtime/policy/conftest_client.go b/server/events/runtime/policy/conftest_client.go index 053c8a9a7..8e701ebe1 100644 --- a/server/events/runtime/policy/conftest_client.go +++ b/server/events/runtime/policy/conftest_client.go @@ -127,7 +127,7 @@ type ConfTestExecutorWorkflow struct { Exec runtime_models.Exec } -func NewConfTestExecutorWorkflow(log *logging.SimpleLogger, versionRootDir string, conftestDownloder terraform.Downloader) *ConfTestExecutorWorkflow { +func NewConfTestExecutorWorkflow(log logging.SimpleLogging, versionRootDir string, conftestDownloder terraform.Downloader) *ConfTestExecutorWorkflow { downloader := ConfTestVersionDownloader{ downloader: conftestDownloder, } @@ -201,7 +201,7 @@ func (c *ConfTestExecutorWorkflow) sanitizeOutput(inputFile string, output strin return strings.Replace(output, inputFile, "", -1) } -func (c *ConfTestExecutorWorkflow) EnsureExecutorVersion(log *logging.SimpleLogger, v *version.Version) (string, error) { +func (c *ConfTestExecutorWorkflow) EnsureExecutorVersion(log logging.SimpleLogging, v *version.Version) (string, error) { // we have no information to proceed so fail hard if c.DefaultConftestVersion == nil && v == nil { return "", errors.New("no conftest version configured/specified") diff --git a/server/events/runtime/policy/conftest_client_test.go b/server/events/runtime/policy/conftest_client_test.go index 570a89b2a..163180332 100644 --- a/server/events/runtime/policy/conftest_client_test.go +++ b/server/events/runtime/policy/conftest_client_test.go @@ -62,7 +62,7 @@ func TestEnsureExecutorVersion(t *testing.T) { RegisterMockTestingT(t) mockCache := mocks.NewMockExecutionVersionCache() - log := logging.NewNoopLogger() + log := logging.NewNoopLogger(t) t.Run("no specified version or default version", func(t *testing.T) { subject := &ConfTestExecutorWorkflow{ @@ -132,6 +132,7 @@ func TestRun(t *testing.T) { SourceResolver: mockResolver, Exec: mockExec, } + log := logging.NewNoopLogger(t) policySetName1 := "policy1" policySetPath1 := "/some/path" @@ -167,6 +168,7 @@ func TestRun(t *testing.T) { }, ProjectName: "testproj", Workspace: "default", + Log: log, } t.Run("success", func(t *testing.T) { diff --git a/server/events/runtime/policy_check_step_runner_test.go b/server/events/runtime/policy_check_step_runner_test.go index a1b723af9..e19269ea7 100644 --- a/server/events/runtime/policy_check_step_runner_test.go +++ b/server/events/runtime/policy_check_step_runner_test.go @@ -15,7 +15,7 @@ import ( func TestRun(t *testing.T) { RegisterMockTestingT(t) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) workspace := "default" v, _ := version.NewVersion("1.0") workdir := "/path" diff --git a/server/events/runtime/pre_workflow_hook_runner_test.go b/server/events/runtime/pre_workflow_hook_runner_test.go index 70c092a56..75eb4a2b1 100644 --- a/server/events/runtime/pre_workflow_hook_runner_test.go +++ b/server/events/runtime/pre_workflow_hook_runner_test.go @@ -68,7 +68,7 @@ func TestPreWorkflowHookRunner_Run(t *testing.T) { When(terraform.EnsureVersion(matchers.AnyPtrToLoggingSimpleLogger(), matchers2.AnyPtrToGoVersionVersion())). ThenReturn(nil) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r := runtime.DefaultPreWorkflowHookRunner{} t.Run(c.Command, func(t *testing.T) { diff --git a/server/events/runtime/run_step_runner_test.go b/server/events/runtime/run_step_runner_test.go index 04528113c..165bedbe7 100644 --- a/server/events/runtime/run_step_runner_test.go +++ b/server/events/runtime/run_step_runner_test.go @@ -102,7 +102,7 @@ func TestRunStepRunner_Run(t *testing.T) { When(terraform.EnsureVersion(matchers.AnyPtrToLoggingSimpleLogger(), matchers2.AnyPtrToGoVersionVersion())). ThenReturn(nil) - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r := runtime.RunStepRunner{ TerraformExecutor: terraform, diff --git a/server/events/runtime/runtime.go b/server/events/runtime/runtime.go index fb8656f5d..a2beb78da 100644 --- a/server/events/runtime/runtime.go +++ b/server/events/runtime/runtime.go @@ -25,8 +25,8 @@ const ( // TerraformExec brings the interface from TerraformClient into this package // without causing circular imports. type TerraformExec interface { - RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) - EnsureVersion(log *logging.SimpleLogger, v *version.Version) error + RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) + EnsureVersion(log logging.SimpleLogging, v *version.Version) error } // AsyncTFExec brings the interface from TerraformClient into this package @@ -40,7 +40,7 @@ type AsyncTFExec interface { // Callers can use the input channel to pass stdin input to the command. // If any error is passed on the out channel, there will be no // further output (so callers are free to exit). - RunCommandAsync(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) + RunCommandAsync(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (chan<- string, <-chan terraform.Line) } // StatusUpdater brings the interface from CommitStatusUpdater into this package diff --git a/server/events/runtime/show_step_runner_test.go b/server/events/runtime/show_step_runner_test.go index 977530278..72250d3a0 100644 --- a/server/events/runtime/show_step_runner_test.go +++ b/server/events/runtime/show_step_runner_test.go @@ -15,7 +15,7 @@ import ( ) func TestShowStepRunnner(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) path, _ := ioutil.TempDir("", "") resultPath := filepath.Join(path, "test-default.json") envs := map[string]string{"key": "val"} diff --git a/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791b..cf9bb5453 100644 --- a/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/terraform/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/terraform/mocks/mock_terraform_client.go b/server/events/terraform/mocks/mock_terraform_client.go index 329e849eb..b92077775 100644 --- a/server/events/terraform/mocks/mock_terraform_client.go +++ b/server/events/terraform/mocks/mock_terraform_client.go @@ -26,7 +26,7 @@ func NewMockClient(options ...pegomock.Option) *MockClient { func (mock *MockClient) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockClient) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) (string, error) { +func (mock *MockClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) (string, error) { if mock == nil { panic("mock must not be nil. Use myMock := NewMockClient().") } @@ -45,7 +45,7 @@ func (mock *MockClient) RunCommandWithVersion(log *logging.SimpleLogger, path st return ret0, ret1 } -func (mock *MockClient) EnsureVersion(log *logging.SimpleLogger, v *go_version.Version) error { +func (mock *MockClient) EnsureVersion(log logging.SimpleLogging, v *go_version.Version) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockClient().") } @@ -97,7 +97,7 @@ type VerifierMockClient struct { timeout time.Duration } -func (verifier *VerifierMockClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) *MockClient_RunCommandWithVersion_OngoingVerification { +func (verifier *VerifierMockClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *go_version.Version, workspace string) *MockClient_RunCommandWithVersion_OngoingVerification { params := []pegomock.Param{log, path, args, envs, v, workspace} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "RunCommandWithVersion", params, verifier.timeout) return &MockClient_RunCommandWithVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -108,17 +108,17 @@ type MockClient_RunCommandWithVersion_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, string, []string, map[string]string, *go_version.Version, string) { +func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, string, []string, map[string]string, *go_version.Version, string) { log, path, args, envs, v, workspace := c.GetAllCapturedArguments() return log[len(log)-1], path[len(path)-1], args[len(args)-1], envs[len(envs)-1], v[len(v)-1], workspace[len(workspace)-1] } -func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []string, _param2 [][]string, _param3 []map[string]string, _param4 []*go_version.Version, _param5 []string) { +func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []string, _param2 [][]string, _param3 []map[string]string, _param4 []*go_version.Version, _param5 []string) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]string, len(c.methodInvocations)) for u, param := range params[1] { @@ -144,7 +144,7 @@ func (c *MockClient_RunCommandWithVersion_OngoingVerification) GetAllCapturedArg return } -func (verifier *VerifierMockClient) EnsureVersion(log *logging.SimpleLogger, v *go_version.Version) *MockClient_EnsureVersion_OngoingVerification { +func (verifier *VerifierMockClient) EnsureVersion(log logging.SimpleLogging, v *go_version.Version) *MockClient_EnsureVersion_OngoingVerification { params := []pegomock.Param{log, v} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "EnsureVersion", params, verifier.timeout) return &MockClient_EnsureVersion_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -155,17 +155,17 @@ type MockClient_EnsureVersion_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockClient_EnsureVersion_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, *go_version.Version) { +func (c *MockClient_EnsureVersion_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, *go_version.Version) { log, v := c.GetAllCapturedArguments() return log[len(log)-1], v[len(v)-1] } -func (c *MockClient_EnsureVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []*go_version.Version) { +func (c *MockClient_EnsureVersion_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []*go_version.Version) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]*go_version.Version, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/terraform/terraform_client.go b/server/events/terraform/terraform_client.go index 4f0310ec8..023ba731b 100644 --- a/server/events/terraform/terraform_client.go +++ b/server/events/terraform/terraform_client.go @@ -40,10 +40,10 @@ type Client interface { // RunCommandWithVersion executes terraform with args in path. If v is nil, // it will use the default Terraform version. workspace is the Terraform // workspace which should be set as an environment variable. - RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) + RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, envs map[string]string, v *version.Version, workspace string) (string, error) // EnsureVersion makes sure that terraform version `v` is available to use - EnsureVersion(log *logging.SimpleLogger, v *version.Version) error + EnsureVersion(log logging.SimpleLogging, v *version.Version) error } type DefaultClient struct { @@ -97,7 +97,7 @@ var versionRegex = regexp.MustCompile("Terraform v(.*?)(\\s.*)?\n") // tfDownloader is used to download terraform versions. // Will asynchronously download the required version if it doesn't exist already. func NewClient( - log *logging.SimpleLogger, + log logging.SimpleLogging, binDir string, cacheDir string, tfeToken string, @@ -182,7 +182,7 @@ func (c *DefaultClient) TerraformBinDir() string { } // See Client.EnsureVersion. -func (c *DefaultClient) EnsureVersion(log *logging.SimpleLogger, v *version.Version) error { +func (c *DefaultClient) EnsureVersion(log logging.SimpleLogging, v *version.Version) error { if v == nil { v = c.defaultVersion } @@ -199,7 +199,7 @@ func (c *DefaultClient) EnsureVersion(log *logging.SimpleLogger, v *version.Vers } // See Client.RunCommandWithVersion. -func (c *DefaultClient) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (string, error) { +func (c *DefaultClient) RunCommandWithVersion(log logging.SimpleLogging, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (string, error) { tfCmd, cmd, err := c.prepCmd(log, v, workspace, path, args) if err != nil { return "", err @@ -222,7 +222,7 @@ func (c *DefaultClient) RunCommandWithVersion(log *logging.SimpleLogger, path st // prepCmd builds a ready to execute command based on the version of terraform // v, and args. It returns a printable representation of the command that will // be run and the actual command. -func (c *DefaultClient) prepCmd(log *logging.SimpleLogger, v *version.Version, workspace string, path string, args []string) (string, *exec.Cmd, error) { +func (c *DefaultClient) prepCmd(log logging.SimpleLogging, v *version.Version, workspace string, path string, args []string) (string, *exec.Cmd, error) { if v == nil { v = c.defaultVersion } @@ -279,7 +279,7 @@ type Line struct { // Callers can use the input channel to pass stdin input to the command. // If any error is passed on the out channel, there will be no // further output (so callers are free to exit). -func (c *DefaultClient) RunCommandAsync(log *logging.SimpleLogger, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (chan<- string, <-chan Line) { +func (c *DefaultClient) RunCommandAsync(log logging.SimpleLogging, path string, args []string, customEnvVars map[string]string, v *version.Version, workspace string) (chan<- string, <-chan Line) { outCh := make(chan Line) inCh := make(chan string) @@ -382,7 +382,7 @@ func MustConstraint(v string) version.Constraints { // ensureVersion returns the path to a terraform binary of version v. // It will download this version if we don't have it. -func ensureVersion(log *logging.SimpleLogger, dl Downloader, versions map[string]string, v *version.Version, binDir string, downloadURL string) (string, error) { +func ensureVersion(log logging.SimpleLogging, dl Downloader, versions map[string]string, v *version.Version, binDir string, downloadURL string) (string, error) { if binPath, ok := versions[v.String()]; ok { return binPath, nil } diff --git a/server/events/terraform/terraform_client_internal_test.go b/server/events/terraform/terraform_client_internal_test.go index b2504f650..8a447fb82 100644 --- a/server/events/terraform/terraform_client_internal_test.go +++ b/server/events/terraform/terraform_client_internal_test.go @@ -104,7 +104,8 @@ func TestDefaultClient_RunCommandWithVersion_EnvVars(t *testing.T) { "ATLANTIS_TERRAFORM_VERSION=$ATLANTIS_TERRAFORM_VERSION", "DIR=$DIR", } - out, err := client.RunCommandWithVersion(nil, tmp, args, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + out, err := client.RunCommandWithVersion(log, tmp, args, map[string]string{}, nil, "workspace") Ok(t, err) exp := fmt.Sprintf("TF_IN_AUTOMATION=true TF_PLUGIN_CACHE_DIR=%s WORKSPACE=workspace ATLANTIS_TERRAFORM_VERSION=0.11.11 DIR=%s\n", tmp, tmp) Equals(t, exp, out) @@ -128,7 +129,7 @@ func TestDefaultClient_RunCommandWithVersion_Error(t *testing.T) { "exit", "1", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) out, err := client.RunCommandWithVersion(log, tmp, args, map[string]string{}, nil, "workspace") ErrEquals(t, fmt.Sprintf(`running "echo dying && exit 1" in %q: exit status 1`, tmp), err) // Test that we still get our output. @@ -154,7 +155,8 @@ func TestDefaultClient_RunCommandAsync_Success(t *testing.T) { "ATLANTIS_TERRAFORM_VERSION=$ATLANTIS_TERRAFORM_VERSION", "DIR=$DIR", } - _, outCh := client.RunCommandAsync(nil, tmp, args, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + _, outCh := client.RunCommandAsync(log, tmp, args, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) Ok(t, err) @@ -183,7 +185,8 @@ func TestDefaultClient_RunCommandAsync_BigOutput(t *testing.T) { _, err = f.WriteString(s) Ok(t, err) } - _, outCh := client.RunCommandAsync(nil, tmp, []string{filename}, map[string]string{}, nil, "workspace") + log := logging.NewNoopLogger(t) + _, outCh := client.RunCommandAsync(log, tmp, []string{filename}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) Ok(t, err) @@ -200,7 +203,7 @@ func TestDefaultClient_RunCommandAsync_StderrOutput(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "echo", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) _, outCh := client.RunCommandAsync(log, tmp, []string{"stderr", ">&2"}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) @@ -218,7 +221,7 @@ func TestDefaultClient_RunCommandAsync_ExitOne(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "echo", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) _, outCh := client.RunCommandAsync(log, tmp, []string{"dying", "&&", "exit", "1"}, map[string]string{}, nil, "workspace") out, err := waitCh(outCh) @@ -237,7 +240,7 @@ func TestDefaultClient_RunCommandAsync_Input(t *testing.T) { terraformPluginCacheDir: tmp, overrideTF: "read", } - log := logging.NewSimpleLogger("test", false, logging.Debug) + log := logging.NewNoopLogger(t) inCh, outCh := client.RunCommandAsync(log, tmp, []string{"a", "&&", "echo", "$a"}, map[string]string{}, nil, "workspace") inCh <- "echo me\n" diff --git a/server/events/terraform/terraform_client_test.go b/server/events/terraform/terraform_client_test.go index 4b0f7ea0b..574e50698 100644 --- a/server/events/terraform/terraform_client_test.go +++ b/server/events/terraform/terraform_client_test.go @@ -62,19 +62,21 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() + logger := logging.NewNoopLogger(t) + // We're testing this by adding our own "fake" terraform binary to path that // outputs what would normally come from terraform version. err := ioutil.WriteFile(filepath.Join(tmp, "terraform"), []byte(fmt.Sprintf("#!/bin/sh\necho '%s'", fakeBinOut)), 0755) Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{"test": "123"}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{"test": "123"}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -87,6 +89,7 @@ func TestNewClient_LocalTFMatchesFlag(t *testing.T) { Your version of Terraform is out of date! The latest version is 0.11.13. You can update by downloading from www.terraform.io/downloads.html ` + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -96,13 +99,13 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -110,13 +113,14 @@ is 0.11.13. You can update by downloading from www.terraform.io/downloads.html // Test that if terraform is not in PATH and we didn't set the default-tf flag // that we error. func TestNewClient_NoTF(t *testing.T) { + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() // Set PATH to only include our empty directory. defer tempSetEnv(t, "PATH", tmp)() - _, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + _, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) ErrEquals(t, "terraform not found in $PATH. Set --default-tf-version or download terraform from https://www.terraform.io/downloads.html", err) } @@ -124,6 +128,7 @@ func TestNewClient_NoTF(t *testing.T) { // that we use it. func TestNewClient_DefaultTFFlagInPath(t *testing.T) { fakeBinOut := "Terraform v0.11.10\n" + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -133,13 +138,13 @@ func TestNewClient_DefaultTFFlagInPath(t *testing.T) { Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -148,6 +153,7 @@ func TestNewClient_DefaultTFFlagInPath(t *testing.T) { // bin dir that we use it. func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { fakeBinOut := "Terraform v0.11.10\n" + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -156,13 +162,13 @@ func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { Ok(t, err) defer tempSetEnv(t, "PATH", fmt.Sprintf("%s:%s", tmp, os.Getenv("PATH")))() - c, err := terraform.NewClient(logging.NewNoopLogger(), binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + c, err := terraform.NewClient(logging.NewNoopLogger(t), binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) Ok(t, err) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, fakeBinOut+"\n", output) } @@ -170,6 +176,7 @@ func TestNewClient_DefaultTFFlagInBinDir(t *testing.T) { // Test that if we don't have that version of TF that we download it. func TestNewClient_DefaultTFFlagDownload(t *testing.T) { RegisterMockTestingT(t) + logger := logging.NewNoopLogger(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -182,7 +189,7 @@ func TestNewClient_DefaultTFFlagDownload(t *testing.T) { err := ioutil.WriteFile(params[0].(string), []byte("#!/bin/sh\necho '\nTerraform v0.11.10\n'"), 0755) return []pegomock.ReturnValue{err} }) - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, "https://my-mirror.releases.mycompany.com", mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, "https://my-mirror.releases.mycompany.com", mockDownloader, true) Ok(t, err) Ok(t, err) @@ -197,21 +204,23 @@ func TestNewClient_DefaultTFFlagDownload(t *testing.T) { // Reset PATH so that it has sh. Ok(t, os.Setenv("PATH", orig)) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, nil, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, nil, "") Ok(t, err) Equals(t, "\nTerraform v0.11.10\n\n", output) } // Test that we get an error if the terraform version flag is malformed. func TestNewClient_BadVersion(t *testing.T) { + logger := logging.NewNoopLogger(t) _, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() - _, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "malformed", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) + _, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "malformed", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, nil, true) ErrEquals(t, "Malformed version: malformed", err) } // Test that if we run a command with a version we don't have, we download it. func TestRunCommandWithVersion_DLsTF(t *testing.T) { + logger := logging.NewNoopLogger(t) RegisterMockTestingT(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() @@ -229,26 +238,27 @@ func TestRunCommandWithVersion_DLsTF(t *testing.T) { return []pegomock.ReturnValue{err} }) - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) v, err := version.NewVersion("99.99.99") Ok(t, err) - output, err := c.RunCommandWithVersion(nil, tmp, nil, map[string]string{}, v, "") + output, err := c.RunCommandWithVersion(logger, tmp, nil, map[string]string{}, v, "") Assert(t, err == nil, "err: %s: %s", err, output) Equals(t, "\nTerraform v99.99.99\n\n", output) } // Test the EnsureVersion downloads terraform. func TestEnsureVersion_downloaded(t *testing.T) { + logger := logging.NewNoopLogger(t) RegisterMockTestingT(t) tmp, binDir, cacheDir, cleanup := mkSubDirs(t) defer cleanup() mockDownloader := mocks.NewMockDownloader() - c, err := terraform.NewClient(nil, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) + c, err := terraform.NewClient(logger, binDir, cacheDir, "", "", "0.11.10", cmd.DefaultTFVersionFlag, cmd.DefaultTFDownloadURL, mockDownloader, true) Ok(t, err) Equals(t, "0.11.10", c.DefaultVersion().String()) @@ -256,7 +266,7 @@ func TestEnsureVersion_downloaded(t *testing.T) { v, err := version.NewVersion("99.99.99") Ok(t, err) - err = c.EnsureVersion(nil, v) + err = c.EnsureVersion(logger, v) Ok(t, err) diff --git a/server/events/vcs/github_client.go b/server/events/vcs/github_client.go index a0b1db6a4..20d3ab1ae 100644 --- a/server/events/vcs/github_client.go +++ b/server/events/vcs/github_client.go @@ -41,7 +41,7 @@ type GithubClient struct { client *github.Client v4MutateClient *graphql.Client ctx context.Context - logger *logging.SimpleLogger + logger logging.SimpleLogging } // GithubAppTemporarySecrets holds app credentials obtained from github after creation. @@ -59,7 +59,7 @@ type GithubAppTemporarySecrets struct { } // NewGithubClient returns a valid GitHub client. -func NewGithubClient(hostname string, credentials GithubCredentials, logger *logging.SimpleLogger) (*GithubClient, error) { +func NewGithubClient(hostname string, credentials GithubCredentials, logger logging.SimpleLogging) (*GithubClient, error) { transport, err := credentials.Client() if err != nil { return nil, errors.Wrap(err, "error initializing github authentication transport") diff --git a/server/events/vcs/github_client_internal_test.go b/server/events/vcs/github_client_internal_test.go index 81b0185ac..ebe039d31 100644 --- a/server/events/vcs/github_client_internal_test.go +++ b/server/events/vcs/github_client_internal_test.go @@ -16,19 +16,20 @@ package vcs import ( "testing" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) // If the hostname is github.com, should use normal BaseURL. func TestNewGithubClient_GithubCom(t *testing.T) { - client, err := NewGithubClient("github.com", &GithubUserCredentials{"user", "pass"}, nil) + client, err := NewGithubClient("github.com", &GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) Equals(t, "https://api.github.com/", client.client.BaseURL.String()) } // If the hostname is a non-github hostname should use the right BaseURL. func TestNewGithubClient_NonGithub(t *testing.T) { - client, err := NewGithubClient("example.com", &GithubUserCredentials{"user", "pass"}, nil) + client, err := NewGithubClient("example.com", &GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) Equals(t, "https://example.com/api/v3/", client.client.BaseURL.String()) // If possible in the future, test the GraphQL client's URL as well. But at the diff --git a/server/events/vcs/github_client_test.go b/server/events/vcs/github_client_test.go index dc56d7996..70d719704 100644 --- a/server/events/vcs/github_client_test.go +++ b/server/events/vcs/github_client_test.go @@ -13,6 +13,7 @@ import ( "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/events/vcs" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" "github.com/shurcooL/githubv4" @@ -21,6 +22,7 @@ import ( // GetModifiedFiles should make multiple requests if more than one page // and concat results. func TestGithubClient_GetModifiedFiles(t *testing.T) { + logger := logging.NewNoopLogger(t) respTemplate := `[ { "sha": "bbcd538c8e72b8c175046e27cc8f907076331401", @@ -59,7 +61,7 @@ func TestGithubClient_GetModifiedFiles(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logger) Ok(t, err) defer disableSSLVerification()() @@ -114,7 +116,7 @@ func TestGithubClient_GetModifiedFilesMovedFile(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -208,7 +210,7 @@ func TestGithubClient_PaginatesComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -296,7 +298,7 @@ func TestGithubClient_HideOldComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -361,7 +363,7 @@ func TestGithubClient_UpdateStatus(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -447,7 +449,7 @@ func TestGithubClient_PullIsApproved(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -538,7 +540,7 @@ func TestGithubClient_PullIsMergeable(t *testing.T) { })) testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -620,7 +622,7 @@ func TestGithubClient_MergePullHandlesError(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -741,7 +743,7 @@ func TestGithubClient_MergePullCorrectMethod(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() @@ -766,7 +768,7 @@ func TestGithubClient_MergePullCorrectMethod(t *testing.T) { } func TestGithubClient_MarkdownPullLink(t *testing.T) { - client, err := vcs.NewGithubClient("hostname", &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient("hostname", &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) pull := models.PullRequest{Num: 1} s, _ := client.MarkdownPullLink(pull) @@ -821,7 +823,7 @@ func TestGithubClient_SplitComments(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() pull := models.PullRequest{Num: 1} @@ -879,7 +881,7 @@ func TestGithubClient_Retry404(t *testing.T) { testServerURL, err := url.Parse(testServer.URL) Ok(t, err) - client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, nil) + client, err := vcs.NewGithubClient(testServerURL.Host, &vcs.GithubUserCredentials{"user", "pass"}, logging.NewNoopLogger(t)) Ok(t, err) defer disableSSLVerification()() repo := models.Repo{ diff --git a/server/events/vcs/github_credentials_test.go b/server/events/vcs/github_credentials_test.go index c643c9706..7de0c98f4 100644 --- a/server/events/vcs/github_credentials_test.go +++ b/server/events/vcs/github_credentials_test.go @@ -6,6 +6,7 @@ import ( "github.com/runatlantis/atlantis/server/events/vcs" "github.com/runatlantis/atlantis/server/events/vcs/fixtures" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -15,7 +16,7 @@ func TestGithubClient_GetUser_AppSlug(t *testing.T) { Ok(t, err) anonCreds := &vcs.GithubAnonymousCredentials{} - anonClient, err := vcs.NewGithubClient(testServer, anonCreds, nil) + anonClient, err := vcs.NewGithubClient(testServer, anonCreds, logging.NewNoopLogger(t)) Ok(t, err) tempSecrets, err := anonClient.ExchangeCode("good-code") Ok(t, err) @@ -45,7 +46,7 @@ func TestGithubClient_AppAuthentication(t *testing.T) { Ok(t, err) anonCreds := &vcs.GithubAnonymousCredentials{} - anonClient, err := vcs.NewGithubClient(testServer, anonCreds, nil) + anonClient, err := vcs.NewGithubClient(testServer, anonCreds, logging.NewNoopLogger(t)) Ok(t, err) tempSecrets, err := anonClient.ExchangeCode("good-code") Ok(t, err) @@ -61,7 +62,7 @@ func TestGithubClient_AppAuthentication(t *testing.T) { KeyPath: keyPath, Hostname: testServer, } - _, err = vcs.NewGithubClient(testServer, appCreds, nil) + _, err = vcs.NewGithubClient(testServer, appCreds, logging.NewNoopLogger(t)) Ok(t, err) token, err := appCreds.GetToken() diff --git a/server/events/vcs/gitlab_client.go b/server/events/vcs/gitlab_client.go index b991eaba3..9cb320f4b 100644 --- a/server/events/vcs/gitlab_client.go +++ b/server/events/vcs/gitlab_client.go @@ -47,7 +47,7 @@ var commonMarkSupported = MustConstraint(">=11.1") var gitlabClientUnderTest = false // NewGitlabClient returns a valid GitLab client. -func NewGitlabClient(hostname string, token string, logger *logging.SimpleLogger) (*GitlabClient, error) { +func NewGitlabClient(hostname string, token string, logger logging.SimpleLogging) (*GitlabClient, error) { client := &GitlabClient{} // Create the client differently depending on the base URL. diff --git a/server/events/vcs/gitlab_client_test.go b/server/events/vcs/gitlab_client_test.go index 7e9b10abe..bb0002381 100644 --- a/server/events/vcs/gitlab_client_test.go +++ b/server/events/vcs/gitlab_client_test.go @@ -9,6 +9,7 @@ import ( version "github.com/hashicorp/go-version" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" gitlab "github.com/xanzy/go-gitlab" . "github.com/runatlantis/atlantis/testing" @@ -54,7 +55,8 @@ func TestNewGitlabClient_BaseURL(t *testing.T) { for _, c := range cases { t.Run(c.Hostname, func(t *testing.T) { - client, err := NewGitlabClient(c.Hostname, "token", nil) + log := logging.NewNoopLogger(t) + client, err := NewGitlabClient(c.Hostname, "token", log) Ok(t, err) Equals(t, c.ExpBaseURL, client.Client.BaseURL().String()) }) diff --git a/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go b/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go index 0ce4a1c74..ddb778473 100644 --- a/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/events/webhooks/mocks/matchers/ptr_to_logging_simplelogger.go @@ -8,26 +8,26 @@ import ( logging "github.com/runatlantis/atlantis/server/logging" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } -func NotEqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func NotEqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } -func PtrToLoggingSimpleLoggerThat(matcher pegomock.ArgumentMatcher) *logging.SimpleLogger { +func PtrToLoggingSimpleLoggerThat(matcher pegomock.ArgumentMatcher) logging.SimpleLogging { pegomock.RegisterMatcher(matcher) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/events/webhooks/mocks/mock_sender.go b/server/events/webhooks/mocks/mock_sender.go index 90f849534..680ab6dce 100644 --- a/server/events/webhooks/mocks/mock_sender.go +++ b/server/events/webhooks/mocks/mock_sender.go @@ -26,7 +26,7 @@ func NewMockSender(options ...pegomock.Option) *MockSender { func (mock *MockSender) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh } func (mock *MockSender) FailHandler() pegomock.FailHandler { return mock.fail } -func (mock *MockSender) Send(log *logging.SimpleLogger, applyResult webhooks.ApplyResult) error { +func (mock *MockSender) Send(log logging.SimpleLogging, applyResult webhooks.ApplyResult) error { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSender().") } @@ -78,7 +78,7 @@ type VerifierMockSender struct { timeout time.Duration } -func (verifier *VerifierMockSender) Send(log *logging.SimpleLogger, applyResult webhooks.ApplyResult) *MockSender_Send_OngoingVerification { +func (verifier *VerifierMockSender) Send(log logging.SimpleLogging, applyResult webhooks.ApplyResult) *MockSender_Send_OngoingVerification { params := []pegomock.Param{log, applyResult} methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Send", params, verifier.timeout) return &MockSender_Send_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} @@ -89,17 +89,17 @@ type MockSender_Send_OngoingVerification struct { methodInvocations []pegomock.MethodInvocation } -func (c *MockSender_Send_OngoingVerification) GetCapturedArguments() (*logging.SimpleLogger, webhooks.ApplyResult) { +func (c *MockSender_Send_OngoingVerification) GetCapturedArguments() (logging.SimpleLogging, webhooks.ApplyResult) { log, applyResult := c.GetAllCapturedArguments() return log[len(log)-1], applyResult[len(applyResult)-1] } -func (c *MockSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []*logging.SimpleLogger, _param1 []webhooks.ApplyResult) { +func (c *MockSender_Send_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.SimpleLogging, _param1 []webhooks.ApplyResult) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]*logging.SimpleLogger, len(c.methodInvocations)) + _param0 = make([]logging.SimpleLogging, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(*logging.SimpleLogger) + _param0[u] = param.(logging.SimpleLogging) } _param1 = make([]webhooks.ApplyResult, len(c.methodInvocations)) for u, param := range params[1] { diff --git a/server/events/webhooks/slack.go b/server/events/webhooks/slack.go index 7e943c1ef..23ac3a0db 100644 --- a/server/events/webhooks/slack.go +++ b/server/events/webhooks/slack.go @@ -50,7 +50,7 @@ func NewSlack(r *regexp.Regexp, channel string, client SlackClient) (*SlackWebho } // Send sends the webhook to Slack if the workspace matches the regex. -func (s *SlackWebhook) Send(log *logging.SimpleLogger, applyResult ApplyResult) error { +func (s *SlackWebhook) Send(log logging.SimpleLogging, applyResult ApplyResult) error { if !s.WorkspaceRegex.MatchString(applyResult.Workspace) { return nil } diff --git a/server/events/webhooks/slack_test.go b/server/events/webhooks/slack_test.go index fbb89f931..096aabbf8 100644 --- a/server/events/webhooks/slack_test.go +++ b/server/events/webhooks/slack_test.go @@ -42,7 +42,7 @@ func TestSend_PostMessage(t *testing.T) { } t.Log("PostMessage should be called, doesn't matter if it errors or not") - _ = hook.Send(logging.NewNoopLogger(), result) + _ = hook.Send(logging.NewNoopLogger(t), result) client.VerifyWasCalledOnce().PostMessage(channel, result) } @@ -62,7 +62,7 @@ func TestSend_NoopSuccess(t *testing.T) { result := webhooks.ApplyResult{ Workspace: "production", } - err = hook.Send(logging.NewNoopLogger(), result) + err = hook.Send(logging.NewNoopLogger(t), result) Ok(t, err) client.VerifyWasCalled(Never()).PostMessage(channel, result) } diff --git a/server/events/webhooks/webhooks.go b/server/events/webhooks/webhooks.go index dacc267e3..b64001f46 100644 --- a/server/events/webhooks/webhooks.go +++ b/server/events/webhooks/webhooks.go @@ -31,7 +31,7 @@ const ApplyEvent = "apply" // Sender sends webhooks. type Sender interface { // Send sends the webhook (if the implementation thinks it should). - Send(log *logging.SimpleLogger, applyResult ApplyResult) error + Send(log logging.SimpleLogging, applyResult ApplyResult) error } // ApplyResult is the result of a terraform apply. @@ -93,7 +93,7 @@ func NewMultiWebhookSender(configs []Config, client SlackClient) (*MultiWebhookS } // Send sends the webhook using its Webhooks. -func (w *MultiWebhookSender) Send(log *logging.SimpleLogger, result ApplyResult) error { +func (w *MultiWebhookSender) Send(log logging.SimpleLogging, result ApplyResult) error { for _, w := range w.Webhooks { if err := w.Send(log, result); err != nil { log.Warn("error sending slack webhook: %s", err) diff --git a/server/events/webhooks/webhooks_test.go b/server/events/webhooks/webhooks_test.go index 4cd263cd3..0be80faaa 100644 --- a/server/events/webhooks/webhooks_test.go +++ b/server/events/webhooks/webhooks_test.go @@ -161,7 +161,7 @@ func TestSend_SingleSuccess(t *testing.T) { manager := webhooks.MultiWebhookSender{ Webhooks: []webhooks.Sender{sender}, } - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) result := webhooks.ApplyResult{} manager.Send(logger, result) // nolint: errcheck sender.VerifyWasCalledOnce().Send(logger, result) @@ -178,7 +178,7 @@ func TestSend_MultipleSuccess(t *testing.T) { manager := webhooks.MultiWebhookSender{ Webhooks: []webhooks.Sender{senders[0], senders[1], senders[2]}, } - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) result := webhooks.ApplyResult{} err := manager.Send(logger, result) Ok(t, err) diff --git a/server/events/working_dir.go b/server/events/working_dir.go index 77125b177..967042391 100644 --- a/server/events/working_dir.go +++ b/server/events/working_dir.go @@ -37,7 +37,7 @@ type WorkingDir interface { // absolute path to the root of the cloned repo. It also returns // a boolean indicating if we should warn users that the branch we're // merging into has been updated since we cloned it. - Clone(log *logging.SimpleLogger, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) + Clone(log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) // GetWorkingDir returns the path to the workspace for this repo and pull. // If workspace does not exist on disk, error will be of type os.IsNotExist. GetWorkingDir(r models.Repo, p models.PullRequest, workspace string) (string, error) @@ -71,7 +71,7 @@ type FileWorkspace struct { // the right commit it does nothing. This is to support running commands in // multiple dirs of the same repo without deleting existing plans. func (w *FileWorkspace) Clone( - log *logging.SimpleLogger, + log logging.SimpleLogging, headRepo models.Repo, p models.PullRequest, workspace string) (string, bool, error) { @@ -122,7 +122,7 @@ func (w *FileWorkspace) Clone( // Then users won't be getting the merge functionality they expected. // If there are any errors we return false since we prefer things to succeed // vs. stopping the plan/apply. -func (w *FileWorkspace) warnDiverged(log *logging.SimpleLogger, p models.PullRequest, headRepo models.Repo, cloneDir string) bool { +func (w *FileWorkspace) warnDiverged(log logging.SimpleLogging, p models.PullRequest, headRepo models.Repo, cloneDir string) bool { if !w.CheckoutMerge { // It only makes sense to warn that master has diverged if we're using // the checkout merge strategy. If we're just checking out the branch, @@ -177,7 +177,7 @@ func (w *FileWorkspace) warnDiverged(log *logging.SimpleLogger, p models.PullReq return hasDiverged } -func (w *FileWorkspace) forceClone(log *logging.SimpleLogger, +func (w *FileWorkspace) forceClone(log logging.SimpleLogging, cloneDir string, headRepo models.Repo, p models.PullRequest) error { diff --git a/server/events/working_dir_test.go b/server/events/working_dir_test.go index be003ae92..1185e4c9f 100644 --- a/server/events/working_dir_test.go +++ b/server/events/working_dir_test.go @@ -10,6 +10,7 @@ import ( "github.com/runatlantis/atlantis/server/events" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" . "github.com/runatlantis/atlantis/testing" ) @@ -40,7 +41,7 @@ func TestClone_NoneExisting(t *testing.T) { TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, _, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, _, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -90,7 +91,7 @@ func TestClone_CheckoutMergeNoneExisting(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -139,7 +140,7 @@ func TestClone_CheckoutMergeNoReclone(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -151,7 +152,7 @@ func TestClone_CheckoutMergeNoReclone(t *testing.T) { runCmd(t, dataDir, "touch", "repos/0/default/proof") // Now run the clone again. - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -189,7 +190,7 @@ func TestClone_CheckoutMergeNoRecloneFastForward(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -201,7 +202,7 @@ func TestClone_CheckoutMergeNoRecloneFastForward(t *testing.T) { runCmd(t, dataDir, "touch", "repos/0/default/proof") // Now run the clone again. - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -244,7 +245,7 @@ func TestClone_CheckoutMergeConflict(t *testing.T) { TestingOverrideBaseCloneURL: overrideURL, } - _, _, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, _, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", BaseBranch: "master", @@ -275,7 +276,7 @@ func TestClone_NoReclone(t *testing.T) { CheckoutMerge: false, TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", }, "default") @@ -311,7 +312,7 @@ func TestClone_RecloneWrongCommit(t *testing.T) { CheckoutMerge: false, TestingOverrideHeadCloneURL: fmt.Sprintf("file://%s", repoDir), } - cloneDir, hasDiverged, err := wd.Clone(nil, models.Repo{}, models.PullRequest{ + cloneDir, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "branch", HeadCommit: expCommit, @@ -377,7 +378,7 @@ func TestClone_MasterHasDiverged(t *testing.T) { DataDir: repoDir, CheckoutMerge: true, } - _, hasDiverged, err := wd.Clone(nil, models.Repo{CloneURL: repoDir}, models.PullRequest{ + _, hasDiverged, err := wd.Clone(logging.NewNoopLogger(t), models.Repo{CloneURL: repoDir}, models.PullRequest{ BaseRepo: models.Repo{CloneURL: repoDir}, HeadBranch: "second-pr", BaseBranch: "master", @@ -388,7 +389,7 @@ func TestClone_MasterHasDiverged(t *testing.T) { // Run it again but without the checkout merge strategy. It should return // false. wd.CheckoutMerge = false - _, hasDiverged, err = wd.Clone(nil, models.Repo{}, models.PullRequest{ + _, hasDiverged, err = wd.Clone(logging.NewNoopLogger(t), models.Repo{}, models.PullRequest{ BaseRepo: models.Repo{}, HeadBranch: "second-pr", BaseBranch: "master", diff --git a/server/events/yaml/valid/global_cfg_test.go b/server/events/yaml/valid/global_cfg_test.go index 5fbf759ce..95d04358d 100644 --- a/server/events/yaml/valid/global_cfg_test.go +++ b/server/events/yaml/valid/global_cfg_test.go @@ -551,7 +551,7 @@ policies: Equals(t, c.exp, - global.MergeProjectCfg(logging.NewNoopLogger(), c.repoID, c.proj, valid.RepoCfg{})) + global.MergeProjectCfg(logging.NewNoopLogger(t), c.repoID, c.proj, valid.RepoCfg{})) }) } } @@ -709,7 +709,7 @@ repos: } global.PolicySets = emptyPolicySets - Equals(t, c.exp, global.MergeProjectCfg(logging.NewNoopLogger(), c.repoID, c.proj, valid.RepoCfg{Workflows: c.repoWorkflows})) + Equals(t, c.exp, global.MergeProjectCfg(logging.NewNoopLogger(t), c.repoID, c.proj, valid.RepoCfg{Workflows: c.repoWorkflows})) }) } } diff --git a/server/events_controller.go b/server/events_controller.go index de0859908..dc7f5c18a 100644 --- a/server/events_controller.go +++ b/server/events_controller.go @@ -47,7 +47,7 @@ const bitbucketServerSignatureHeader = "X-Hub-Signature" type EventsController struct { CommandRunner events.CommandRunner PullCleaner events.PullCleaner - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Parser events.EventParsing CommentParser events.CommentParsing ApplyDisabled bool diff --git a/server/events_controller_e2e_test.go b/server/events_controller_e2e_test.go index 181ec7ca7..7ee8fd649 100644 --- a/server/events_controller_e2e_test.go +++ b/server/events_controller_e2e_test.go @@ -630,7 +630,14 @@ func setupE2E(t *testing.T, repoDir string) (server.EventsController, *vcsmocks. e2eGitlabGetter := mocks.NewMockGitlabMergeRequestGetter() // Real dependencies. - logger := logging.NewSimpleLogger("server", true, logging.Error) + logger, err := logging.NewStructuredLogger() + + if err != nil { + panic("Could not setup logger for e2e") + } + + logger.SetLevel(logging.Error) + eventParser := &events.EventParser{ GithubUser: "github-user", GithubToken: "github-token", @@ -860,7 +867,7 @@ func (m *mockLockURLGenerator) GenerateLockURL(lockID string) string { type mockWebhookSender struct{} -func (w *mockWebhookSender) Send(log *logging.SimpleLogger, result webhooks.ApplyResult) error { +func (w *mockWebhookSender) Send(log logging.SimpleLogging, result webhooks.ApplyResult) error { return nil } diff --git a/server/events_controller_test.go b/server/events_controller_test.go index af24490eb..0b8ab903e 100644 --- a/server/events_controller_test.go +++ b/server/events_controller_test.go @@ -187,7 +187,7 @@ func TestPost_GitlabCommentNotAllowlisted(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), CommentParser: &events.CommentParser{}, GitlabRequestParserValidator: &server.DefaultGitlabRequestParserValidator{}, Parser: &events.EventParser{}, @@ -215,7 +215,7 @@ func TestPost_GitlabCommentNotAllowlistedWithSilenceErrors(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), CommentParser: &events.CommentParser{}, GitlabRequestParserValidator: &server.DefaultGitlabRequestParserValidator{}, Parser: &events.EventParser{}, @@ -244,7 +244,7 @@ func TestPost_GithubCommentNotAllowlisted(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: &server.DefaultGithubRequestValidator{}, CommentParser: &events.CommentParser{}, Parser: &events.EventParser{}, @@ -273,7 +273,7 @@ func TestPost_GithubCommentNotAllowlistedWithSilenceErrors(t *testing.T) { RegisterMockTestingT(t) vcsClient := vcsmocks.NewMockClient() e := server.EventsController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: &server.DefaultGithubRequestValidator{}, CommentParser: &events.CommentParser{}, Parser: &events.EventParser{}, @@ -471,7 +471,7 @@ func TestPost_AzureDevopsPullRequestIgnoreEvent(t *testing.T) { Ok(t, err) e := server.EventsController{ TestingMode: true, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyDisabled: false, AzureDevopsWebhookBasicUser: user, AzureDevopsWebhookBasicPassword: secret, @@ -635,6 +635,7 @@ func TestPost_BBServerPullClosed(t *testing.T) { RepoAllowlistChecker: allowlist, SupportedVCSHosts: []models.VCSHostType{models.BitbucketServer}, VCSClient: nil, + Logger: logging.NewNoopLogger(t), } // Build HTTP request. @@ -754,7 +755,7 @@ func setup(t *testing.T) (server.EventsController, *mocks.MockGithubRequestValid Ok(t, err) e := server.EventsController{ TestingMode: true, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), GithubRequestValidator: v, Parser: p, CommentParser: cp, diff --git a/server/github_app_controller.go b/server/github_app_controller.go index cd8b64e66..4fed5968d 100644 --- a/server/github_app_controller.go +++ b/server/github_app_controller.go @@ -13,7 +13,7 @@ import ( // GithubAppController handles the creation and setup of a new GitHub app type GithubAppController struct { AtlantisURL *url.URL - Logger *logging.SimpleLogger + Logger logging.SimpleLogging GithubSetupComplete bool GithubHostname string GithubOrg string diff --git a/server/locks_controller.go b/server/locks_controller.go index 66313dce0..8d7eebcfb 100644 --- a/server/locks_controller.go +++ b/server/locks_controller.go @@ -20,8 +20,8 @@ type LocksController struct { AtlantisVersion string AtlantisURL *url.URL Locker locking.Locker + Logger logging.SimpleLogging ApplyLocker locking.ApplyLocker - Logger *logging.SimpleLogger VCSClient vcs.Client LockDetailTemplate TemplateWriter WorkingDir events.WorkingDir diff --git a/server/locks_controller_test.go b/server/locks_controller_test.go index bdd0d5ae6..9ec5fb1f9 100644 --- a/server/locks_controller_test.go +++ b/server/locks_controller_test.go @@ -50,7 +50,7 @@ func TestCreateApplyLock(t *testing.T) { }, nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.LockApply(w, req) @@ -68,7 +68,7 @@ func TestCreateApplyLock(t *testing.T) { }, errors.New("failed to acquire lock")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.LockApply(w, req) @@ -86,7 +86,7 @@ func TestUnlockApply(t *testing.T) { When(l.UnlockApply()).ThenReturn(nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.UnlockApply(w, req) @@ -102,7 +102,7 @@ func TestUnlockApply(t *testing.T) { When(l.UnlockApply()).ThenReturn(errors.New("failed to delete lock")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), ApplyLocker: l, } lc.UnlockApply(w, req) @@ -116,7 +116,7 @@ func TestGetLockRoute_NoLockID(t *testing.T) { req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } lc.GetLock(w, req) responseContains(t, w, http.StatusBadRequest, "No lock id in request") @@ -125,7 +125,7 @@ func TestGetLockRoute_NoLockID(t *testing.T) { func TestGetLock_InvalidLockID(t *testing.T) { t.Log("If the lock ID is invalid then we should get a 400") lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "%A@"}) @@ -140,7 +140,7 @@ func TestGetLock_LockerErr(t *testing.T) { l := mocks.NewMockLocker() When(l.GetLock("id")).ThenReturn(nil, errors.New("err")) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -156,7 +156,7 @@ func TestGetLock_None(t *testing.T) { l := mocks.NewMockLocker() When(l.GetLock("id")).ThenReturn(nil, nil) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -179,7 +179,7 @@ func TestGetLock_Success(t *testing.T) { atlantisURL, err := url.Parse("https://example.com/basepath") Ok(t, err) lc := server.LocksController{ - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), Locker: l, LockDetailTemplate: tmpl, AtlantisVersion: "1300135", @@ -207,14 +207,14 @@ func TestDeleteLock_NoLockID(t *testing.T) { t.Log("If there is no lock ID in the request then we should get a 400") req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() - lc := server.LocksController{Logger: logging.NewNoopLogger()} + lc := server.LocksController{Logger: logging.NewNoopLogger(t)} lc.DeleteLock(w, req) responseContains(t, w, http.StatusBadRequest, "No lock id in request") } func TestDeleteLock_InvalidLockID(t *testing.T) { t.Log("If the lock ID is invalid then we should get a 400") - lc := server.LocksController{Logger: logging.NewNoopLogger()} + lc := server.LocksController{Logger: logging.NewNoopLogger(t)} req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "%A@"}) w := httptest.NewRecorder() @@ -229,7 +229,7 @@ func TestDeleteLock_LockerErr(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(nil, errors.New("err")) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "id"}) @@ -245,7 +245,7 @@ func TestDeleteLock_None(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(nil, nil) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) req = mux.SetURLVars(req, map[string]string{"id": "id"}) @@ -262,7 +262,7 @@ func TestDeleteLock_OldFormat(t *testing.T) { When(dlc.DeleteLock("id")).ThenReturn(&models.ProjectLock{}, nil) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) @@ -315,7 +315,7 @@ func TestDeleteLock_UpdateProjectStatus(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: l, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, WorkingDirLocker: workingDirLocker, WorkingDir: workingDir, @@ -357,7 +357,7 @@ func TestDeleteLock_CommentFailed(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, WorkingDir: workingDir, WorkingDirLocker: workingDirLocker, @@ -394,7 +394,7 @@ func TestDeleteLock_CommentSuccess(t *testing.T) { Ok(t, err) lc := server.LocksController{ DeleteLockCommand: dlc, - Logger: logging.NewNoopLogger(), + Logger: logging.NewNoopLogger(t), VCSClient: cp, DB: db, WorkingDir: workingDir, diff --git a/server/logging/logging_test.go b/server/logging/logging_test.go index 8f7b67e2d..237d1d8b6 100644 --- a/server/logging/logging_test.go +++ b/server/logging/logging_test.go @@ -13,4 +13,22 @@ package logging_test -// purposefully empty to trigger coverage report +import ( + "testing" + + "github.com/runatlantis/atlantis/server/logging" + "github.com/stretchr/testify/assert" +) + +func TestStructuredLoggerSavesHistory(t *testing.T) { + logger := logging.NewNoopLogger(t) + + historyLogger := logger.WithHistory() + + expectedStr := "[DBUG] Hello World\n[INFO] foo bar\n" + + historyLogger.Debug("Hello World") + historyLogger.Info("foo bar") + + assert.Equal(t, expectedStr, historyLogger.GetHistory()) +} diff --git a/server/logging/mocks/matchers/logging_loglevel.go b/server/logging/mocks/matchers/logging_loglevel.go index 660a3cc43..bba8254e7 100644 --- a/server/logging/mocks/matchers/logging_loglevel.go +++ b/server/logging/mocks/matchers/logging_loglevel.go @@ -2,8 +2,9 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" + "reflect" + logging "github.com/runatlantis/atlantis/server/logging" ) @@ -18,3 +19,15 @@ func EqLoggingLogLevel(value logging.LogLevel) logging.LogLevel { var nullValue logging.LogLevel return nullValue } + +func NotEqLoggingLogLevel(value logging.LogLevel) logging.LogLevel { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue logging.LogLevel + return nullValue +} + +func LoggingLogLevelThat(matcher pegomock.ArgumentMatcher) logging.LogLevel { + pegomock.RegisterMatcher(matcher) + var nullValue logging.LogLevel + return nullValue +} diff --git a/server/logging/mocks/matchers/logging_simplelogging.go b/server/logging/mocks/matchers/logging_simplelogging.go new file mode 100644 index 000000000..502456e7c --- /dev/null +++ b/server/logging/mocks/matchers/logging_simplelogging.go @@ -0,0 +1,33 @@ +// Code generated by pegomock. DO NOT EDIT. +package matchers + +import ( + "github.com/petergtz/pegomock" + "reflect" + + logging "github.com/runatlantis/atlantis/server/logging" +) + +func AnyLoggingSimpleLogging() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging + return nullValue +} + +func EqLoggingSimpleLogging(value logging.SimpleLogging) logging.SimpleLogging { + pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) + var nullValue logging.SimpleLogging + return nullValue +} + +func NotEqLoggingSimpleLogging(value logging.SimpleLogging) logging.SimpleLogging { + pegomock.RegisterMatcher(&pegomock.NotEqMatcher{Value: value}) + var nullValue logging.SimpleLogging + return nullValue +} + +func LoggingSimpleLoggingThat(matcher pegomock.ArgumentMatcher) logging.SimpleLogging { + pegomock.RegisterMatcher(matcher) + var nullValue logging.SimpleLogging + return nullValue +} diff --git a/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go b/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go index 04c72791b..cf9bb5453 100644 --- a/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go +++ b/server/logging/mocks/matchers/ptr_to_logging_simplelogger.go @@ -2,19 +2,19 @@ package matchers import ( - "reflect" "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" + "reflect" ) -func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger { - pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem())) - var nullValue *logging.SimpleLogger +func AnyPtrToLoggingSimpleLogger() logging.SimpleLogging { + pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.SimpleLogging))(nil)).Elem())) + var nullValue logging.SimpleLogging return nullValue } -func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger { +func EqPtrToLoggingSimpleLogger(value logging.SimpleLogging) logging.SimpleLogging { pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value}) - var nullValue *logging.SimpleLogger + var nullValue logging.SimpleLogging return nullValue } diff --git a/server/logging/mocks/mock_simple_logging.go b/server/logging/mocks/mock_simple_logging.go index 7d2eef71a..ed2eb414b 100644 --- a/server/logging/mocks/mock_simple_logging.go +++ b/server/logging/mocks/mock_simple_logging.go @@ -6,7 +6,6 @@ package mocks import ( pegomock "github.com/petergtz/pegomock" logging "github.com/runatlantis/atlantis/server/logging" - log "log" "reflect" "time" ) @@ -81,46 +80,60 @@ func (mock *MockSimpleLogging) Log(level logging.LogLevel, format string, a ...i pegomock.GetGenericMockFrom(mock).Invoke("Log", params, []reflect.Type{}) } -func (mock *MockSimpleLogging) Underlying() *log.Logger { +func (mock *MockSimpleLogging) SetLevel(lvl logging.LogLevel) { + if mock == nil { + panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") + } + params := []pegomock.Param{lvl} + pegomock.GetGenericMockFrom(mock).Invoke("SetLevel", params, []reflect.Type{}) +} + +func (mock *MockSimpleLogging) With(a ...interface{}) logging.SimpleLogging { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } params := []pegomock.Param{} - result := pegomock.GetGenericMockFrom(mock).Invoke("Underlying", params, []reflect.Type{reflect.TypeOf((**log.Logger)(nil)).Elem()}) - var ret0 *log.Logger + for _, param := range a { + params = append(params, param) + } + result := pegomock.GetGenericMockFrom(mock).Invoke("With", params, []reflect.Type{reflect.TypeOf((*logging.SimpleLogging)(nil)).Elem()}) + var ret0 logging.SimpleLogging if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(*log.Logger) + ret0 = result[0].(logging.SimpleLogging) } } return ret0 } -func (mock *MockSimpleLogging) GetLevel() logging.LogLevel { +func (mock *MockSimpleLogging) WithHistory(a ...interface{}) logging.SimpleLogging { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } params := []pegomock.Param{} - result := pegomock.GetGenericMockFrom(mock).Invoke("GetLevel", params, []reflect.Type{reflect.TypeOf((*logging.LogLevel)(nil)).Elem()}) - var ret0 logging.LogLevel + for _, param := range a { + params = append(params, param) + } + result := pegomock.GetGenericMockFrom(mock).Invoke("WithHistory", params, []reflect.Type{reflect.TypeOf((*logging.SimpleLogging)(nil)).Elem()}) + var ret0 logging.SimpleLogging if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(logging.LogLevel) + ret0 = result[0].(logging.SimpleLogging) } } return ret0 } -func (mock *MockSimpleLogging) NewLogger(_param0 string, _param1 bool, _param2 logging.LogLevel) *logging.SimpleLogger { +func (mock *MockSimpleLogging) GetHistory() string { if mock == nil { panic("mock must not be nil. Use myMock := NewMockSimpleLogging().") } - params := []pegomock.Param{_param0, _param1, _param2} - result := pegomock.GetGenericMockFrom(mock).Invoke("NewLogger", params, []reflect.Type{reflect.TypeOf((**logging.SimpleLogger)(nil)).Elem()}) - var ret0 *logging.SimpleLogger + params := []pegomock.Param{} + result := pegomock.GetGenericMockFrom(mock).Invoke("GetHistory", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem()}) + var ret0 string if len(result) != 0 { if result[0] != nil { - ret0 = result[0].(*logging.SimpleLogger) + ret0 = result[0].(string) } } return ret0 @@ -133,14 +146,14 @@ func (mock *MockSimpleLogging) VerifyWasCalledOnce() *VerifierMockSimpleLogging } } -func (mock *MockSimpleLogging) VerifyWasCalled(invocationCountMatcher pegomock.Matcher) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalled(invocationCountMatcher pegomock.InvocationCountMatcher) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, } } -func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher pegomock.Matcher, inOrderContext *pegomock.InOrderContext) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher pegomock.InvocationCountMatcher, inOrderContext *pegomock.InOrderContext) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -148,7 +161,7 @@ func (mock *MockSimpleLogging) VerifyWasCalledInOrder(invocationCountMatcher peg } } -func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher pegomock.Matcher, timeout time.Duration) *VerifierMockSimpleLogging { +func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher pegomock.InvocationCountMatcher, timeout time.Duration) *VerifierMockSimpleLogging { return &VerifierMockSimpleLogging{ mock: mock, invocationCountMatcher: invocationCountMatcher, @@ -158,7 +171,7 @@ func (mock *MockSimpleLogging) VerifyWasCalledEventually(invocationCountMatcher type VerifierMockSimpleLogging struct { mock *MockSimpleLogging - invocationCountMatcher pegomock.Matcher + invocationCountMatcher pegomock.InvocationCountMatcher inOrderContext *pegomock.InOrderContext timeout time.Duration } @@ -362,71 +375,116 @@ func (c *MockSimpleLogging_Log_OngoingVerification) GetAllCapturedArguments() (_ return } -func (verifier *VerifierMockSimpleLogging) Underlying() *MockSimpleLogging_Underlying_OngoingVerification { - params := []pegomock.Param{} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Underlying", params, verifier.timeout) - return &MockSimpleLogging_Underlying_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +func (verifier *VerifierMockSimpleLogging) SetLevel(lvl logging.LogLevel) *MockSimpleLogging_SetLevel_OngoingVerification { + params := []pegomock.Param{lvl} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "SetLevel", params, verifier.timeout) + return &MockSimpleLogging_SetLevel_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} } -type MockSimpleLogging_Underlying_OngoingVerification struct { +type MockSimpleLogging_SetLevel_OngoingVerification struct { mock *MockSimpleLogging methodInvocations []pegomock.MethodInvocation } -func (c *MockSimpleLogging_Underlying_OngoingVerification) GetCapturedArguments() { +func (c *MockSimpleLogging_SetLevel_OngoingVerification) GetCapturedArguments() logging.LogLevel { + lvl := c.GetAllCapturedArguments() + return lvl[len(lvl)-1] } -func (c *MockSimpleLogging_Underlying_OngoingVerification) GetAllCapturedArguments() { -} - -func (verifier *VerifierMockSimpleLogging) GetLevel() *MockSimpleLogging_GetLevel_OngoingVerification { - params := []pegomock.Param{} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "GetLevel", params, verifier.timeout) - return &MockSimpleLogging_GetLevel_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} -} - -type MockSimpleLogging_GetLevel_OngoingVerification struct { - mock *MockSimpleLogging - methodInvocations []pegomock.MethodInvocation -} - -func (c *MockSimpleLogging_GetLevel_OngoingVerification) GetCapturedArguments() { -} - -func (c *MockSimpleLogging_GetLevel_OngoingVerification) GetAllCapturedArguments() { -} - -func (verifier *VerifierMockSimpleLogging) NewLogger(_param0 string, _param1 bool, _param2 logging.LogLevel) *MockSimpleLogging_NewLogger_OngoingVerification { - params := []pegomock.Param{_param0, _param1, _param2} - methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "NewLogger", params, verifier.timeout) - return &MockSimpleLogging_NewLogger_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} -} - -type MockSimpleLogging_NewLogger_OngoingVerification struct { - mock *MockSimpleLogging - methodInvocations []pegomock.MethodInvocation -} - -func (c *MockSimpleLogging_NewLogger_OngoingVerification) GetCapturedArguments() (string, bool, logging.LogLevel) { - _param0, _param1, _param2 := c.GetAllCapturedArguments() - return _param0[len(_param0)-1], _param1[len(_param1)-1], _param2[len(_param2)-1] -} - -func (c *MockSimpleLogging_NewLogger_OngoingVerification) GetAllCapturedArguments() (_param0 []string, _param1 []bool, _param2 []logging.LogLevel) { +func (c *MockSimpleLogging_SetLevel_OngoingVerification) GetAllCapturedArguments() (_param0 []logging.LogLevel) { params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) if len(params) > 0 { - _param0 = make([]string, len(c.methodInvocations)) + _param0 = make([]logging.LogLevel, len(c.methodInvocations)) for u, param := range params[0] { - _param0[u] = param.(string) - } - _param1 = make([]bool, len(c.methodInvocations)) - for u, param := range params[1] { - _param1[u] = param.(bool) - } - _param2 = make([]logging.LogLevel, len(c.methodInvocations)) - for u, param := range params[2] { - _param2[u] = param.(logging.LogLevel) + _param0[u] = param.(logging.LogLevel) } } return } + +func (verifier *VerifierMockSimpleLogging) With(a ...interface{}) *MockSimpleLogging_With_OngoingVerification { + params := []pegomock.Param{} + for _, param := range a { + params = append(params, param) + } + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "With", params, verifier.timeout) + return &MockSimpleLogging_With_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockSimpleLogging_With_OngoingVerification struct { + mock *MockSimpleLogging + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockSimpleLogging_With_OngoingVerification) GetCapturedArguments() []interface{} { + a := c.GetAllCapturedArguments() + return a[len(a)-1] +} + +func (c *MockSimpleLogging_With_OngoingVerification) GetAllCapturedArguments() (_param0 [][]interface{}) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([][]interface{}, len(c.methodInvocations)) + for u := 0; u < len(c.methodInvocations); u++ { + _param0[u] = make([]interface{}, len(params)-0) + for x := 0; x < len(params); x++ { + if params[x][u] != nil { + _param0[u][x-0] = params[x][u].(interface{}) + } + } + } + } + return +} + +func (verifier *VerifierMockSimpleLogging) WithHistory(a ...interface{}) *MockSimpleLogging_WithHistory_OngoingVerification { + params := []pegomock.Param{} + for _, param := range a { + params = append(params, param) + } + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "WithHistory", params, verifier.timeout) + return &MockSimpleLogging_WithHistory_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockSimpleLogging_WithHistory_OngoingVerification struct { + mock *MockSimpleLogging + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockSimpleLogging_WithHistory_OngoingVerification) GetCapturedArguments() []interface{} { + a := c.GetAllCapturedArguments() + return a[len(a)-1] +} + +func (c *MockSimpleLogging_WithHistory_OngoingVerification) GetAllCapturedArguments() (_param0 [][]interface{}) { + params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations) + if len(params) > 0 { + _param0 = make([][]interface{}, len(c.methodInvocations)) + for u := 0; u < len(c.methodInvocations); u++ { + _param0[u] = make([]interface{}, len(params)-0) + for x := 0; x < len(params); x++ { + if params[x][u] != nil { + _param0[u][x-0] = params[x][u].(interface{}) + } + } + } + } + return +} + +func (verifier *VerifierMockSimpleLogging) GetHistory() *MockSimpleLogging_GetHistory_OngoingVerification { + params := []pegomock.Param{} + methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "GetHistory", params, verifier.timeout) + return &MockSimpleLogging_GetHistory_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations} +} + +type MockSimpleLogging_GetHistory_OngoingVerification struct { + mock *MockSimpleLogging + methodInvocations []pegomock.MethodInvocation +} + +func (c *MockSimpleLogging_GetHistory_OngoingVerification) GetCapturedArguments() { +} + +func (c *MockSimpleLogging_GetHistory_OngoingVerification) GetAllCapturedArguments() { +} diff --git a/server/logging/simple_logger.go b/server/logging/simple_logger.go index 0918e43f8..3314d6101 100644 --- a/server/logging/simple_logger.go +++ b/server/logging/simple_logger.go @@ -17,211 +17,197 @@ package logging import ( "bytes" "fmt" - "io/ioutil" - "log" - "os" - "runtime" - "time" - "unicode" + "testing" + + "github.com/pkg/errors" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest" ) //go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_simple_logging.go SimpleLogging -// SimpleLogging is the interface that our SimpleLogger implements. -// It's really only used for mocking when we need to test what's being logged. +// SimpleLogging is the interface used for logging throughout the codebase. type SimpleLogging interface { + + // These basically just fmt.Sprintf() the message and args. Debug(format string, a ...interface{}) Info(format string, a ...interface{}) Warn(format string, a ...interface{}) Err(format string, a ...interface{}) Log(level LogLevel, format string, a ...interface{}) - // Underlying returns the underlying logger. - Underlying() *log.Logger - // GetLevel returns the current log level. - GetLevel() LogLevel - NewLogger(string, bool, LogLevel) *SimpleLogger + SetLevel(lvl LogLevel) + + // With adds a variadic number of fields to the logging context. It accepts a + // mix of strongly-typed Field objects and loosely-typed key-value pairs. When + // processing pairs, the first element of the pair is used as the field key + // and the second as the field value. + With(a ...interface{}) SimpleLogging + + // Creates a new logger with history preserved . log storage + search strategies + // should ideally be used instead of managing this ourselves. + // keeping as a separate method to ensure that usage of history is completely intentional + WithHistory(a ...interface{}) SimpleLogging + + // Fetches the history we've stored associated with the logging context + GetHistory() string + + // Flushes anything left in the buffer + Flush() error } -// SimpleLogger wraps the standard logger with leveled logging -// and the ability to store log history for later adding it -// to a VCS comment. -type SimpleLogger struct { - // Source is added as a prefix to each log entry. - // It's useful if you want to trace a log entry back to a - // context, for example a pull request id. - Source string +type StructuredLogger struct { + z *zap.SugaredLogger + level zap.AtomicLevel + keepHistory bool // History stores all log entries ever written using // this logger. This is safe for short-lived loggers // like those used during plan/apply commands. - History bytes.Buffer - Logger *log.Logger - KeepHistory bool - Level LogLevel + // TODO: Deprecate this + // this is added here to maintain backwards compatibility + // This doesn't really make sense to keep given that structured logging + // gives us the ability to query our logs across multiple dimensions + // I don't believe we should mix this in with atlantis commands and expose this to the user + history bytes.Buffer } -type LogLevel int +func NewStructuredLoggerFromLevel(lvl LogLevel) (SimpleLogging, error) { + cfg := zap.NewProductionConfig() -const ( - Debug LogLevel = iota - Info - Warn - Error -) + cfg.Level = zap.NewAtomicLevelAt(lvl.zLevel) + return newStructuredLogger(cfg) +} -// NewSimpleLogger creates a new logger. -// source is added as a prefix to each log entry. It's useful if you want to -// trace a log entry back to a specific context, for example a pull request id. -// keepHistory set to true will store all log entries written using this logger. -// level will set the level at which logs >= than that level will be written. -// If keepHistory is set to true, we'll store logs at all levels, regardless of -// what level is set to. -func NewSimpleLogger(source string, keepHistory bool, level LogLevel) *SimpleLogger { - return &SimpleLogger{ - Source: source, - Logger: log.New(os.Stderr, "", 0), - Level: level, - KeepHistory: keepHistory, +func NewStructuredLogger() (SimpleLogging, error) { + cfg := zap.NewProductionConfig() + return newStructuredLogger(cfg) +} + +func newStructuredLogger(cfg zap.Config) (*StructuredLogger, error) { + baseLogger, err := cfg.Build() + + baseLogger = baseLogger. + // ensures that the caller doesn't just say logging/simple_logger each time + WithOptions(zap.AddCallerSkip(1)). + WithOptions(zap.AddStacktrace(zapcore.WarnLevel)). + // creates isolated context for all future kv pairs, name can be flexible as needed + With(zap.Namespace("json")) + + if err != nil { + return nil, errors.Wrap(err, " initializing structured logger") } + + return &StructuredLogger{ + z: baseLogger.Sugar(), + level: cfg.Level, + }, nil +} + +func (l *StructuredLogger) With(a ...interface{}) SimpleLogging { + return &StructuredLogger{ + z: l.z.With(a...), + level: l.level, + } +} + +func (l *StructuredLogger) WithHistory(a ...interface{}) SimpleLogging { + logger := &StructuredLogger{ + z: l.z.With(a...), + level: l.level, + } + + // ensure that the history is kept across loggers. + logger.keepHistory = true + logger.history = l.history + + return logger +} + +func (l *StructuredLogger) GetHistory() string { + return l.history.String() +} + +func (l *StructuredLogger) Debug(format string, a ...interface{}) { + l.z.Debugf(format, a...) + l.saveToHistory(Debug, format, a...) +} + +func (l *StructuredLogger) Info(format string, a ...interface{}) { + l.z.Infof(format, a...) + l.saveToHistory(Info, format, a...) +} + +func (l *StructuredLogger) Warn(format string, a ...interface{}) { + l.z.Warnf(format, a...) + l.saveToHistory(Warn, format, a...) +} + +func (l *StructuredLogger) Err(format string, a ...interface{}) { + l.z.Errorf(format, a...) + l.saveToHistory(Error, format, a...) +} + +func (l *StructuredLogger) Log(level LogLevel, format string, a ...interface{}) { + switch level { + case Debug: + l.Debug(format, a...) + case Info: + l.Info(format, a...) + case Warn: + l.Warn(format, a...) + case Error: + l.Err(format, a...) + } +} + +func (l *StructuredLogger) SetLevel(lvl LogLevel) { + if l != nil { + l.level.SetLevel(lvl.zLevel) + } +} + +func (l *StructuredLogger) Flush() error { + return l.z.Sync() +} + +func (l *StructuredLogger) saveToHistory(lvl LogLevel, format string, a ...interface{}) { + if !l.keepHistory { + return + } + msg := fmt.Sprintf(format, a...) + l.history.WriteString(fmt.Sprintf("[%s] %s\n", lvl.shortStr, msg)) } // NewNoopLogger creates a logger instance that discards all logs and never // writes them. Used for testing. -func NewNoopLogger() *SimpleLogger { - logger := log.New(os.Stderr, "", 0) - logger.SetOutput(ioutil.Discard) - return &SimpleLogger{ - Source: "", - Logger: logger, - Level: Info, - KeepHistory: false, +func NewNoopLogger(t *testing.T) SimpleLogging { + level := zap.DebugLevel + return &StructuredLogger{ + z: zaptest.NewLogger(t, zaptest.Level(level)).Sugar(), + level: zap.NewAtomicLevelAt(level), } } -// NewLogger returns a new logger that reuses the underlying logger. -func (l *SimpleLogger) NewLogger(source string, keepHistory bool, lvl LogLevel) *SimpleLogger { - if l == nil { - return nil +type LogLevel struct { + zLevel zapcore.Level + shortStr string +} + +var ( + Debug = LogLevel{ + zLevel: zapcore.DebugLevel, + shortStr: "DBUG", } - return &SimpleLogger{ - Source: source, - Level: lvl, - Logger: l.Underlying(), - KeepHistory: keepHistory, + Info = LogLevel{ + zLevel: zapcore.InfoLevel, + shortStr: "INFO", } -} - -// SetLevel changes the level that this logger is writing at to lvl. -func (l *SimpleLogger) SetLevel(lvl LogLevel) { - if l != nil { - l.Level = lvl + Warn = LogLevel{ + zLevel: zapcore.WarnLevel, + shortStr: "WARN", } -} - -// Debug logs at debug level. -func (l *SimpleLogger) Debug(format string, a ...interface{}) { - if l != nil { - l.Log(Debug, format, a...) + Error = LogLevel{ + zLevel: zapcore.ErrorLevel, + shortStr: "EROR", } -} - -// Info logs at info level. -func (l *SimpleLogger) Info(format string, a ...interface{}) { - if l != nil { - l.Log(Info, format, a...) - } -} - -// Warn logs at warn level. -func (l *SimpleLogger) Warn(format string, a ...interface{}) { - if l != nil { - l.Log(Warn, format, a...) - } -} - -// Err logs at error level. -func (l *SimpleLogger) Err(format string, a ...interface{}) { - if l != nil { - l.Log(Error, format, a...) - } -} - -// Log writes the log at level. -func (l *SimpleLogger) Log(level LogLevel, format string, a ...interface{}) { - if l != nil { - levelStr := l.levelToString(level) - msg := l.capitalizeFirstLetter(fmt.Sprintf(format, a...)) - - // Only log this message if configured to log at this level. - if l.Level <= level { - datetime := time.Now().Format("2006/01/02 15:04:05-0700") - var caller string - if l.Level <= Debug { - file, line := l.callSite(3) - caller = fmt.Sprintf(" %s:%d", file, line) - } - l.Logger.Printf("%s [%s]%s %s: %s\n", datetime, levelStr, caller, l.Source, msg) // noline: errcheck - } - - // Keep history at all log levels. - if l.KeepHistory { - l.saveToHistory(levelStr, msg) - } - } -} - -// Underlying returns the underlying logger. -func (l *SimpleLogger) Underlying() *log.Logger { - return l.Logger -} - -// GetLevel returns the current log level of the logger. -func (l *SimpleLogger) GetLevel() LogLevel { - return l.Level -} - -func (l *SimpleLogger) saveToHistory(level string, msg string) { - l.History.WriteString(fmt.Sprintf("[%s] %s\n", level, msg)) -} - -func (l *SimpleLogger) capitalizeFirstLetter(s string) string { - runes := []rune(s) - runes[0] = unicode.ToUpper(runes[0]) - return string(runes) -} - -// levelToString returns the logging level as a 4 character string. DEBUG and ERROR are shortened intentionally -// so that logs line up. -func (l *SimpleLogger) levelToString(level LogLevel) string { - switch level { - case Debug: - return "DBUG" - case Info: - return "INFO" - case Warn: - return "WARN" - case Error: - return "EROR" - } - return "????" -} - -// callSite returns the location of the caller of this function via its -// filename and line number. skip is the number of stack frames to skip. -func (l *SimpleLogger) callSite(skip int) (string, int) { - _, file, line, ok := runtime.Caller(skip) - if !ok { - return "???", 0 - } - - // file is the full filepath but we just want the filename. - // NOTE: rather than calling path.Base we're using code from the stdlib - // logging package which I assume is optimized. - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } - } - return short, line -} +) diff --git a/server/middleware.go b/server/middleware.go index 760d71b28..5aee2ebb6 100644 --- a/server/middleware.go +++ b/server/middleware.go @@ -21,13 +21,13 @@ import ( ) // NewRequestLogger creates a RequestLogger. -func NewRequestLogger(logger *logging.SimpleLogger) *RequestLogger { +func NewRequestLogger(logger logging.SimpleLogging) *RequestLogger { return &RequestLogger{logger} } // RequestLogger logs requests and their response codes. type RequestLogger struct { - logger *logging.SimpleLogger + logger logging.SimpleLogging } // ServeHTTP implements the middleware function. It logs all requests at DEBUG level. diff --git a/server/server.go b/server/server.go index 0d2ae59a7..23098e4c1 100644 --- a/server/server.go +++ b/server/server.go @@ -82,7 +82,7 @@ type Server struct { Port int PreWorkflowHooksCommandRunner *events.DefaultPreWorkflowHooksCommandRunner CommandRunner *events.DefaultCommandRunner - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Locker locking.Locker ApplyLocker locking.ApplyLocker EventsController *EventsController @@ -125,7 +125,12 @@ type WebhookConfig struct { // its dependencies an error will be returned. This is like the main() function // for the server CLI command because it injects all the dependencies. func NewServer(userConfig UserConfig, config Config) (*Server, error) { - logger := logging.NewSimpleLogger("server", false, userConfig.ToLogLevel()) + logger, err := logging.NewStructuredLoggerFromLevel(userConfig.ToLogLevel()) + + if err != nil { + return nil, err + } + var supportedVCSHosts []models.VCSHostType var githubClient *vcs.GithubClient var githubAppEnabled bool @@ -642,6 +647,8 @@ func (s *Server) Start() error { }, NewRequestLogger(s.Logger)) n.UseHandler(s.Router) + defer s.Logger.Flush() + // Ensure server gracefully drains connections when stopped. stop := make(chan os.Signal, 1) // Stop on SIGINTs and SIGTERMs. diff --git a/server/server_test.go b/server/server_test.go index 27a34ef23..4b22cdf6a 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -29,6 +29,7 @@ import ( "github.com/runatlantis/atlantis/server" "github.com/runatlantis/atlantis/server/events/locking/mocks" "github.com/runatlantis/atlantis/server/events/models" + "github.com/runatlantis/atlantis/server/logging" sMocks "github.com/runatlantis/atlantis/server/mocks" . "github.com/runatlantis/atlantis/testing" ) @@ -106,6 +107,7 @@ func TestIndex_Success(t *testing.T) { Router: r, AtlantisVersion: atlantisVersion, AtlantisURL: u, + Logger: logging.NewNoopLogger(t), } req, _ := http.NewRequest("GET", "", bytes.NewBuffer(nil)) w := httptest.NewRecorder() diff --git a/server/status_controller.go b/server/status_controller.go index 7add51671..411176437 100644 --- a/server/status_controller.go +++ b/server/status_controller.go @@ -11,7 +11,7 @@ import ( // StatusController handles the status of Atlantis. type StatusController struct { - Logger *logging.SimpleLogger + Logger logging.SimpleLogging Drainer *events.Drainer } diff --git a/server/status_controller_test.go b/server/status_controller_test.go index 9ad3a4fc4..9032febb0 100644 --- a/server/status_controller_test.go +++ b/server/status_controller_test.go @@ -15,7 +15,7 @@ import ( ) func TestStatusController_Startup(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{} @@ -36,7 +36,7 @@ func TestStatusController_Startup(t *testing.T) { } func TestStatusController_InProgress(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{} @@ -59,7 +59,7 @@ func TestStatusController_InProgress(t *testing.T) { } func TestStatusController_Shutdown(t *testing.T) { - logger := logging.NewNoopLogger() + logger := logging.NewNoopLogger(t) r, _ := http.NewRequest("GET", "/status", bytes.NewBuffer(nil)) w := httptest.NewRecorder() dr := &events.Drainer{}