From a48f63d3b936195ca2019a6de64dec17bfd46a51 Mon Sep 17 00:00:00 2001 From: Oliver Braun Date: Mon, 4 Nov 2024 16:56:12 +0100 Subject: [PATCH] feat(clone): suppress output for piping --- README.md | 11 +++++++++ cmd/clone.go | 12 ++++++---- git/clone.go | 66 ++++++++++++++++++++++++++++++++-------------------- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index eac445c..28e509a 100644 --- a/README.md +++ b/README.md @@ -242,8 +242,10 @@ Usage: Flags: -b, --branch string checkout branch after cloning + -f, --force remove directory if it already exists -h, --help help for clone -p, --path string clone in this directory + -s, --suppress suppress config output for piping to other commands Global Flags: --config string config file (default is $HOME/.glabs.yml) @@ -252,6 +254,15 @@ Global Flags: Command line options (`-b` and `-p`) override the config file settings. +With `-s` it is possible to suppress all output but the local path for use in +a pipe. For example + +``` +glabs clone algdati blatt3 "grp0[35]" -fs | xargs code +``` + +clones the two repositories for `grp03` and `grp05` and opens them in VS Code. + ## Seeding using a custom tool Instead of providing each student/group the same repository using the startercode option it is possible to run a tool to seed each repository individually. diff --git a/cmd/clone.go b/cmd/clone.go index f1d1165..93a9488 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -27,16 +27,19 @@ var ( if Force { assignmentConfig.SetForce() } - assignmentConfig.Show() - fmt.Println(aurora.Magenta("Config okay? Press 'Enter' to continue or 'Ctrl-C' to stop ...")) - fmt.Scanln() //nolint:errcheck + if !Suppress { + assignmentConfig.Show() + fmt.Println(aurora.Magenta("Config okay? Press 'Enter' to continue or 'Ctrl-C' to stop ...")) + fmt.Scanln() //nolint:errcheck + } - git.Clone(assignmentConfig) + git.Clone(assignmentConfig, Suppress) }, } Localpath string Branch string Force bool + Suppress bool ) func init() { @@ -44,4 +47,5 @@ func init() { cloneCmd.Flags().StringVarP(&Localpath, "path", "p", "", "clone in this directory") cloneCmd.Flags().StringVarP(&Branch, "branch", "b", "", "checkout branch after cloning") cloneCmd.Flags().BoolVarP(&Force, "force", "f", false, "remove directory if it already exists") + cloneCmd.Flags().BoolVarP(&Suppress, "suppress", "s", false, "suppress config output for piping to other commands") } diff --git a/git/clone.go b/git/clone.go index 6daddfd..ce7c9af 100644 --- a/git/clone.go +++ b/git/clone.go @@ -15,7 +15,7 @@ import ( "github.com/theckman/yacspin" ) -func Clone(cfg *config.AssignmentConfig) { +func Clone(cfg *config.AssignmentConfig, noSpinner bool) { auth, err := GetAuth() if err != nil { fmt.Printf("error: %v", err) @@ -26,11 +26,11 @@ func Clone(cfg *config.AssignmentConfig) { case config.PerStudent: for _, stud := range cfg.Students { suffix := cfg.RepoSuffix(stud) - clone(localpath(cfg, suffix), cfg.Clone.Branch, cloneurl(cfg, suffix), auth, cfg.Clone.Force) + clone(localpath(cfg, suffix), cfg.Clone.Branch, cloneurl(cfg, suffix), auth, cfg.Clone.Force, noSpinner) } case config.PerGroup: for _, grp := range cfg.Groups { - clone(localpath(cfg, grp.Name), cfg.Clone.Branch, cloneurl(cfg, grp.Name), auth, cfg.Clone.Force) + clone(localpath(cfg, grp.Name), cfg.Clone.Branch, cloneurl(cfg, grp.Name), auth, cfg.Clone.Force, noSpinner) } } } @@ -45,7 +45,7 @@ func localpath(cfg *config.AssignmentConfig, suffix string) string { return fmt.Sprintf("%s/%s-%s", cfg.Clone.LocalPath, cfg.Name, suffix) } -func clone(localpath, branch, cloneurl string, auth ssh.AuthMethod, force bool) { +func clone(localpath, branch, cloneurl string, auth ssh.AuthMethod, force bool, noSpinner bool) { cfg := yacspin.Config{ Frequency: 100 * time.Millisecond, CharSet: yacspin.CharSets[69], @@ -62,49 +62,65 @@ func clone(localpath, branch, cloneurl string, auth ssh.AuthMethod, force bool) StopFailColors: []string{"fgRed"}, } - spinner, err := yacspin.New(cfg) - if err != nil { - log.Debug().Err(err).Msg("cannot create spinner") - } - err = spinner.Start() - if err != nil { - log.Debug().Err(err).Msg("cannot start spinner") + var spinner *yacspin.Spinner + + if !noSpinner { + spinner, err := yacspin.New(cfg) + if err != nil { + log.Debug().Err(err).Msg("cannot create spinner") + } + err = spinner.Start() + if err != nil { + log.Debug().Err(err).Msg("cannot start spinner") + } } if force { - spinner.Message(" trying to remove folder if it exists") + if !noSpinner { + spinner.Message(" trying to remove folder if it exists") + } err := os.RemoveAll(localpath) if err != nil { - spinner.StopFailMessage(fmt.Sprintf("error when trying to remove %s: %v", localpath, err)) + if !noSpinner { + spinner.StopFailMessage(fmt.Sprintf("error when trying to remove %s: %v", localpath, err)) - err := spinner.StopFail() - if err != nil { - log.Debug().Err(err).Msg("cannot stop spinner") + err := spinner.StopFail() + if err != nil { + log.Debug().Err(err).Msg("cannot stop spinner") + } } return } - spinner.Message(" cloning") + if !noSpinner { + spinner.Message(" cloning") + } } - _, err = git.PlainClone(localpath, false, &git.CloneOptions{ + _, err := git.PlainClone(localpath, false, &git.CloneOptions{ Auth: auth, URL: cloneurl, ReferenceName: plumbing.ReferenceName("refs/heads/" + branch), }) if err != nil { - spinner.StopFailMessage(fmt.Sprintf("problem: %v", err)) + if !noSpinner { + spinner.StopFailMessage(fmt.Sprintf("problem: %v", err)) - err := spinner.StopFail() - if err != nil { - log.Debug().Err(err).Msg("cannot stop spinner") + err := spinner.StopFail() + if err != nil { + log.Debug().Err(err).Msg("cannot stop spinner") + } } return } - errs := spinner.Stop() - if errs != nil { - log.Debug().Err(err).Msg("cannot stop spinner") + fmt.Println(localpath) + + if !noSpinner { + errs := spinner.Stop() + if errs != nil { + log.Debug().Err(err).Msg("cannot stop spinner") + } } }