From 7c300b6974533c4bddefe41cf8daea8e73ccd055 Mon Sep 17 00:00:00 2001 From: Eduardo Asafe Date: Mon, 1 Apr 2024 04:26:51 -0300 Subject: [PATCH 1/3] Multiple accounts for deployment Add support for several --account flags. The accounts passed must already have been logged in. `force import` uses a mutex to synchonize concurrent deployments. --- command/deploy.go | 93 +++++++++++++++++++++++++++++------------------ command/import.go | 37 ++++++++++++++++--- command/logout.go | 2 +- command/root.go | 70 +++++++++++++++++++++++++++++++++-- lib/metadata.go | 3 +- 5 files changed, 158 insertions(+), 47 deletions(-) diff --git a/command/deploy.go b/command/deploy.go index b7a6c6e6..af9e6d15 100644 --- a/command/deploy.go +++ b/command/deploy.go @@ -6,10 +6,10 @@ import ( "os" "os/signal" "strings" + "sync" "syscall" "time" - . "github.com/ForceCLI/force/error" . "github.com/ForceCLI/force/lib" "github.com/spf13/cobra" ) @@ -38,53 +38,41 @@ func defaultDeployOutputOptions() *deployOutputOptions { var testFailureError = errors.New("Apex tests failed") -func monitorDeploy(deployId string) (ForceCheckDeploymentStatusResult, error) { - var result ForceCheckDeploymentStatusResult - var err error - retrying := false - for { - result, err = force.Metadata.CheckDeployStatus(deployId) - if err != nil { - if retrying { - return result, fmt.Errorf("Error getting deploy status: %w", err) - } else { - retrying = true - Log.Info(fmt.Sprintf("Received error checking deploy status: %s. Will retry once before aborting.", err.Error())) - } - } else { - retrying = false - } - if result.Done { - break - } - if !retrying { - Log.Info(result) - } - time.Sleep(5000 * time.Millisecond) - } - return result, err +type deployStatus struct { + mu sync.Mutex + aborted bool +} + +func (c *deployStatus) abort() { + c.mu.Lock() + c.aborted = true + c.mu.Unlock() +} + +func (c *deployStatus) isAborted() bool { + c.mu.Lock() + defer c.mu.Unlock() + return c.aborted } func deploy(force *Force, files ForceMetadataFiles, deployOptions *ForceDeployOptions, outputOptions *deployOutputOptions) error { - if outputOptions.quiet { - previousLogger := Log - var l quietLogger - Log = l - defer func() { - Log = previousLogger - }() - } + status := deployStatus{aborted: false} + + return deployWith(force, &status, files, deployOptions, outputOptions) +} + +func deployWith(force *Force, status *deployStatus, files ForceMetadataFiles, deployOptions *ForceDeployOptions, outputOptions *deployOutputOptions) error { startTime := time.Now() deployId, err := force.Metadata.StartDeploy(files, *deployOptions) if err != nil { - ErrorAndExit(err.Error()) + return err } stopDeployUponSignal(force, deployId) if outputOptions.interactive { watchDeploy(deployId) return nil } - result, err := monitorDeploy(deployId) + result, err := monitorDeploy(force, deployId, status) if err != nil { return err } @@ -156,6 +144,39 @@ func deploy(force *Force, files ForceMetadataFiles, deployOptions *ForceDeployOp return nil } +func monitorDeploy(force *Force, deployId string, status *deployStatus) (ForceCheckDeploymentStatusResult, error) { + var result ForceCheckDeploymentStatusResult + var err error + retrying := false + for { + if status.isAborted() { + fmt.Fprintf(os.Stderr, "Cancelling deploy %s\n", deployId) + force.Metadata.CancelDeploy(deployId) + return result, nil + } + result, err = force.Metadata.CheckDeployStatus(deployId) + if err != nil { + if retrying { + return result, fmt.Errorf("Error getting deploy status: %w", err) + } else { + retrying = true + Log.Info(fmt.Sprintf("Received error checking deploy status: %s. Will retry once before aborting.", err.Error())) + } + } else { + retrying = false + } + result.UserName = force.GetCredentials().UserInfo.UserName + if result.Done { + break + } + if !retrying { + Log.Info(result) + } + time.Sleep(5000 * time.Millisecond) + } + return result, err +} + func stopDeployUponSignal(force *Force, deployId string) { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) diff --git a/command/import.go b/command/import.go index 1090f266..1ca0944b 100644 --- a/command/import.go +++ b/command/import.go @@ -8,6 +8,7 @@ import ( "os/user" "path/filepath" "strings" + "sync" . "github.com/ForceCLI/force/error" . "github.com/ForceCLI/force/lib" @@ -92,6 +93,14 @@ func sourceDir(cmd *cobra.Command) string { } func runImport(root string, options ForceDeployOptions, displayOptions *deployOutputOptions) { + if displayOptions.quiet { + previousLogger := Log + var l quietLogger + Log = l + defer func() { + Log = previousLogger + }() + } files := make(ForceMetadataFiles) if _, err := os.Stat(filepath.Join(root, "package.xml")); os.IsNotExist(err) { ErrorAndExit(" \n" + filepath.Join(root, "package.xml") + "\ndoes not exist") @@ -113,11 +122,27 @@ func runImport(root string, options ForceDeployOptions, displayOptions *deployOu ErrorAndExit(err.Error()) } - err = deploy(force, files, &options, displayOptions) - if err == nil && displayOptions.reportFormat == "text" && !displayOptions.quiet { - fmt.Printf("Imported from %s\n", root) - } - if err != nil && (!errors.Is(err, testFailureError) || displayOptions.errorOnTestFailure) { - ErrorAndExit(err.Error()) + var deployments sync.WaitGroup + status := deployStatus{aborted: false} + + for _, f := range manager.getAllForce() { + if status.isAborted() { + break + } + current := f + deployments.Add(1) + go func() { + defer deployments.Done() + err := deployWith(current, &status, files, &options, displayOptions) + if err == nil && displayOptions.reportFormat == "text" && !displayOptions.quiet { + fmt.Printf("Imported from %s\n", root) + } + if err != nil && (!errors.Is(err, testFailureError) || displayOptions.errorOnTestFailure) && !status.isAborted() { + fmt.Fprintf(os.Stderr, "Aborting deploy due to %s\n", err.Error()) + status.abort() + } + }() } + + deployments.Wait() } diff --git a/command/logout.go b/command/logout.go index 525e0980..72572e95 100644 --- a/command/logout.go +++ b/command/logout.go @@ -37,7 +37,7 @@ func runLogout() { SetActiveLoginDefault() } if runtime.GOOS == "windows" { - cmd := exec.Command("title", account) + cmd := exec.Command("title", username) cmd.Run() } else { title := fmt.Sprintf("\033];%s\007", "") diff --git a/command/root.go b/command/root.go index 6e2621b0..54a98e65 100644 --- a/command/root.go +++ b/command/root.go @@ -14,11 +14,12 @@ import ( ) var ( - account string + accounts []string configName string _apiVersion string - force *Force + manager forceManager + force *Force ) func init() { @@ -30,7 +31,7 @@ func init() { } } RootCmd.SetArgs(args) - RootCmd.PersistentFlags().StringVarP(&account, "account", "a", "", "account `username` to use") + RootCmd.PersistentFlags().StringArrayVarP(&accounts, "account", "a", []string{}, "account `username` to use") RootCmd.PersistentFlags().StringVar(&configName, "config", "", "config directory to use (default: .force)") RootCmd.PersistentFlags().StringVarP(&_apiVersion, "apiversion", "V", "", "API version to use") } @@ -75,6 +76,7 @@ func envSession() *Force { } func initializeSession() { +<<<<<<< HEAD var err error if account != "" { force, err = GetForce(account) @@ -84,12 +86,18 @@ func initializeSession() { if err != nil { ErrorAndExit(err.Error()) } +======= + manager = newForceManager(accounts) + +>>>>>>> 75cc0f4 (Multiple accounts for deployment) if _apiVersion != "" { err := SetApiVersion(_apiVersion) if err != nil { ErrorAndExit(err.Error()) } } + + force = manager.getCurrentForce() } func Execute() { @@ -103,3 +111,59 @@ type quietLogger struct{} func (l quietLogger) Info(args ...interface{}) { } + +// provides support for commands that can be run concurrently for many accounts +type forceManager struct { + connections map[string]*Force + currentAccount string +} + +func (manager forceManager) getCurrentForce() *Force { + return manager.connections[manager.currentAccount] +} + +func (manager forceManager) getAllForce() []*Force { + fs := make([]*Force, 0, len(manager.connections)) + + for _, v := range manager.connections { + fs = append(fs, v) + } + return fs +} + +func newForceManager(accounts []string) forceManager { + var err error + fm := forceManager{connections: make(map[string]*Force, 1)} + + if len(accounts) > 1 { + for _, a := range accounts { + var f *Force + + f, err = GetForce(a) + if err != nil { + ErrorAndExit(err.Error()) + } + + fm.connections[a] = f + } + + fm.currentAccount = accounts[0] + } else { + var f *Force + + if len(accounts) == 1 { + f, err = GetForce(accounts[0]) + } else if f = envSession(); f == nil { + f, err = ActiveForce() + } + + if err != nil { + ErrorAndExit(err.Error()) + } + + fm.currentAccount = f.GetCredentials().UserInfo.UserName + fm.connections[fm.currentAccount] = f + } + + return fm +} diff --git a/lib/metadata.go b/lib/metadata.go index c58da314..f174a9b5 100644 --- a/lib/metadata.go +++ b/lib/metadata.go @@ -174,6 +174,7 @@ type ComponentDetails struct { } type ForceCheckDeploymentStatusResult struct { + UserName string CheckOnly bool `xml:"checkOnly"` CompletedDate time.Time `xml:"completedDate"` CreatedDate time.Time `xml:"createdDate"` @@ -745,7 +746,7 @@ func (results ForceCheckDeploymentStatusResult) String() string { complete = fmt.Sprintf(" (%d/%d)", results.NumberTestsCompleted, results.NumberTestsTotal) } - return fmt.Sprintf("Status: %s%s %s", results.Status, complete, results.StateDetail) + return fmt.Sprintf("Status (%s): %s%s %s", results.UserName, results.Status, complete, results.StateDetail) } func (fm *ForceMetadata) CancelDeploy(id string) (ForceCancelDeployResult, error) { From ec24b696e1c04a874c55434919a9828bb0b476dd Mon Sep 17 00:00:00 2001 From: Eduardo Asafe Date: Mon, 1 Jul 2024 08:29:25 -0300 Subject: [PATCH 2/3] Split test runs among deployments If more than one account is passed for a deployment with `force import` divide test runs between deployments. --- .gitignore | 4 +- command/deploy.go | 6 +- command/field.go | 2 +- command/import.go | 171 +++++++++++++++++++++++++++++++++++++++------- command/push.go | 6 +- go.mod | 13 ++-- go.sum | 12 ++++ 7 files changed, 179 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index f49614e6..f8d6ce12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ .DS_Store metadata/ +src/ +.sfdx/ # Force CLI specific things force metadata -test +test *.json diff --git a/command/deploy.go b/command/deploy.go index af9e6d15..d2be43d8 100644 --- a/command/deploy.go +++ b/command/deploy.go @@ -55,15 +55,15 @@ func (c *deployStatus) isAborted() bool { return c.aborted } -func deploy(force *Force, files ForceMetadataFiles, deployOptions *ForceDeployOptions, outputOptions *deployOutputOptions) error { +func deploy(force *Force, files ForceMetadataFiles, deployOptions ForceDeployOptions, outputOptions *deployOutputOptions) error { status := deployStatus{aborted: false} return deployWith(force, &status, files, deployOptions, outputOptions) } -func deployWith(force *Force, status *deployStatus, files ForceMetadataFiles, deployOptions *ForceDeployOptions, outputOptions *deployOutputOptions) error { +func deployWith(force *Force, status *deployStatus, files ForceMetadataFiles, deployOptions ForceDeployOptions, outputOptions *deployOutputOptions) error { startTime := time.Now() - deployId, err := force.Metadata.StartDeploy(files, *deployOptions) + deployId, err := force.Metadata.StartDeploy(files, deployOptions) if err != nil { return err } diff --git a/command/field.go b/command/field.go index 7bf01be7..4557725b 100644 --- a/command/field.go +++ b/command/field.go @@ -173,7 +173,7 @@ func updateFLSOnProfile(force *Force, objectName string, fieldName string) (err } displayOptions := defaultDeployOutputOptions() displayOptions.quiet = true - return deploy(force, pb.ForceMetadataFiles(), new(ForceDeployOptions), displayOptions) + return deploy(force, pb.ForceMetadataFiles(), ForceDeployOptions{}, displayOptions) } func getFLSUpdateXML(objectName string, fieldName string) string { diff --git a/command/import.go b/command/import.go index 1ca0944b..4d63f200 100644 --- a/command/import.go +++ b/command/import.go @@ -7,14 +7,38 @@ import ( "os" "os/user" "path/filepath" + "slices" + "sort" "strings" "sync" . "github.com/ForceCLI/force/error" . "github.com/ForceCLI/force/lib" + + "github.com/antlr4-go/antlr/v4" + "github.com/octoberswimmer/apexfmt/parser" "github.com/spf13/cobra" ) +var importCmd = &cobra.Command{ + Use: "import", + Short: "Import metadata from a local directory", + Example: ` + force import + force import -directory=my_metadata -c -r -v + force import -checkonly -runalltests +`, + Run: func(cmd *cobra.Command, args []string) { + options := getDeploymentOptions(cmd) + srcDir := sourceDir(cmd) + + displayOptions := getDeploymentOutputOptions(cmd) + + runImport(srcDir, options, displayOptions) + }, + Args: cobra.MaximumNArgs(0), +} + func init() { // Deploy options importCmd.Flags().BoolP("rollbackonerror", "r", false, "roll back deployment on error") @@ -25,7 +49,8 @@ func init() { importCmd.Flags().BoolP("allowmissingfiles", "m", false, "set allow missing files") importCmd.Flags().BoolP("autoupdatepackage", "u", false, "set auto update package") importCmd.Flags().BoolP("ignorewarnings", "i", false, "ignore warnings") - importCmd.Flags().StringSliceP("test", "", []string{}, "Test(s) to run") + importCmd.Flags().BoolP("splittests", "s", false, "split tests between deployments") + importCmd.Flags().StringSliceP("test", "", []string{}, "test(s) to run") // Output options importCmd.Flags().BoolP("ignorecoverage", "w", false, "suppress code coverage warnings") @@ -42,25 +67,6 @@ func init() { RootCmd.AddCommand(importCmd) } -var importCmd = &cobra.Command{ - Use: "import", - Short: "Import metadata from a local directory", - Example: ` - force import - force import -directory=my_metadata -c -r -v - force import -checkonly -runalltests -`, - Run: func(cmd *cobra.Command, args []string) { - options := getDeploymentOptions(cmd) - srcDir := sourceDir(cmd) - - displayOptions := getDeploymentOutputOptions(cmd) - - runImport(srcDir, options, displayOptions) - }, - Args: cobra.MaximumNArgs(0), -} - func sourceDir(cmd *cobra.Command) string { directory, _ := cmd.Flags().GetString("directory") @@ -92,7 +98,7 @@ func sourceDir(cmd *cobra.Command) string { return root } -func runImport(root string, options ForceDeployOptions, displayOptions *deployOutputOptions) { +func runImport(root string, baseOptions ForceDeployOptions, displayOptions *deployOutputOptions) { if displayOptions.quiet { previousLogger := Log var l quietLogger @@ -124,16 +130,27 @@ func runImport(root string, options ForceDeployOptions, displayOptions *deployOu var deployments sync.WaitGroup status := deployStatus{aborted: false} + forces := manager.getAllForce() + var options []ForceDeployOptions + if baseOptions.TestLevel == "NoTestRun" || len(forces) == 1 { + options = make([]ForceDeployOptions, len(forces)) + for i := range options { + options[i] = baseOptions + } + } else { + options = splitTests(baseOptions, files, len(forces)) + } - for _, f := range manager.getAllForce() { + for i, f := range forces { if status.isAborted() { break } current := f + index := i deployments.Add(1) go func() { defer deployments.Done() - err := deployWith(current, &status, files, &options, displayOptions) + err := deployWith(current, &status, files, options[index], displayOptions) if err == nil && displayOptions.reportFormat == "text" && !displayOptions.quiet { fmt.Printf("Imported from %s\n", root) } @@ -146,3 +163,111 @@ func runImport(root string, options ForceDeployOptions, displayOptions *deployOu deployments.Wait() } + +// Evenly distribute tests to be run among deployments by counting how many test methods each (test) class has +func splitTests(ops ForceDeployOptions, files ForceMetadataFiles, deployments int) []ForceDeployOptions { + //what about RunAllTestsInOrg? + options := make([]ForceDeployOptions, deployments) + testClasses := makeTestClasses(ops, files) + split := splitByDeployments(testClasses, deployments) + + for i, s := range split { + options[i] = ops + options[i].RunTests = make([]string, len(s)) + + for j, className := range s { + options[i].RunTests[j] = className.name + } + } + + return options +} + +type testClass struct { + name string + methods int +} + +func makeTestClasses(ops ForceDeployOptions, files ForceMetadataFiles) []testClass { + allTests := len(ops.RunTests) == 0 + testClasses := make([]testClass, 0) + folderPreffix := "classes" + string(os.PathSeparator) + + for fileName, contents := range files { + name, isClass := strings.CutSuffix(fileName, ".cls") + + if isClass && (allTests || slices.Contains(ops.RunTests, name)) { + count := testMethods(contents) + + if count > 0 { + testClasses = append(testClasses, testClass{name: strings.TrimPrefix(name, folderPreffix), methods: count}) + } + } + } + + return testClasses +} + +type testClassListener struct { + *parser.BaseApexParserListener + methods int +} + +func (t *testClassListener) EnterModifier(ctx *parser.ModifierContext) { + if ctx.TESTMETHOD() != nil { + t.methods += 1 + } +} + +func (t *testClassListener) EnterAnnotation(ctx *parser.AnnotationContext) { + annotation := ctx.QualifiedName() + + if annotation != nil && strings.ToUpper(annotation.GetText()) == "ISTEST" { + t.methods += 1 + } +} + +func testMethods(src []byte) int { + input := antlr.NewInputStream(string(src)) + lexer := parser.NewApexLexer(input) + stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) + p := parser.NewApexParser(stream) + listener := new(testClassListener) + + p.RemoveErrorListeners() + antlr.ParseTreeWalkerDefault.Walk(listener, p.CompilationUnit()) + + return listener.methods +} + +type byMethods []testClass + +func (a byMethods) Len() int { return len(a) } +func (a byMethods) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byMethods) Less(i, j int) bool { return a[i].methods > a[j].methods } + +func splitByDeployments(classes []testClass, n int) [][]testClass { + sort.Sort(byMethods(classes)) + groups := make([][]testClass, n) + + for i := range groups { + groups[i] = []testClass{} + } + + methodCounts := make([]int, n) + + for _, class := range classes { + // Find the group with the least number of methods + minIdx := 0 + for i := 1; i < n; i++ { + if methodCounts[i] < methodCounts[minIdx] { + minIdx = i + } + } + + groups[minIdx] = append(groups[minIdx], class) + methodCounts[minIdx] += class.methods + } + + return groups +} diff --git a/command/push.go b/command/push.go index 72cea280..2c0aebba 100644 --- a/command/push.go +++ b/command/push.go @@ -173,7 +173,7 @@ func pushByPaths(resourcePaths []string, deployOptions *ForceDeployOptions, disp ErrorAndExit("Could not add %s: %s", p, err.Error()) } } - err = deploy(force, pb.ForceMetadataFiles(), deployOptions, displayOptions) + err = deploy(force, pb.ForceMetadataFiles(), *deployOptions, displayOptions) if err != nil { ErrorAndExit(err.Error()) } @@ -198,7 +198,7 @@ func pushByMetadataType(metadataType string, metadataNames []string, deployOptio } } - err = deploy(force, pb.ForceMetadataFiles(), deployOptions, displayOptions) + err = deploy(force, pb.ForceMetadataFiles(), *deployOptions, displayOptions) if err != nil { ErrorAndExit(err.Error()) } @@ -217,7 +217,7 @@ func pushMetadataTypes(metadataTypes []string, deployOptions *ForceDeployOptions } } - err = deploy(force, pb.ForceMetadataFiles(), deployOptions, displayOptions) + err = deploy(force, pb.ForceMetadataFiles(), *deployOptions, displayOptions) if err != nil { ErrorAndExit(err.Error()) } diff --git a/go.mod b/go.mod index 81036087..64a63669 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,15 @@ module github.com/ForceCLI/force -go 1.20 +go 1.22 + +toolchain go1.22.4 require ( github.com/ForceCLI/config v0.0.0-20230217143549-9149d42a3c99 github.com/ForceCLI/force-md v0.0.0-20240126214027-5b906037b66a github.com/ForceCLI/inflect v0.0.0-20130829110746-cc00b5ad7a6a github.com/ViViDboarder/gotifier v0.0.0-20140619195515-0f19f3d7c54c + github.com/antlr4-go/antlr/v4 v4.13.1 github.com/antonmedv/expr v1.15.3 github.com/bgentry/speakeasy v0.1.0 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 @@ -19,12 +22,13 @@ require ( github.com/hamba/avro/v2 v2.16.0 github.com/linkedin/goavro/v2 v2.12.0 github.com/obeattie/ohmyglob v0.0.0-20150811221449-290764208a0d + github.com/octoberswimmer/apexfmt v0.0.0-20240326123316-6d1990ec1d8b github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/ginkgo v1.12.0 github.com/onsi/gomega v1.10.0 github.com/pkg/errors v0.9.1 github.com/rgalanakis/golangal v0.0.0-20210923203926-e36008487518 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 golang.org/x/crypto v0.14.0 google.golang.org/grpc v1.39.0-dev google.golang.org/protobuf v1.28.1 @@ -36,7 +40,7 @@ require ( github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -62,8 +66,9 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.1.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index 02fe7826..b78151eb 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/ForceCLI/inflect v0.0.0-20130829110746-cc00b5ad7a6a h1:mMd54YgLoeupNp github.com/ForceCLI/inflect v0.0.0-20130829110746-cc00b5ad7a6a/go.mod h1:DGKmCfb9oo5BivGO+szHk2ZvlqPDTlW4AYVpRBIVbms= github.com/ViViDboarder/gotifier v0.0.0-20140619195515-0f19f3d7c54c h1:qLWjxZGLdzxp0Gc4Sf6f4w15D+wNKZ28HhkV9y5cAhw= github.com/ViViDboarder/gotifier v0.0.0-20140619195515-0f19f3d7c54c/go.mod h1:/nH+y85gO3ta3b6JtRWGA5hPIH35XJr/ZHXlfrBRx3A= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/antonmedv/expr v1.15.3 h1:q3hOJZNvLvhqE8OHBs1cFRdbXFNKuA+bHmRaI+AmRmI= github.com/antonmedv/expr v1.15.3/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -35,6 +37,8 @@ github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2 github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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= @@ -123,6 +127,8 @@ github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/obeattie/ohmyglob v0.0.0-20150811221449-290764208a0d h1:SIsYJszBZOjUGo91Z3x3LufvYRZ2CwB+F4EKK5b53iw= github.com/obeattie/ohmyglob v0.0.0-20150811221449-290764208a0d/go.mod h1:hFInPnl2+HgL1AruAAgDGZa0EQBpTLIMU0PObAVi1ow= +github.com/octoberswimmer/apexfmt v0.0.0-20240326123316-6d1990ec1d8b h1:uikahGNfSrrauRMQf0L4ZZuvc2z7aqGPLMYsYV6t2/8= +github.com/octoberswimmer/apexfmt v0.0.0-20240326123316-6d1990ec1d8b/go.mod h1:X6i1fOO3s/tLtpMlSt2m5h1p6G2Ks0zuzF10Umt6Jog= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -150,6 +156,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -164,6 +172,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= 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-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -180,6 +190,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 518eb7d36baecfa4557cf85bb0dec2c1b1245c0a Mon Sep 17 00:00:00 2001 From: Eduardo Asafe Date: Thu, 21 Nov 2024 12:59:31 -0300 Subject: [PATCH 3/3] Update ci --- .circleci/config.yml | 2 +- command/root.go | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 75ed328c..02356a9b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: cimg/go:1.20 + - image: cimg/go:1.22 steps: - checkout - run: go install github.com/mitchellh/gox@v1.0.1 diff --git a/command/root.go b/command/root.go index 54a98e65..6a54636b 100644 --- a/command/root.go +++ b/command/root.go @@ -76,20 +76,8 @@ func envSession() *Force { } func initializeSession() { -<<<<<<< HEAD - var err error - if account != "" { - force, err = GetForce(account) - } else if force = envSession(); force == nil { - force, err = ActiveForce() - } - if err != nil { - ErrorAndExit(err.Error()) - } -======= manager = newForceManager(accounts) ->>>>>>> 75cc0f4 (Multiple accounts for deployment) if _apiVersion != "" { err := SetApiVersion(_apiVersion) if err != nil {