Skip to content

Commit

Permalink
Add --sync option to gopass show (gopasspw#544)
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikschulz authored Dec 20, 2017
1 parent 3867434 commit a0730be
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 26 deletions.
6 changes: 6 additions & 0 deletions action/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
28 changes: 16 additions & 12 deletions action/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = "<root>"
}
fmt.Print(color.GreenString("[%s] ", name))
out.Print(ctxno, color.GreenString("[%s] ", name))

sub, err := s.Store.GetSubStore(mp)
if err != nil {
Expand All @@ -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)")
Expand All @@ -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)
Expand All @@ -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
}
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
},
},
Expand Down
6 changes: 3 additions & 3 deletions store/root/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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())
}
Expand Down
45 changes: 35 additions & 10 deletions utils/out/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type contextKey int
const (
ctxKeyPrefix contextKey = iota
ctxKeyHidden
ctxKeyNewline
)

var (
Expand Down Expand Up @@ -61,79 +62,103 @@ 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
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
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
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
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
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
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
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
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
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...))
}

0 comments on commit a0730be

Please sign in to comment.