diff --git a/action/show.go b/action/show.go index 8d9039a6b1..4913910ef1 100644 --- a/action/show.go +++ b/action/show.go @@ -26,6 +26,12 @@ func (s *Action) Show(ctx context.Context, c *cli.Context) error { ctx = WithPrintQR(ctx, c.Bool("qr")) ctx = WithPasswordOnly(ctx, c.Bool("password")) + if c.Bool("sync") { + if err := s.sync(out.WithHidden(ctx, true), c, s.Store.MountPoint(name)); err != nil { + out.Red(ctx, "Failed to sync %s: %s", name, err) + } + } + if err := s.show(ctx, c, name, key, true); err != nil { return exitError(ctx, ExitDecrypt, err, "%s", err) } diff --git a/action/sync.go b/action/sync.go index 7431f8345a..930aa282ba 100644 --- a/action/sync.go +++ b/action/sync.go @@ -15,7 +15,10 @@ import ( // Sync all stores with their remotes func (s *Action) Sync(ctx context.Context, c *cli.Context) error { store := c.String("store") + return s.sync(ctx, c, store) +} +func (s *Action) sync(ctx context.Context, c *cli.Context, store string) error { out.Green(ctx, "Sync starting ...") numEntries := 0 @@ -59,11 +62,12 @@ func (s *Action) Sync(ctx context.Context, c *cli.Context) error { } func (s *Action) syncMount(ctx context.Context, mp string) error { + ctxno := out.WithNewline(ctx, false) name := mp if mp == "" { name = "" } - fmt.Print(color.GreenString("[%s] ", name)) + out.Print(ctxno, color.GreenString("[%s] ", name)) sub, err := s.Store.GetSubStore(mp) if err != nil { @@ -81,7 +85,7 @@ func (s *Action) syncMount(ctx context.Context, mp string) error { numMP = len(l) } - fmt.Print("\n " + color.GreenString("git pull and push ... ")) + out.Print(ctxno, "\n "+color.GreenString("git pull and push ... ")) if err := sub.GitPush(ctx, "", ""); err != nil { if errors.Cause(err) == store.ErrGitNoRemote { out.Yellow(ctx, "Skipped (no remote)") @@ -92,29 +96,29 @@ func (s *Action) syncMount(ctx context.Context, mp string) error { out.Red(ctx, "Failed to push '%s' to it's remote: %s", name, err) return err } - fmt.Print(color.GreenString("OK")) + out.Print(ctxno, color.GreenString("OK")) if l, err := sub.List(""); err == nil { diff := len(l) - numMP if diff > 0 { - fmt.Print(color.GreenString(" (Added %d entries)", diff)) + out.Print(ctxno, color.GreenString(" (Added %d entries)", diff)) } else if diff < 0 { - fmt.Print(color.GreenString(" (Removed %d entries)", -1*diff)) + out.Print(ctxno, color.GreenString(" (Removed %d entries)", -1*diff)) } else { - fmt.Print(color.GreenString(" (no changes)")) + out.Print(ctxno, color.GreenString(" (no changes)")) } } // import keys - fmt.Print("\n " + color.GreenString("importing missing keys ... ")) + out.Print(ctxno, "\n "+color.GreenString("importing missing keys ... ")) if err := sub.ImportMissingPublicKeys(ctx); err != nil { out.Red(ctx, "Failed to import missing public keys for '%s': %s", name, err) return err } - fmt.Print(color.GreenString("OK")) + out.Print(ctxno, color.GreenString("OK")) // export keys - fmt.Print("\n " + color.GreenString("exporting missing keys ... ")) + out.Print(ctxno, "\n "+color.GreenString("exporting missing keys ... ")) rs, err := sub.GetRecipients(ctx, "") if err != nil { out.Red(ctx, "Failed to load recipients for '%s': %s", name, err) @@ -132,10 +136,10 @@ func (s *Action) syncMount(ctx context.Context, mp string) error { out.Red(ctx, "Failed to push '%s' to it's remote: %s", name, err) return err } - fmt.Print(color.GreenString("OK")) + out.Print(ctxno, color.GreenString("OK")) } else { - fmt.Print(color.GreenString("nothing to do")) + out.Print(ctxno, color.GreenString("nothing to do")) } - fmt.Println("\n " + color.GreenString("done")) + out.Print(ctx, "\n "+color.GreenString("done")) return nil } diff --git a/main.go b/main.go index da54839252..e80e765f9b 100644 --- a/main.go +++ b/main.go @@ -894,7 +894,11 @@ func main() { }, cli.BoolFlag{ Name: "password, o", - Usage: "Dispaly only the password", + Usage: "Display only the password", + }, + cli.BoolFlag{ + Name: "sync, s", + Usage: "Sync before attempting to display the secret", }, }, }, diff --git a/store/root/mount.go b/store/root/mount.go index 53138f806e..63523a72d2 100644 --- a/store/root/mount.go +++ b/store/root/mount.go @@ -98,8 +98,8 @@ func (r *Store) MountPoints() []string { return mps } -// mountPoint returns the most-specific mount point for the given key -func (r *Store) mountPoint(name string) string { +// MountPoint returns the most-specific mount point for the given key +func (r *Store) MountPoint(name string) string { for _, mp := range r.MountPoints() { if strings.HasPrefix(name+"/", mp+"/") { return mp @@ -113,7 +113,7 @@ func (r *Store) mountPoint(name string) string { // context with sub store options set, sub store reference, truncated path to secret func (r *Store) getStore(ctx context.Context, name string) (context.Context, *sub.Store, string) { name = strings.TrimSuffix(name, "/") - mp := r.mountPoint(name) + mp := r.MountPoint(name) if sub, found := r.mounts[mp]; found { return r.cfg.Mounts[mp].WithContext(ctx), sub, strings.TrimPrefix(name, sub.Alias()) } diff --git a/utils/out/print.go b/utils/out/print.go index 999696974b..9fd580bb73 100644 --- a/utils/out/print.go +++ b/utils/out/print.go @@ -14,6 +14,7 @@ type contextKey int const ( ctxKeyPrefix contextKey = iota ctxKeyHidden + ctxKeyNewline ) var ( @@ -61,9 +62,33 @@ func IsHidden(ctx context.Context) bool { return bv } +// WithNewline returns a context with the flag value for newline set +func WithNewline(ctx context.Context, nl bool) context.Context { + return context.WithValue(ctx, ctxKeyNewline, nl) +} + +// HasNewline returns the value of newline or the default (true) +func HasNewline(ctx context.Context) bool { + bv, ok := ctx.Value(ctxKeyNewline).(bool) + if !ok { + return true + } + return bv +} + +func newline(ctx context.Context) string { + if HasNewline(ctx) { + return "\n" + } + return "" +} + // Print formats and prints the given string func Print(ctx context.Context, format string, args ...interface{}) { - fmt.Fprintf(stdout, Prefix(ctx)+format+"\n", args...) + if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { + return + } + fmt.Fprintf(stdout, Prefix(ctx)+format+newline(ctx), args...) } // Debug prints the given string if the debug flag is set @@ -71,7 +96,7 @@ func Debug(ctx context.Context, format string, args ...interface{}) { if !ctxutil.IsDebug(ctx) { return } - fmt.Fprintf(stdout, Prefix(ctx)+"[DEBUG] "+format+"\n", args...) + fmt.Fprintf(stdout, Prefix(ctx)+"[DEBUG] "+format+newline(ctx), args...) } // Black prints the string in black @@ -79,7 +104,7 @@ func Black(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.BlackString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.BlackString(Prefix(ctx)+format+newline(ctx), args...)) } // Blue prints the string in blue @@ -87,7 +112,7 @@ func Blue(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.BlueString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.BlueString(Prefix(ctx)+format+newline(ctx), args...)) } // Cyan prints the string in cyan @@ -95,7 +120,7 @@ func Cyan(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.CyanString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.CyanString(Prefix(ctx)+format+newline(ctx), args...)) } // Green prints the string in green @@ -103,7 +128,7 @@ func Green(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.GreenString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.GreenString(Prefix(ctx)+format+newline(ctx), args...)) } // Magenta prints the string in magenta @@ -111,7 +136,7 @@ func Magenta(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.MagentaString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.MagentaString(Prefix(ctx)+format+newline(ctx), args...)) } // Red prints the string in red @@ -119,7 +144,7 @@ func Red(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.RedString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.RedString(Prefix(ctx)+format+newline(ctx), args...)) } // White prints the string in white @@ -127,7 +152,7 @@ func White(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.WhiteString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.WhiteString(Prefix(ctx)+format+newline(ctx), args...)) } // Yellow prints the string in yellow @@ -135,5 +160,5 @@ func Yellow(ctx context.Context, format string, args ...interface{}) { if IsHidden(ctx) && !ctxutil.IsDebug(ctx) { return } - fmt.Fprintln(stdout, color.YellowString(Prefix(ctx)+format, args...)) + fmt.Fprint(stdout, color.YellowString(Prefix(ctx)+format+newline(ctx), args...)) }