diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6d5e509..f087cb9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: ${{ runner.os }}-go- - name: Run Tests - run: go test -v -race -coverprofile coverage.out -covermode atomic ./... + run: go test -race -coverprofile coverage.out -covermode atomic ./... - name: Upload Coverage to Codecov if: success() @@ -60,7 +60,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@master with: - version: v1.37 + version: v1.39 skip-go-installation: true verify_doc_tools: @@ -75,7 +75,7 @@ jobs: - name: Run gendoc tool run: go run ./tools/gendoc - + - name: Run licensing tool run: go run ./tools/licensing diff --git a/.gitignore b/.gitignore index 62800cb..eab9175 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ # Test binary, built with `go test -c` *.test -# Output of the go coverage tool, specifically when used with LiteIDE +# Output of the go coverage tool *.out # Dependency directories (remove the comment below to include it) diff --git a/README.md b/README.md index 65f93f1..fc273cd 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ Documentation is hosted at . Check out our in ## Integrations -- [GitHub Action](https://github.com/marketplace/actions/cider-action) -- [Buildkite Plugin](https://github.com/cidertool/cider-buildkite-plugin) +- [GitHub Action](https://github.com/marketplace/actions/cider-action) +- [Buildkite Plugin](https://github.com/cidertool/cider-buildkite-plugin) ## Badges @@ -37,7 +37,7 @@ This project's primary goal is to simplify the process to release on the App Sto Special thanks to: -- [GoReleaser](https://goreleaser.com/) for inspiring the architecture and open sourcing several components used in Cider +- [GoReleaser](https://goreleaser.com/) for inspiring the architecture and open sourcing several components used in Cider ## License diff --git a/internal/clicommand/check.go b/internal/clicommand/check.go index 2a5a967..13b7694 100644 --- a/internal/clicommand/check.go +++ b/internal/clicommand/check.go @@ -23,7 +23,6 @@ package clicommand import ( "fmt" - "github.com/apex/log" "github.com/cidertool/cider/internal/pipe/defaults" "github.com/cidertool/cider/pkg/context" "github.com/fatih/color" @@ -31,12 +30,13 @@ import ( ) type checkCmd struct { - cmd *cobra.Command - config string + cmd *cobra.Command + debugFlagValue *bool + config string } -func newCheckCmd() *checkCmd { - var root = &checkCmd{} +func newCheckCmd(debugFlagValue *bool) *checkCmd { + var root = &checkCmd{debugFlagValue: debugFlagValue} var cmd = &cobra.Command{ Use: "check", @@ -45,32 +45,37 @@ func newCheckCmd() *checkCmd { Example: "cider check", SilenceUsage: true, SilenceErrors: true, - RunE: func(cmd *cobra.Command, args []string) error { - cfg, err := loadConfig(root.config, "") - if err != nil { - return err - } - var ctx = context.New(cfg) + RunE: root.Run, + } - if err := context.NewInterrupt().Run(ctx, func() error { - log.Info(color.New(color.Bold).Sprint("checking config:")) + cmd.Flags().StringVarP(&root.config, "config", "f", "", "Configuration file to check") - return defaults.Pipe{}.Run(ctx) - }); err != nil { - log.WithError(err).Error(color.New(color.Bold).Sprintf("config is invalid")) + root.cmd = cmd - return fmt.Errorf("invalid config: %w", err) - } + return root +} - log.Info(color.New(color.Bold).Sprintf("config is valid")) +func (cmd *checkCmd) Run(c *cobra.Command, args []string) error { + logger := newLogger(cmd.debugFlagValue) - return nil - }, + cfg, err := loadConfig(cmd.config, "") + if err != nil { + return err } - cmd.Flags().StringVarP(&root.config, "config", "f", "", "Configuration file to check") + var ctx = context.New(cfg) - root.cmd = cmd + if err := context.NewInterrupt().Run(ctx, func() error { + logger.Info(color.New(color.Bold).Sprint("checking config:")) - return root + return defaults.Pipe{}.Run(ctx) + }); err != nil { + logger.WithError(err).Error(color.New(color.Bold).Sprintf("config is invalid")) + + return fmt.Errorf("invalid config: %w", err) + } + + logger.Info(color.New(color.Bold).Sprintf("config is valid")) + + return nil } diff --git a/internal/clicommand/check_test.go b/internal/clicommand/check_test.go index f013921..b67f73d 100644 --- a/internal/clicommand/check_test.go +++ b/internal/clicommand/check_test.go @@ -32,7 +32,9 @@ import ( func TestCheckCmd(t *testing.T) { t.Parallel() - var cmd = newCheckCmd() + var noDebug bool + + var cmd = newCheckCmd(&noDebug) var path = filepath.Join(t.TempDir(), "foo.yaml") diff --git a/internal/clicommand/clicommand.go b/internal/clicommand/clicommand.go new file mode 100644 index 0000000..ee36dff --- /dev/null +++ b/internal/clicommand/clicommand.go @@ -0,0 +1,42 @@ +/** +Copyright (C) 2020 Aaron Sky. + +This file is part of Cider, a tool for automating submission +of apps to Apple's App Stores. + +Cider is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Cider is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Cider. If not, see . +*/ + +// Package clicommand declares the command line interface for Cider. +package clicommand + +import ( + "github.com/cidertool/cider/internal/log" +) + +func newLogger(debugFlagValue *bool) *log.Log { + logger := log.New() + + // Comment this out as it's causing issues during parallel testing + // if os.Getenv("CI") != "" { + // logger.SetColorMode(false) + // } + + if debugFlagValue != nil { + logger.SetDebug(*debugFlagValue) + logger.Debug("debug logs enabled") + } + + return logger +} diff --git a/internal/clicommand/init.go b/internal/clicommand/init.go index a5d77be..1747d58 100644 --- a/internal/clicommand/init.go +++ b/internal/clicommand/init.go @@ -25,8 +25,8 @@ import ( "os" "path/filepath" - "github.com/apex/log" "github.com/cidertool/cider/internal/closer" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/pkg/config" "github.com/fatih/color" "github.com/manifoldco/promptui" @@ -50,7 +50,7 @@ type initOpts struct { skipPrompt bool } -func newInitCmd() *initCmd { +func newInitCmd(debugFlagValue *bool) *initCmd { var root = &initCmd{} var cmd = &cobra.Command{ @@ -62,7 +62,9 @@ func newInitCmd() *initCmd { SilenceUsage: true, SilenceErrors: true, RunE: func(cmd *cobra.Command, args []string) error { - return initProject(root.opts) + logger := newLogger(debugFlagValue) + + return initProject(root.opts, logger) }, } @@ -74,17 +76,17 @@ func newInitCmd() *initCmd { return root } -func initProject(opts initOpts) (err error) { - file, err := createFileIfNeeded(opts.config, opts.skipPrompt) +func initProject(opts initOpts, logger log.Interface) (err error) { + file, err := createFileIfNeeded(opts.config, opts.skipPrompt, logger) if err != nil { return err } defer closer.Close(file) - log.Info(color.New(color.Bold).Sprintf("Populating project file at %s", opts.config)) + logger.Info(color.New(color.Bold).Sprintf("Populating project file at %s", opts.config)) - project, err := newProject(opts.skipPrompt) + project, err := newProject(opts.skipPrompt, logger) if err != nil { return err } @@ -93,16 +95,16 @@ func initProject(opts initOpts) (err error) { return err } - log. + logger. WithField("file", file.Name()). Info("config created") - log.Info("Please edit accordingly to fit your needs.") - log.Info("For additional configuration options, see: https://cidertool.github.io/cider/configuration") + logger.Info("Please edit accordingly to fit your needs.") + logger.Info("For additional configuration options, see: https://cidertool.github.io/cider/configuration") return nil } -func createFileIfNeeded(path string, skipPrompt bool) (*os.File, error) { +func createFileIfNeeded(path string, skipPrompt bool, logger log.Interface) (*os.File, error) { f, err := os.OpenFile(filepath.Clean(path), os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_EXCL, 0600) if err == nil { return f, nil @@ -113,7 +115,7 @@ func createFileIfNeeded(path string, skipPrompt bool) (*os.File, error) { } if skipPrompt { - log.Warn("file exists, overwriting") + logger.Warn("file exists, overwriting") } else { prompt := promptui.Prompt{ Label: "Overwrite file?", @@ -128,7 +130,7 @@ func createFileIfNeeded(path string, skipPrompt bool) (*os.File, error) { return os.OpenFile(filepath.Clean(path), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) } -func newProject(skipPrompt bool) (*config.Project, error) { +func newProject(skipPrompt bool, logger log.Interface) (*config.Project, error) { var project *config.Project var err error @@ -136,18 +138,18 @@ func newProject(skipPrompt bool) (*config.Project, error) { if skipPrompt { project = newProjectFromDefaults() } else { - project, err = newProjectFromPrompts() + project, err = newProjectFromPrompts(logger) } return project, err } -func newProjectFromPrompts() (*config.Project, error) { +func newProjectFromPrompts(logger log.Interface) (*config.Project, error) { values := projectInitValues{} var continueAppsSetup = true for continueAppsSetup { - name, app, err := promptAppValues() + name, app, err := promptAppValues(logger) if err != nil { return nil, err } @@ -167,7 +169,7 @@ func newProjectFromPrompts() (*config.Project, error) { return &proj, nil } -func promptAppValues() (name string, app *projectInitAppValues, err error) { +func promptAppValues(logger log.Interface) (name string, app *projectInitAppValues, err error) { var prompt promptui.Prompt var selec promptui.Select @@ -180,7 +182,7 @@ func promptAppValues() (name string, app *projectInitAppValues, err error) { PhasedReleaseEnabled: true, } - log.Info("Let's set up an app in your project!") + logger.Info("Let's set up an app in your project!") prompt = promptui.Prompt{Label: "App Name"} diff --git a/internal/clicommand/init_test.go b/internal/clicommand/init_test.go index a9a1649..95afdd9 100644 --- a/internal/clicommand/init_test.go +++ b/internal/clicommand/init_test.go @@ -32,7 +32,9 @@ func TestInitCmd(t *testing.T) { var folder = t.TempDir() - var cmd = newInitCmd().cmd + var noDebug bool + + var cmd = newInitCmd(&noDebug).cmd var path = filepath.Join(folder, "foo.yaml") diff --git a/internal/clicommand/release.go b/internal/clicommand/release.go index ecb203e..b5fcb08 100644 --- a/internal/clicommand/release.go +++ b/internal/clicommand/release.go @@ -24,7 +24,7 @@ import ( "errors" "time" - "github.com/apex/log" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/middleware" "github.com/cidertool/cider/internal/pipeline" "github.com/cidertool/cider/pkg/config" @@ -62,7 +62,7 @@ type releaseOpts struct { currentDirectory string } -func newReleaseCmd() *releaseCmd { +func newReleaseCmd(debugFlagValue *bool) *releaseCmd { var root = &releaseCmd{} var cmd = &cobra.Command{ @@ -94,6 +94,8 @@ More info: https://developer.apple.com/documentation/appstoreconnectapi/creating SilenceUsage: true, SilenceErrors: true, RunE: func(cmd *cobra.Command, args []string) error { + logger := newLogger(debugFlagValue) + if len(args) > 0 { root.opts.currentDirectory = args[0] } @@ -104,14 +106,14 @@ More info: https://developer.apple.com/documentation/appstoreconnectapi/creating start := time.Now() - log.Info(color.New(color.Bold).Sprint("releasing...")) + logger.Info(color.New(color.Bold).Sprint("releasing...")) - _, err := releaseProject(root.opts) + _, err := releaseProject(root.opts, logger) if err != nil { return wrapError(err, color.New(color.Bold).Sprintf("release failed after %0.2fs", time.Since(start).Seconds())) } - log.Info(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds())) + logger.Info(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds())) return nil }, @@ -241,14 +243,14 @@ using the configuration file.`, return root } -func releaseProject(options releaseOpts) (*context.Context, error) { +func releaseProject(options releaseOpts, logger log.Interface) (*context.Context, error) { var forceAllSkips bool cfg, err := loadConfig(options.config, options.currentDirectory) if err != nil { if errors.Is(err, ErrConfigNotFound) { - log.Warn(err.Error()) - log.Warn("using defaults and enabling all skips to avoid dangerous consequences...") + logger.Warn(err.Error()) + logger.Warn("using defaults and enabling all skips to avoid dangerous consequences...") forceAllSkips = true } else { @@ -258,7 +260,7 @@ func releaseProject(options releaseOpts) (*context.Context, error) { ctx, cancel := context.NewWithTimeout(cfg, options.timeout) defer cancel() - setupReleaseContext(ctx, options, forceAllSkips) + setupReleaseContext(ctx, options, forceAllSkips, logger) return ctx, context.NewInterrupt().Run(ctx, func() error { for _, pipe := range pipeline.Pipeline { @@ -275,7 +277,7 @@ func releaseProject(options releaseOpts) (*context.Context, error) { }) } -func setupReleaseContext(ctx *context.Context, options releaseOpts, forceAllSkips bool) *context.Context { +func setupReleaseContext(ctx *context.Context, options releaseOpts, forceAllSkips bool, logger log.Interface) *context.Context { ctx.AppsToRelease = ctx.Config.AppsMatching(options.appsToRelease, options.releaseAllApps) if options.publishMode == "" { ctx.PublishMode = context.PublishModeTestflight @@ -283,6 +285,7 @@ func setupReleaseContext(ctx *context.Context, options releaseOpts, forceAllSkip ctx.PublishMode = options.publishMode } + ctx.Log = logger ctx.MaxProcesses = options.maxProcesses ctx.SkipGit = options.skipGit || forceAllSkips ctx.SkipUpdatePricing = options.skipUpdatePricing || forceAllSkips diff --git a/internal/clicommand/root.go b/internal/clicommand/root.go index abb7ac5..92a1239 100644 --- a/internal/clicommand/root.go +++ b/internal/clicommand/root.go @@ -18,27 +18,15 @@ You should have received a copy of the GNU General Public License along with Cider. If not, see . */ -// Package clicommand declares the command line interface for Cider. package clicommand import ( "errors" "fmt" - "os" - "sync" - "github.com/apex/log" - "github.com/apex/log/handlers/cli" - "github.com/fatih/color" "github.com/spf13/cobra" ) -// nolint: gochecknoglobals -// It's strange these need to be global. -var ( - loggerMu sync.Mutex -) - // Execute is the primary function to initiate the command line interface for Cider. func Execute(version string, exit func(int), args []string) { // nolint: forbidigo @@ -51,9 +39,8 @@ func Execute(version string, exit func(int), args []string) { // Root defines a rough structure for a root command type. type Root struct { - Cmd *cobra.Command - debug bool - exit func(int) + Cmd *cobra.Command + exit func(int) } // NewRoot creates a new instance of the root command for the cider executable. @@ -62,6 +49,8 @@ func NewRoot(version string, exit func(int)) *Root { exit: exit, } + var debug bool + var cmd = &cobra.Command{ Use: "cider", Short: "Submit your builds to the Apple App Store in seconds", @@ -69,15 +58,14 @@ func NewRoot(version string, exit func(int)) *Root { SilenceUsage: true, SilenceErrors: true, DisableAutoGenTag: true, - PersistentPreRun: root.customizeLogger, } - cmd.PersistentFlags().BoolVar(&root.debug, "debug", false, "Enable debug mode") + cmd.PersistentFlags().BoolVar(&debug, "debug", false, "Enable debug mode") cmd.AddCommand( - newInitCmd().cmd, - newCheckCmd().cmd, - newReleaseCmd().cmd, + newInitCmd(&debug).cmd, + newCheckCmd(&debug).cmd, + newReleaseCmd(&debug).cmd, newCompletionsCmd().cmd, ) @@ -105,24 +93,8 @@ func (cmd *Root) Execute(args []string) { } } - log.WithError(err).Error(msg) + newLogger(nil).WithError(err).Error(msg) cmd.exit(code) } } - -func (cmd *Root) customizeLogger(c *cobra.Command, args []string) { - loggerMu.Lock() - defer loggerMu.Unlock() - - if os.Getenv("CI") != "" { - color.NoColor = false - } - - log.SetHandler(cli.Default) - - if cmd.debug { - log.SetLevel(log.DebugLevel) - log.Debug("debug logs enabled") - } -} diff --git a/internal/clicommand/root_test.go b/internal/clicommand/root_test.go index b769458..27950d3 100644 --- a/internal/clicommand/root_test.go +++ b/internal/clicommand/root_test.go @@ -21,7 +21,6 @@ along with Cider. If not, see . package clicommand import ( - "os" "testing" "github.com/stretchr/testify/assert" @@ -33,8 +32,7 @@ func TestRootCmd(t *testing.T) { exit := func(code int) { assert.Equal(t, 0, code) } - err := os.Setenv("CI", "1") - assert.NoError(t, err) + Execute("TEST", exit, []string{"help", "--debug"}) } @@ -44,5 +42,6 @@ func TestRootCmd_Error(t *testing.T) { exit := func(code int) { assert.NotEqual(t, 0, code) } + Execute("TEST", exit, []string{"check"}) } diff --git a/internal/client/assets.go b/internal/client/assets.go index 3f25ec4..3e99e20 100644 --- a/internal/client/assets.go +++ b/internal/client/assets.go @@ -28,9 +28,9 @@ import ( "os" "path/filepath" - "github.com/apex/log" "github.com/cidertool/asc-go/asc" "github.com/cidertool/cider/internal/closer" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/parallel" "github.com/cidertool/cider/pkg/config" "github.com/cidertool/cider/pkg/context" @@ -74,7 +74,7 @@ func (c *ascClient) UploadRoutingCoverage(ctx *context.Context, versionID string prepare := func(name string, checksum string) (shouldContinue bool, err error) { covResp, _, err := c.client.Apps.GetRoutingAppCoverageForAppStoreVersion(ctx, versionID, nil) if err != nil { - log.Warn(err.Error()) + ctx.Log.Warn(err.Error()) } if covResp == nil { @@ -165,7 +165,7 @@ func (c *ascClient) UploadPreviews(ctx *context.Context, g parallel.Group, previ if preview.Attributes.SourceFileChecksum != nil && *preview.Attributes.SourceFileChecksum == checksum { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": preview.ID, "checksum": checksum, }).Debug("skip existing preview") @@ -173,7 +173,7 @@ func (c *ascClient) UploadPreviews(ctx *context.Context, g parallel.Group, previ return false, nil } - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, "id": preview.ID, }).Debug("delete preview") @@ -186,7 +186,7 @@ func (c *ascClient) UploadPreviews(ctx *context.Context, g parallel.Group, previ } create := func(name string, size int64) (id string, ops []asc.UploadOperation, err error) { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, }).Debug("create preview") @@ -201,7 +201,7 @@ func (c *ascClient) UploadPreviews(ctx *context.Context, g parallel.Group, previ for i := range previewConfigs { previewConfig := previewConfigs[i] commit := func(id string, checksum string) error { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": id, }).Debug("commit preview") @@ -277,7 +277,7 @@ func (c *ascClient) UploadScreenshots(ctx *context.Context, g parallel.Group, sc if shot.Attributes.SourceFileChecksum != nil && *shot.Attributes.SourceFileChecksum == checksum { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": shot.ID, "checksum": checksum, }).Debug("skip existing screenshot") @@ -285,7 +285,7 @@ func (c *ascClient) UploadScreenshots(ctx *context.Context, g parallel.Group, sc return false, nil } - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, "id": shot.ID, }).Debug("delete screenshot") @@ -298,7 +298,7 @@ func (c *ascClient) UploadScreenshots(ctx *context.Context, g parallel.Group, sc } create := func(name string, size int64) (id string, ops []asc.UploadOperation, err error) { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, }).Debug("create screenshot") @@ -311,7 +311,7 @@ func (c *ascClient) UploadScreenshots(ctx *context.Context, g parallel.Group, sc } commit := func(id string, checksum string) error { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": id, }).Debug("commit screenshot") @@ -362,7 +362,7 @@ func (c *ascClient) UploadReviewAttachments(ctx *context.Context, reviewDetailID if attachment.Attributes.SourceFileChecksum != nil && *attachment.Attributes.SourceFileChecksum == checksum { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": attachment.ID, "checksum": checksum, }).Debug("skip existing attachment") @@ -370,7 +370,7 @@ func (c *ascClient) UploadReviewAttachments(ctx *context.Context, reviewDetailID return false, nil } - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, "id": attachment.ID, }).Debug("delete attachment") @@ -383,7 +383,7 @@ func (c *ascClient) UploadReviewAttachments(ctx *context.Context, reviewDetailID } create := func(name string, size int64) (id string, ops []asc.UploadOperation, err error) { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "name": name, }).Debug("create attachment") @@ -396,7 +396,7 @@ func (c *ascClient) UploadReviewAttachments(ctx *context.Context, reviewDetailID } commit := func(id string, checksum string) error { - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "id": id, }).Debug("commit attachment") diff --git a/internal/client/clienttest/clienttest_test.go b/internal/client/clienttest/clienttest_test.go index 47f749a..d58afee 100644 --- a/internal/client/clienttest/clienttest_test.go +++ b/internal/client/clienttest/clienttest_test.go @@ -33,6 +33,7 @@ func TestClient(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + c := clienttest.Client{} app, err := c.GetAppForBundleID(ctx, "TEST") diff --git a/internal/client/store.go b/internal/client/store.go index 5910345..99cc34b 100644 --- a/internal/client/store.go +++ b/internal/client/store.go @@ -23,7 +23,6 @@ package client import ( "fmt" - "github.com/apex/log" "github.com/cidertool/asc-go/asc" "github.com/cidertool/cider/internal/parallel" "github.com/cidertool/cider/pkg/config" @@ -236,11 +235,11 @@ func (c *ascClient) UpdateAppLocalizations(ctx *context.Context, appID string, c for i := range appLocResp.Data { loc := appLocResp.Data[i] locale := *loc.Attributes.Locale - log.WithField("locale", locale).Debug("found app locale") + ctx.Log.WithField("locale", locale).Debug("found app locale") locConfig, ok := config[locale] if !ok { - log.WithField("locale", locale).Debug("not in configuration. skipping...") + ctx.Log.WithField("locale", locale).Debug("not in configuration. skipping...") continue } @@ -339,11 +338,11 @@ func (c *ascClient) UpdateVersionLocalizations(ctx *context.Context, versionID s for i := range locListResp.Data { loc := locListResp.Data[i] locale := *loc.Attributes.Locale - log.WithField("locale", locale).Debug("found version locale") + ctx.Log.WithField("locale", locale).Debug("found version locale") locConfig, ok := config[locale] if !ok { - log.WithField("locale", locale).Debug("not in configuration. skipping...") + ctx.Log.WithField("locale", locale).Debug("not in configuration. skipping...") continue } @@ -351,7 +350,7 @@ func (c *ascClient) UpdateVersionLocalizations(ctx *context.Context, versionID s found[locale] = true g.Go(func() error { - log.WithField("locale", locale).Debug("update version locale") + ctx.Log.WithField("locale", locale).Debug("update version locale") updatedLocResp, _, err := c.client.Apps.UpdateAppStoreVersionLocalization(ctx, loc.ID, appStoreVersionLocalizationUpdateRequestAttributes(ctx, locConfig)) if err != nil { return err @@ -370,7 +369,7 @@ func (c *ascClient) UpdateVersionLocalizations(ctx *context.Context, versionID s locConfig := config[locale] g.Go(func() error { - log.WithField("locale", locale).Debug("create version locale") + ctx.Log.WithField("locale", locale).Debug("create version locale") locResp, _, err := c.client.Apps.CreateAppStoreVersionLocalization(ctx.Context, appStoreVersionLocalizationCreateRequestAttributes(ctx, locale, locConfig), versionID) if err != nil { return err diff --git a/internal/client/testflight.go b/internal/client/testflight.go index 45d1d5f..a82f53e 100644 --- a/internal/client/testflight.go +++ b/internal/client/testflight.go @@ -21,8 +21,8 @@ along with Cider. If not, see . package client import ( - "github.com/apex/log" "github.com/cidertool/asc-go/asc" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/parallel" "github.com/cidertool/cider/pkg/config" "github.com/cidertool/cider/pkg/context" @@ -41,11 +41,11 @@ func (c *ascClient) UpdateBetaAppLocalizations(ctx *context.Context, appID strin for i := range locListResp.Data { loc := locListResp.Data[i] locale := *loc.Attributes.Locale - log.WithField("locale", locale).Debug("found beta app locale") + ctx.Log.WithField("locale", locale).Debug("found beta app locale") locConfig, ok := config[locale] if !ok { - log.WithField("locale", locale).Debug("not in configuration. skipping...") + ctx.Log.WithField("locale", locale).Debug("not in configuration. skipping...") continue } @@ -150,15 +150,15 @@ func (c *ascClient) UpdateBetaBuildLocalizations(ctx *context.Context, buildID s for i := range locListResp.Data { loc := locListResp.Data[i] locale := *loc.Attributes.Locale - log.WithField("locale", locale).Debug("found beta build locale") + ctx.Log.WithField("locale", locale).Debug("found beta build locale") locConfig, ok := config[locale] if !ok { - log.WithField("locale", locale).Debug("not in configuration. skipping...") + ctx.Log.WithField("locale", locale).Debug("not in configuration. skipping...") continue } else if locConfig.WhatsNew == "" { - log.WithField("locale", locale).Warn("skipping updating beta build localization due to empty What's New text") + ctx.Log.WithField("locale", locale).Warn("skipping updating beta build localization due to empty What's New text") continue } @@ -181,7 +181,7 @@ func (c *ascClient) UpdateBetaBuildLocalizations(ctx *context.Context, buildID s locConfig := config[locale] if locConfig.WhatsNew == "" { - log.WithField("locale", locale).Warn("skipping updating beta build localization due to empty What's New text") + ctx.Log.WithField("locale", locale).Warn("skipping updating beta build localization due to empty What's New text") continue } @@ -215,7 +215,7 @@ func (c *ascClient) AssignBetaGroups(ctx *context.Context, appID string, buildID var g = parallel.New(ctx.MaxProcesses) if len(groups) == 0 { - log.Debug("no groups in configuration") + ctx.Log.Debug("no groups in configuration") return nil } @@ -249,13 +249,13 @@ func (c *ascClient) AssignBetaGroups(ctx *context.Context, appID string, buildID configGroup, ok := groupConfigs[name] if !ok { - log.WithField("group", name).Debug("not in configuration. skipping...") + ctx.Log.WithField("group", name).Debug("not in configuration. skipping...") continue } g.Go(func() error { - log.WithField("group", name).Debug("update beta group") + ctx.Log.WithField("group", name).Debug("update beta group") return c.updateBetaGroup(ctx, g, appID, group.ID, buildID, configGroup) }) @@ -264,7 +264,7 @@ func (c *ascClient) AssignBetaGroups(ctx *context.Context, appID string, buildID for i := range groups { group := groups[i] if group.Name == "" { - log.Warn("skipping a beta group with a missing name") + ctx.Log.Warn("skipping a beta group with a missing name") continue } else if found[group.Name] { @@ -272,7 +272,7 @@ func (c *ascClient) AssignBetaGroups(ctx *context.Context, appID string, buildID } g.Go(func() error { - log.WithField("group", group.Name).Debug("create beta group") + ctx.Log.WithField("group", group.Name).Debug("create beta group") return c.createBetaGroup(ctx, g, appID, buildID, group) }) @@ -345,7 +345,7 @@ func (c *ascClient) updateBetaTestersForGroup(ctx *context.Context, g parallel.G for i := range testers { tester := testers[i] if tester.Email == "" { - log.Warnf("skipping a beta tester in beta group %s with a missing email", groupID) + ctx.Log.Warnf("skipping a beta tester in beta group %s with a missing email", groupID) continue } else if found[tester.Email] { @@ -418,7 +418,7 @@ func (c *ascClient) AssignBetaTesters(ctx *context.Context, appID string, buildI found[email] = true g.Go(func() error { - log. + ctx.Log. WithFields(log.Fields{ "email": email, "build": buildID, @@ -433,7 +433,7 @@ func (c *ascClient) AssignBetaTesters(ctx *context.Context, appID string, buildI for i := range testers { tester := testers[i] if tester.Email == "" { - log.Warn("beta tester email missing") + ctx.Log.Warn("beta tester email missing") continue } else if found[tester.Email] { @@ -441,7 +441,7 @@ func (c *ascClient) AssignBetaTesters(ctx *context.Context, appID string, buildI } g.Go(func() error { - log.WithField("email", tester.Email).Debug("create individual beta tester") + ctx.Log.WithField("email", tester.Email).Debug("create individual beta tester") return c.createBetaTester(ctx, tester, nil, []string{buildID}) }) @@ -484,7 +484,7 @@ func (c *ascClient) listBetaTesters(ctx *context.Context, appID string, config [ func (c *ascClient) createBetaTester(ctx *context.Context, tester config.BetaTester, betaGroupIDs []string, buildIDs []string) error { if betaGroupIDs != nil && buildIDs != nil { - log.WithField("tester", tester).Warn("authors note: you can't define betaGroupIDs and buildIDs at the same time") + ctx.Log.WithField("tester", tester).Warn("authors note: you can't define betaGroupIDs and buildIDs at the same time") } _, _, err := c.client.TestFlight.CreateBetaTester(ctx, asc.BetaTesterCreateRequestAttributes{ @@ -520,7 +520,7 @@ func (c *ascClient) UpdateBetaReviewDetails(ctx *context.Context, appID string, attrs.Notes = &config.Notes if len(config.Attachments) > 0 { - log.Warn("attachments are not supported for beta review details and will be ignored") + ctx.Log.Warn("attachments are not supported for beta review details and will be ignored") } _, _, err = c.client.TestFlight.UpdateBetaAppReviewDetail(ctx, detailsResp.Data.ID, &attrs) diff --git a/internal/client/util_test.go b/internal/client/util_test.go index 23f3c19..ae1909e 100644 --- a/internal/client/util_test.go +++ b/internal/client/util_test.go @@ -31,7 +31,7 @@ import ( "path/filepath" "testing" - "github.com/apex/log" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/pkg/config" "github.com/cidertool/cider/pkg/context" "github.com/stretchr/testify/assert" @@ -67,7 +67,9 @@ type testAsset struct { func newTestContext(resp ...response) (*testContext, Client) { ctx := testContext{} + ctx.Context = context.New(config.Project{}) + server := httptest.NewServer(&ctx) ctx.Context.Credentials = &mockCredentials{ url: server.URL, @@ -86,14 +88,14 @@ func (c *testContext) Close() { func (c *testContext) ServeHTTP(w http.ResponseWriter, r *http.Request) { if c.CurrentResponseIndex >= len(c.Responses) { - log.WithFields(log.Fields{ + c.Context.Log.WithFields(log.Fields{ "currentResponseIndex": c.CurrentResponseIndex, "responsesCount": len(c.Responses), "url": r.URL, }).Fatal("index out of bounds") } - log.WithFields(log.Fields{ + c.Context.Log.WithFields(log.Fields{ "progress": fmt.Sprintf("(%d/%d)", c.CurrentResponseIndex, len(c.Responses)), "req_method": r.Method, "req_url": r.URL, diff --git a/internal/git/git_test.go b/internal/git/git_test.go index db42d5c..0476903 100644 --- a/internal/git/git_test.go +++ b/internal/git/git_test.go @@ -54,6 +54,7 @@ func TestNew(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + client := New(ctx) ok := client.IsRepo() assert.True(t, ok) @@ -69,6 +70,7 @@ func TestSanitizeProcess(t *testing.T) { } ctx := context.New(config.Project{}) + ctx.CurrentDirectory = "test" client := newMockGitWithContext( t, diff --git a/internal/log/log.go b/internal/log/log.go new file mode 100644 index 0000000..379555d --- /dev/null +++ b/internal/log/log.go @@ -0,0 +1,89 @@ +/** +Copyright (C) 2020 Aaron Sky. + +This file is part of Cider, a tool for automating submission +of apps to Apple's App Stores. + +Cider is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Cider is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Cider. If not, see . +*/ + +// Package log is a substitute for the global apex/log that is not thread safe. +package log + +import ( + "os" + "sync" + + "github.com/apex/log" + "github.com/apex/log/handlers/cli" + "github.com/fatih/color" +) + +// Interface is an extension of log.Interface. +type Interface interface { + log.Interface + SetColorMode(v bool) + SetDebug(v bool) + SetPadding(v int) +} + +// Fields re-exports log.Fields from github.com/apex/log. +type Fields = log.Fields + +// Log is a thread-safe wrapper for log.Logger. +type Log struct { + log.Logger + mu sync.RWMutex +} + +// New creates a new Log instance. +func New() *Log { + return &Log{ + Logger: log.Logger{ + Handler: cli.New(os.Stderr), + Level: log.InfoLevel, + }, + } +} + +// SetColorMode sets the global color mode for the logger. +func (l *Log) SetColorMode(v bool) { + l.mu.Lock() + defer l.mu.Unlock() + + color.NoColor = v +} + +// SetDebug sets the log level to Debug or Info. +func (l *Log) SetDebug(v bool) { + l.mu.Lock() + defer l.mu.Unlock() + + if v { + l.Logger.Level = log.DebugLevel + } else { + l.Logger.Level = log.InfoLevel + } +} + +// SetPadding sets the padding of the log handler in a thread-safe way. +func (l *Log) SetPadding(v int) { + l.mu.Lock() + defer l.mu.Unlock() + + if handler, ok := l.Handler.(*cli.Handler); ok { + handler.Padding = v + l.Handler = handler + } +} diff --git a/internal/log/log_test.go b/internal/log/log_test.go new file mode 100644 index 0000000..6f1b407 --- /dev/null +++ b/internal/log/log_test.go @@ -0,0 +1,23 @@ +/** +Copyright (C) 2020 Aaron Sky. + +This file is part of Cider, a tool for automating submission +of apps to Apple's App Stores. + +Cider is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Cider is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Cider. If not, see . +*/ + +package log + +// this package has no testable statements diff --git a/internal/middleware/error.go b/internal/middleware/error.go index b2f15fa..0af72f6 100644 --- a/internal/middleware/error.go +++ b/internal/middleware/error.go @@ -21,7 +21,6 @@ along with Cider. If not, see . package middleware import ( - "github.com/apex/log" "github.com/cidertool/cider/internal/pipe" "github.com/cidertool/cider/pkg/context" ) @@ -36,7 +35,7 @@ func ErrHandler(action Action) Action { } if pipe.IsSkip(err) { - log.WithError(err).Warn("pipe skipped") + ctx.Log.WithError(err).Warn("pipe skipped") return nil } diff --git a/internal/middleware/error_test.go b/internal/middleware/error_test.go index f818e67..f13aa45 100644 --- a/internal/middleware/error_test.go +++ b/internal/middleware/error_test.go @@ -36,9 +36,11 @@ func TestErrHandler_WrapsError(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + wrapped := ErrHandler(func(ctx *context.Context) error { return errTestError }) + err := wrapped(ctx) assert.Error(t, err) } @@ -47,9 +49,11 @@ func TestErrHandler_IgnoresNoError(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + wrapped := ErrHandler(func(ctx *context.Context) error { return nil }) + err := wrapped(ctx) assert.NoError(t, err) } @@ -58,9 +62,11 @@ func TestErrHandler_HandlesSkip(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + wrapped := ErrHandler(func(ctx *context.Context) error { return pipe.Skip("TEST") }) + err := wrapped(ctx) assert.NoError(t, err) } diff --git a/internal/middleware/logging.go b/internal/middleware/logging.go index b7f365e..3eb39b1 100644 --- a/internal/middleware/logging.go +++ b/internal/middleware/logging.go @@ -21,10 +21,6 @@ along with Cider. If not, see . package middleware import ( - "sync" - - "github.com/apex/log" - "github.com/apex/log/handlers/cli" "github.com/cidertool/cider/pkg/context" "github.com/fatih/color" ) @@ -38,9 +34,6 @@ const DefaultInitialPadding Padding = 3 // ExtraPadding is the double of the DefaultInitialPadding. const ExtraPadding Padding = DefaultInitialPadding * 2 -// nolint: gochecknoglobals -var loggerMu sync.Mutex - // Logging pretty prints the given action and its title. // You can have different padding levels by providing different initial // paddings. The middleware will print the title in the given padding and the @@ -49,18 +42,19 @@ var loggerMu sync.Mutex // The middleware always resets to the default padding. func Logging(title string, next Action, padding Padding) Action { return func(ctx *context.Context) error { - loggerMu.Lock() - defer loggerMu.Unlock() + if ctx.Log == nil { + return next(ctx) + } defer func() { - cli.Default.Padding = int(DefaultInitialPadding) + ctx.Log.SetPadding(int(DefaultInitialPadding)) }() - cli.Default.Padding = int(padding) + ctx.Log.SetPadding(int(padding)) - log.Info(color.New(color.Bold).Sprint(title)) + ctx.Log.Info(color.New(color.Bold).Sprint(title)) - cli.Default.Padding = int(padding + DefaultInitialPadding) + ctx.Log.SetPadding(int(padding + DefaultInitialPadding)) return next(ctx) } diff --git a/internal/middleware/logging_test.go b/internal/middleware/logging_test.go index f5c3acb..e240fd9 100644 --- a/internal/middleware/logging_test.go +++ b/internal/middleware/logging_test.go @@ -32,9 +32,11 @@ func TestLogging(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + wrapped := Logging("TEST", func(ctx *context.Context) error { return nil }, DefaultInitialPadding) + err := wrapped(ctx) assert.NoError(t, err) } diff --git a/internal/parallel/group_test.go b/internal/parallel/group_test.go index c3c55ce..50a4d00 100644 --- a/internal/parallel/group_test.go +++ b/internal/parallel/group_test.go @@ -29,15 +29,13 @@ import ( "github.com/stretchr/testify/assert" ) -// nolint: gochecknoglobals -var ( - errTestError = errors.New("TEST") - groupMu sync.Mutex -) +var errTestError = errors.New("TEST") func TestGroup(t *testing.T) { t.Parallel() + var groupMu sync.Mutex + var g = New(4) var counter int diff --git a/internal/pipe/defaults/defaults_test.go b/internal/pipe/defaults/defaults_test.go index 4539ffd..1486ded 100644 --- a/internal/pipe/defaults/defaults_test.go +++ b/internal/pipe/defaults/defaults_test.go @@ -36,6 +36,7 @@ func TestDefaults(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + pipe := Pipe{} var err error diff --git a/internal/pipe/env/env_test.go b/internal/pipe/env/env_test.go index 5bb5792..19a4444 100644 --- a/internal/pipe/env/env_test.go +++ b/internal/pipe/env/env_test.go @@ -34,6 +34,7 @@ func TestEnv(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + pipe := Pipe{} var err error diff --git a/internal/pipe/git/git.go b/internal/pipe/git/git.go index 9482ac6..3255e06 100644 --- a/internal/pipe/git/git.go +++ b/internal/pipe/git/git.go @@ -28,8 +28,8 @@ import ( "strings" "time" - "github.com/apex/log" "github.com/cidertool/cider/internal/git" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/pipe" "github.com/cidertool/cider/pkg/context" ) @@ -76,7 +76,7 @@ func (p Pipe) Run(ctx *context.Context) error { ctx.Git = info - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "commit": info.Commit, "tag": info.CurrentTag, "date": info.CommitDate.String(), @@ -93,7 +93,7 @@ func (p Pipe) Run(ctx *context.Context) error { ctx.Version = strings.TrimPrefix(tag, "v") } - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "version": ctx.Version, "commit": info.Commit, "workdir": ctx.CurrentDirectory, diff --git a/internal/pipe/git/git_test.go b/internal/pipe/git/git_test.go index 3d66f4a..e4596ec 100644 --- a/internal/pipe/git/git_test.go +++ b/internal/pipe/git/git_test.go @@ -21,7 +21,6 @@ along with Cider. If not, see . package git import ( - "os" "strconv" "testing" "time" @@ -45,7 +44,9 @@ func TestGit_Happy(t *testing.T) { CommitDate: time.Unix(1600914830, 0).UTC(), URL: "git@github.com:cidertool/cider.git", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, @@ -70,6 +71,7 @@ func TestGit_RealGitClient(t *testing.T) { ctx := context.New(config.Project{}) ctx.CurrentDirectory = "TEST" + p := Pipe{} err := p.Run(ctx) assert.EqualError(t, err, "the directory at TEST is not a git repository") @@ -81,50 +83,18 @@ func TestGit_SkipGit(t *testing.T) { ctx := context.New(config.Project{}) ctx.Version = "1.0" ctx.SkipGit = true + p := Pipe{} err := p.Run(ctx) assert.EqualError(t, err, pipe.ErrSkipGitEnabled.Error()) } -func TestGit_Happy_EnvCurrentTag(t *testing.T) { - t.Parallel() - - expected := context.GitInfo{ - CurrentTag: "1.0.0", - Commit: "abcdef1234567890abcdef1234567890abcdef12", - ShortCommit: "abcdef12", - FullCommit: "abcdef1234567890abcdef1234567890abcdef12", - CommitDate: time.Unix(1600914830, 0).UTC(), - URL: "git@github.com:cidertool/cider.git", - } - ctx := context.New(config.Project{}) - p := Pipe{} - p.client = newMockGitWithContext(ctx, - shelltest.Command{Stdout: "true"}, - shelltest.Command{Stdout: expected.ShortCommit}, - shelltest.Command{Stdout: expected.FullCommit}, - shelltest.Command{Stdout: strconv.FormatInt(expected.CommitDate.Unix(), 10)}, - shelltest.Command{Stdout: expected.URL}, - shelltest.Command{}, - shelltest.Command{Stdout: expected.CurrentTag}, - ) - - err := os.Setenv("CIDER_CURRENT_TAG", expected.CurrentTag) - assert.NoError(t, err) - - err = p.Run(ctx) - assert.NoError(t, err) - assert.Equal(t, expected, ctx.Git) - - err = os.Unsetenv("CIDER_CURRENT_TAG") - assert.NoError(t, err) -} - func TestGit_Err_NoGit(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + p := Pipe{} p.client = &git.Git{ Shell: &shelltest.Shell{ @@ -144,6 +114,7 @@ func TestGit_Err_NotInRepo(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{ReturnCode: 128, Stdout: "fatal"}, @@ -159,7 +130,9 @@ func TestGit_Err_BadCommit(t *testing.T) { expected := context.GitInfo{ ShortCommit: "abcdef12", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, @@ -184,7 +157,9 @@ func TestGit_Err_BadTime(t *testing.T) { ShortCommit: "abcdef12", FullCommit: "abcdef1234567890abcdef1234567890abcdef12", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, @@ -225,7 +200,9 @@ func TestGit_Err_BadTag(t *testing.T) { CommitDate: time.Unix(1600914830, 0).UTC(), URL: "git@github.com:cidertool/cider.git", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, @@ -251,7 +228,9 @@ func TestGit_Err_DirtyWorkingCopy(t *testing.T) { CommitDate: time.Unix(1600914830, 0).UTC(), URL: "git@github.com:cidertool/cider.git", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, @@ -278,7 +257,9 @@ func TestGit_Err_InvalidTag(t *testing.T) { CommitDate: time.Unix(1600914830, 0).UTC(), URL: "git@github.com:cidertool/cider.git", } + ctx := context.New(config.Project{}) + p := Pipe{} p.client = newMockGitWithContext(ctx, shelltest.Command{Stdout: "true"}, diff --git a/internal/pipe/publish/publish_test.go b/internal/pipe/publish/publish_test.go index f6accab..54524e1 100644 --- a/internal/pipe/publish/publish_test.go +++ b/internal/pipe/publish/publish_test.go @@ -46,6 +46,7 @@ func TestPublish_Happy_Testflight(t *testing.T) { ctx.AppsToRelease = []string{"TEST"} ctx.Credentials = &clienttest.Credentials{} ctx.PublishMode = context.PublishModeTestflight + p := Pipe{} p.client = &clienttest.Client{} @@ -62,6 +63,7 @@ func TestPublish_Happy_Store(t *testing.T) { ctx.AppsToRelease = []string{"TEST"} ctx.Credentials = &clienttest.Credentials{} ctx.PublishMode = context.PublishModeAppStore + p := Pipe{} p.client = &clienttest.Client{} @@ -73,6 +75,7 @@ func TestPublish_Happy_NoApps(t *testing.T) { t.Parallel() ctx := context.New(config.Project{}) + p := Pipe{} err := p.Run(ctx) @@ -84,6 +87,7 @@ func TestPublish_Err_NoPublishMode(t *testing.T) { ctx := context.New(config.Project{}) ctx.AppsToRelease = []string{"TEST"} + p := Pipe{} err := p.Run(ctx) @@ -99,6 +103,7 @@ func TestPublish_Err_AppMismatchTestflight(t *testing.T) { ctx.AppsToRelease = []string{"_TEST"} ctx.Credentials = &clienttest.Credentials{} ctx.PublishMode = context.PublishModeTestflight + p := Pipe{} p.client = &clienttest.Client{} @@ -115,6 +120,7 @@ func TestPublish_Err_AppMismatchStore(t *testing.T) { ctx.AppsToRelease = []string{"_TEST"} ctx.Credentials = &clienttest.Credentials{} ctx.PublishMode = context.PublishModeAppStore + p := Pipe{} p.client = &clienttest.Client{} diff --git a/internal/pipe/store/store.go b/internal/pipe/store/store.go index 1ce3ef4..57a0fa9 100644 --- a/internal/pipe/store/store.go +++ b/internal/pipe/store/store.go @@ -22,9 +22,9 @@ along with Cider. If not, see . package store import ( - "github.com/apex/log" "github.com/cidertool/asc-go/asc" "github.com/cidertool/cider/internal/client" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/pipe" "github.com/cidertool/cider/pkg/config" "github.com/cidertool/cider/pkg/context" @@ -52,7 +52,7 @@ func (p *Pipe) Publish(ctx *context.Context) error { return pipe.ErrMissingApp{Name: name} } - log.WithField("app", name).Info("updating metadata") + ctx.Log.WithField("app", name).Info("updating metadata") err := p.doRelease(ctx, app) if err != nil { @@ -86,16 +86,16 @@ func (p *Pipe) doRelease(ctx *context.Context, config config.App) error { return err } - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "app": *app.Attributes.BundleID, "build": *build.Attributes.Version, "version": *version.Attributes.VersionString, }).Info("found resources") if ctx.SkipUpdateMetadata { - log.Warn("skipping updating metdata") + ctx.Log.Warn("skipping updating metdata") } else { - log.Info("updating metadata") + ctx.Log.Info("updating metadata") if err := p.updateVersionDetails(ctx, config, app, version); err != nil { return err } @@ -106,14 +106,14 @@ func (p *Pipe) doRelease(ctx *context.Context, config config.App) error { } if config.Versions.PhasedReleaseEnabled && !ctx.VersionIsInitialRelease { - log.Info("preparing phased release details") + ctx.Log.Info("preparing phased release details") if err := p.Client.EnablePhasedRelease(ctx, version.ID); err != nil { return err } } - log. + ctx.Log. WithField("version", *version.Attributes.VersionString). Info("submitting to app store") @@ -126,26 +126,26 @@ func (p *Pipe) updateVersionDetails(ctx *context.Context, config config.App, app return err } - log.Info("updating app details") + ctx.Log.Info("updating app details") if err := p.Client.UpdateApp(ctx, app.ID, appInfo.ID, version.ID, config); err != nil { return err } - log.Infof("updating %d app localizations", len(config.Localizations)) + ctx.Log.Infof("updating %d app localizations", len(config.Localizations)) if err := p.Client.UpdateAppLocalizations(ctx, app.ID, config.Localizations); err != nil { return err } - log.Infof("updating %d app store version localizations", len(config.Versions.Localizations)) + ctx.Log.Infof("updating %d app store version localizations", len(config.Versions.Localizations)) if err := p.Client.UpdateVersionLocalizations(ctx, version.ID, config.Versions.Localizations); err != nil { return err } if config.Versions.IDFADeclaration != nil { - log.Info("updating IDFA declaration") + ctx.Log.Info("updating IDFA declaration") if err := p.Client.UpdateIDFADeclaration(ctx, version.ID, *config.Versions.IDFADeclaration); err != nil { return err @@ -153,7 +153,7 @@ func (p *Pipe) updateVersionDetails(ctx *context.Context, config config.App, app } if config.Versions.RoutingCoverage != nil { - log.Info("uploading routing coverage asset") + ctx.Log.Info("uploading routing coverage asset") if err := p.Client.UploadRoutingCoverage(ctx, version.ID, *config.Versions.RoutingCoverage); err != nil { return err @@ -161,7 +161,7 @@ func (p *Pipe) updateVersionDetails(ctx *context.Context, config config.App, app } if config.Versions.ReviewDetails != nil { - log.Info("updating review details") + ctx.Log.Info("updating review details") if err := p.Client.UpdateReviewDetails(ctx, version.ID, *config.Versions.ReviewDetails); err != nil { return err diff --git a/internal/pipe/store/store_test.go b/internal/pipe/store/store_test.go index 7d7ab5e..2cffc1f 100644 --- a/internal/pipe/store/store_test.go +++ b/internal/pipe/store/store_test.go @@ -61,6 +61,7 @@ func TestStore_Happy(t *testing.T) { }, }) ctx.AppsToRelease = []string{"TEST"} + p := Pipe{} p.Client = &clienttest.Client{} @@ -82,6 +83,7 @@ func TestStore_Happy_Skips(t *testing.T) { ctx.SkipUpdatePricing = true ctx.SkipUpdateMetadata = true ctx.SkipSubmit = true + p := Pipe{} p.Client = &clienttest.Client{} @@ -94,6 +96,7 @@ func TestStore_Happy_NoApps(t *testing.T) { ctx := context.New(config.Project{}) ctx.Credentials = &clienttest.Credentials{} + p := Pipe{} err := p.Publish(ctx) diff --git a/internal/pipe/testflight/testflight.go b/internal/pipe/testflight/testflight.go index d536e9b..01c087f 100644 --- a/internal/pipe/testflight/testflight.go +++ b/internal/pipe/testflight/testflight.go @@ -24,9 +24,9 @@ package testflight import ( "fmt" - "github.com/apex/log" "github.com/cidertool/asc-go/asc" "github.com/cidertool/cider/internal/client" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/internal/pipe" "github.com/cidertool/cider/pkg/config" "github.com/cidertool/cider/pkg/context" @@ -54,7 +54,7 @@ func (p *Pipe) Publish(ctx *context.Context) error { return pipe.ErrMissingApp{Name: name} } - log.WithField("name", name).Info("preparing") + ctx.Log.WithField("name", name).Info("preparing") err := p.doRelease(ctx, app) if err != nil { @@ -78,15 +78,15 @@ func (p *Pipe) doRelease(ctx *context.Context, config config.App) error { buildVersionLog := fmt.Sprintf("%s (%s)", ctx.Version, *build.Attributes.Version) - log.WithFields(log.Fields{ + ctx.Log.WithFields(log.Fields{ "app": *app.Attributes.BundleID, "build": buildVersionLog, }).Info("found resources") if ctx.SkipUpdateMetadata { - log.Warn("skipping updating metdata") + ctx.Log.Warn("skipping updating metdata") } else { - log.Info("updating metadata") + ctx.Log.Info("updating metadata") if err := p.updateBetaDetails(ctx, config, app, build); err != nil { return err } @@ -108,7 +108,7 @@ func (p *Pipe) doRelease(ctx *context.Context, config config.App) error { return pipe.ErrSkipSubmitEnabled } - log. + ctx.Log. WithField("build", buildVersionLog). Info("submitting to testflight") @@ -116,32 +116,32 @@ func (p *Pipe) doRelease(ctx *context.Context, config config.App) error { } func (p *Pipe) updateBetaDetails(ctx *context.Context, config config.App, app *asc.App, build *asc.Build) error { - log.Infof("updating %d beta app localizations", len(config.Testflight.Localizations)) + ctx.Log.Infof("updating %d beta app localizations", len(config.Testflight.Localizations)) if err := p.Client.UpdateBetaAppLocalizations(ctx, app.ID, config.Testflight.Localizations); err != nil { return err } - log.Info("updating beta build details") + ctx.Log.Info("updating beta build details") if err := p.Client.UpdateBetaBuildDetails(ctx, build.ID, config.Testflight); err != nil { return err } - log.Infof("updating %d beta build localizations", len(config.Testflight.Localizations)) + ctx.Log.Infof("updating %d beta build localizations", len(config.Testflight.Localizations)) if err := p.Client.UpdateBetaBuildLocalizations(ctx, build.ID, config.Testflight.Localizations); err != nil { return err } - log.Info("updating beta license agreement") + ctx.Log.Info("updating beta license agreement") if err := p.Client.UpdateBetaLicenseAgreement(ctx, app.ID, config.Testflight); err != nil { return err } if config.Testflight.ReviewDetails != nil { - log.Info("updating beta review details") + ctx.Log.Info("updating beta review details") if err := p.Client.UpdateBetaReviewDetails(ctx, app.ID, *config.Testflight.ReviewDetails); err != nil { return err @@ -152,13 +152,13 @@ func (p *Pipe) updateBetaDetails(ctx *context.Context, config config.App, app *a } func (p *Pipe) updateBetaGroups(ctx *context.Context, config config.App, app *asc.App, build *asc.Build) error { - log.Info("updating build beta groups") + ctx.Log.Info("updating build beta groups") return p.Client.AssignBetaGroups(ctx, app.ID, build.ID, config.Testflight.BetaGroups) } func (p *Pipe) updateBetaTesters(ctx *context.Context, config config.App, app *asc.App, build *asc.Build) error { - log.Info("updating build beta testers") + ctx.Log.Info("updating build beta testers") return p.Client.AssignBetaTesters(ctx, app.ID, build.ID, config.Testflight.BetaTesters) } diff --git a/internal/pipe/testflight/testflight_test.go b/internal/pipe/testflight/testflight_test.go index cc113e2..b4b0b8f 100644 --- a/internal/pipe/testflight/testflight_test.go +++ b/internal/pipe/testflight/testflight_test.go @@ -54,6 +54,7 @@ func TestTestflight_Happy(t *testing.T) { }, }) ctx.AppsToRelease = []string{"TEST"} + p := Pipe{} p.Client = &clienttest.Client{} @@ -74,6 +75,7 @@ func TestTestflight_Happy_Skips(t *testing.T) { ctx.AppsToRelease = []string{"TEST"} ctx.SkipUpdateMetadata = true ctx.SkipSubmit = true + p := Pipe{} p.Client = &clienttest.Client{} @@ -86,6 +88,7 @@ func TestTestflight_Happy_NoApps(t *testing.T) { ctx := context.New(config.Project{}) ctx.Credentials = &clienttest.Credentials{} + p := Pipe{} err := p.Publish(ctx) diff --git a/internal/shell/shell.go b/internal/shell/shell.go index 74ef442..81242b2 100644 --- a/internal/shell/shell.go +++ b/internal/shell/shell.go @@ -27,7 +27,7 @@ import ( "strings" "github.com/alessio/shellescape" - "github.com/apex/log" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/pkg/context" ) @@ -116,15 +116,15 @@ func escapeArgs(args []string) []string { // Exec executes a command. func (sh *loginShell) Exec(cmd *exec.Cmd) (proc *CompletedProcess, err error) { - log.WithField("args", cmd.Args).Debug(cmd.Path) + sh.Context.Log.WithField("args", cmd.Args).Debug(cmd.Path) err = cmd.Run() proc = newCompletedProcess(cmd) if proc == nil { - log.Debugf("last process failed to complete coherently") + sh.Context.Log.Debugf("last process failed to complete coherently") } else { - log.WithFields(log.Fields{ + sh.Context.Log.WithFields(log.Fields{ "code": proc.ReturnCode, "stdout": strings.TrimSpace(proc.Stdout), "stderr": strings.TrimSpace(proc.Stderr), diff --git a/pkg/context/context.go b/pkg/context/context.go index e9a148b..7387c2f 100644 --- a/pkg/context/context.go +++ b/pkg/context/context.go @@ -28,6 +28,7 @@ import ( "strings" "time" + "github.com/cidertool/cider/internal/log" "github.com/cidertool/cider/pkg/config" ) @@ -61,6 +62,7 @@ type Context struct { Credentials Credentials AppsToRelease []string PublishMode PublishMode + Log log.Interface MaxProcesses int SkipGit bool SkipUpdatePricing bool @@ -116,6 +118,7 @@ func Wrap(ctx ctx.Context, config config.Project) *Context { RawConfig: config, Env: splitEnv(os.Environ()), Date: time.Now(), + Log: log.New(), MaxProcesses: 1, } } diff --git a/pkg/context/context_test.go b/pkg/context/context_test.go index 728d52e..6f18547 100644 --- a/pkg/context/context_test.go +++ b/pkg/context/context_test.go @@ -21,7 +21,6 @@ along with Cider. If not, see . package context import ( - "os" "testing" "time" @@ -32,10 +31,8 @@ import ( func TestNew(t *testing.T) { t.Parallel() - assert.NoError(t, os.Setenv("TEST", "DOG")) - ctx := New(config.Project{}) - assert.Equal(t, "DOG", ctx.Env["TEST"]) + assert.Equal(t, 1, ctx.MaxProcesses) } func TestNewWithTimeout(t *testing.T) { diff --git a/tools/licensing/main.go b/tools/licensing/main.go index 4cc8407..d62214d 100644 --- a/tools/licensing/main.go +++ b/tools/licensing/main.go @@ -49,11 +49,6 @@ You should have received a copy of the GNU General Public License along with Cider. If not, see . */` -type exitFunc func(int) - -// nolint:gochecknoglobals -var exit exitFunc = os.Exit - func main() { var cmd = &cobra.Command{ Use: "licensing", @@ -72,7 +67,7 @@ func main() { log.WithError(err).Error(msg) - exit(code) + os.Exit(code) } }