feat: huge overhaul of messaging into FAIL, WARN, hint, ok, prompt, and progress types
This commit is contained in:
parent
6ccd801c89
commit
b52a5bfdb7
30 changed files with 192 additions and 96 deletions
|
|
@ -45,29 +45,28 @@ func delStore(cmd *cobra.Command, args []string) error {
|
|||
store := &Store{}
|
||||
dbName, err := store.parseDB(args[0], false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", args[0], err)
|
||||
return fmt.Errorf("cannot delete store '%s': %v", args[0], err)
|
||||
}
|
||||
var notFound errNotFound
|
||||
path, err := store.FindStore(dbName)
|
||||
if errors.As(err, ¬Found) {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", dbName, err)
|
||||
return fmt.Errorf("cannot delete store '%s': %w", dbName, err)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", dbName, err)
|
||||
return fmt.Errorf("cannot delete store '%s': %v", dbName, err)
|
||||
}
|
||||
|
||||
interactive, err := cmd.Flags().GetBool("interactive")
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", dbName, err)
|
||||
return fmt.Errorf("cannot delete store '%s': %v", dbName, err)
|
||||
}
|
||||
|
||||
if interactive || config.Store.AlwaysPromptDelete {
|
||||
message := fmt.Sprintf("delete-store '%s': are you sure? (y/n)", args[0])
|
||||
fmt.Println(message)
|
||||
promptf("delete store '%s'? (y/n)", args[0])
|
||||
|
||||
var confirm string
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", dbName, err)
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot delete store '%s': %v", dbName, err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
return nil
|
||||
|
|
@ -81,7 +80,7 @@ func delStore(cmd *cobra.Command, args []string) error {
|
|||
|
||||
func executeDeletion(path string) error {
|
||||
if err := os.Remove(path); err != nil {
|
||||
return fmt.Errorf("cannot delete-store '%s': %v", path, err)
|
||||
return fmt.Errorf("cannot delete store '%s': %v", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func del(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
return fmt.Errorf("cannot remove: No such key")
|
||||
return fmt.Errorf("cannot remove: no such key")
|
||||
}
|
||||
|
||||
// Group targets by store for batch deletes.
|
||||
|
|
@ -78,9 +78,8 @@ func del(cmd *cobra.Command, args []string) error {
|
|||
for _, target := range targets {
|
||||
if interactive || config.Key.AlwaysPromptDelete {
|
||||
var confirm string
|
||||
message := fmt.Sprintf("remove %q: are you sure? (y/n)", target.display)
|
||||
fmt.Println(message)
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
promptf("remove '%s'? (y/n)", target.display)
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot remove '%s': %v", target.full, err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
|
|
@ -111,7 +110,7 @@ func del(cmd *cobra.Command, args []string) error {
|
|||
for _, t := range st.targets {
|
||||
idx := findEntry(entries, t.key)
|
||||
if idx < 0 {
|
||||
return fmt.Errorf("cannot remove '%s': No such key", t.full)
|
||||
return fmt.Errorf("cannot remove '%s': no such key", t.full)
|
||||
}
|
||||
entries = append(entries[:idx], entries[idx+1:]...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ func get(cmd *cobra.Command, args []string) error {
|
|||
for i, e := range entries {
|
||||
keys[i] = e.Key
|
||||
}
|
||||
return fmt.Errorf("cannot get '%s': %v", args[0], suggestKey(spec.Key, keys))
|
||||
return fmt.Errorf("cannot get '%s': %w", args[0], suggestKey(spec.Key, keys))
|
||||
}
|
||||
v := entries[idx].Value
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ func applyTemplate(tplBytes []byte, substitutions []string) ([]byte, error) {
|
|||
for _, s := range substitutions {
|
||||
parts := strings.SplitN(s, "=", 2)
|
||||
if len(parts) != 2 || parts[0] == "" {
|
||||
fmt.Fprintf(os.Stderr, "invalid substitutions %q (expected KEY=VALUE)\n", s)
|
||||
warnf("invalid substitution '%s', expected KEY=VALUE", s)
|
||||
continue
|
||||
}
|
||||
key := parts[0]
|
||||
|
|
@ -159,13 +159,13 @@ func applyTemplate(tplBytes []byte, substitutions []string) ([]byte, error) {
|
|||
if slices.Contains(allowed, s) {
|
||||
return s, nil
|
||||
}
|
||||
return "", fmt.Errorf("invalid value %q (allowed: %v)", s, allowed)
|
||||
return "", fmt.Errorf("invalid value '%s', allowed: %v", s, allowed)
|
||||
},
|
||||
"int": func(v any) (int, error) {
|
||||
s := fmt.Sprint(v)
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to convert to int: %w", err)
|
||||
return 0, fmt.Errorf("cannot convert to int: %w", err)
|
||||
}
|
||||
return i, nil
|
||||
},
|
||||
|
|
|
|||
31
cmd/init.go
31
cmd/init.go
|
|
@ -61,36 +61,36 @@ func vcsInit(cmd *cobra.Command, args []string) error {
|
|||
if clean {
|
||||
gitDir := filepath.Join(repoDir, ".git")
|
||||
if _, err := os.Stat(gitDir); err == nil {
|
||||
fmt.Printf("remove .git from '%s'? (y/n)\n", repoDir)
|
||||
promptf("remove .git from '%s'? (y/n)", repoDir)
|
||||
var confirm string
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot clean git dir: %w", err)
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot init: %w", err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
return fmt.Errorf("aborted cleaning git dir")
|
||||
return fmt.Errorf("cannot init: aborted")
|
||||
}
|
||||
if err := os.RemoveAll(gitDir); err != nil {
|
||||
return fmt.Errorf("cannot clean git dir: %w", err)
|
||||
return fmt.Errorf("cannot init: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if hasRemote {
|
||||
dbs, err := store.AllStores()
|
||||
if err == nil && len(dbs) > 0 {
|
||||
fmt.Printf("remove all existing stores and .gitignore? (required for clone) (y/n)\n")
|
||||
promptf("remove all existing stores and .gitignore, required for clone? (y/n)")
|
||||
var confirm string
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot clean stores: %w", err)
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot init: %w", err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
return fmt.Errorf("aborted cleaning stores")
|
||||
return fmt.Errorf("cannot init: aborted")
|
||||
}
|
||||
if err := wipeAllStores(store); err != nil {
|
||||
return fmt.Errorf("cannot clean stores: %w", err)
|
||||
return fmt.Errorf("cannot init: %w", err)
|
||||
}
|
||||
gi := filepath.Join(repoDir, ".gitignore")
|
||||
if err := os.Remove(gi); err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("cannot remove .gitignore: %w", err)
|
||||
return fmt.Errorf("cannot init: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +98,8 @@ func vcsInit(cmd *cobra.Command, args []string) error {
|
|||
|
||||
gitDir := filepath.Join(repoDir, ".git")
|
||||
if _, err := os.Stat(gitDir); err == nil {
|
||||
fmt.Println("vcs already initialised; use --clean to reinitialise")
|
||||
warnf("vcs already initialised")
|
||||
printHint("use --clean to reinitialise")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -106,11 +107,11 @@ func vcsInit(cmd *cobra.Command, args []string) error {
|
|||
// git clone requires the target directory to be empty
|
||||
entries, err := os.ReadDir(repoDir)
|
||||
if err == nil && len(entries) > 0 {
|
||||
return fmt.Errorf("stores directory is not empty; use --clean with a remote to wipe and clone")
|
||||
return withHint(fmt.Errorf("cannot init: stores directory not empty"), "use --clean with a remote to wipe and clone")
|
||||
}
|
||||
|
||||
remote := args[0]
|
||||
fmt.Printf("running: git clone %s %s\n", remote, repoDir)
|
||||
progressf("git clone %s %s", remote, repoDir)
|
||||
if err := runGit("", "clone", remote, repoDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -118,7 +119,7 @@ func vcsInit(cmd *cobra.Command, args []string) error {
|
|||
if err := os.MkdirAll(repoDir, 0o750); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("running: git init\n")
|
||||
progressf("git init")
|
||||
if err := runGit(repoDir, "init"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func listStores(cmd *cobra.Command, args []string) error {
|
|||
store := &Store{}
|
||||
dbs, err := store.AllStores()
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot list-stores: %v", err)
|
||||
return fmt.Errorf("cannot list stores: %v", err)
|
||||
}
|
||||
for _, db := range dbs {
|
||||
fmt.Println("@" + db)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func (e *formatEnum) Set(v string) error {
|
|||
*e = formatEnum(v)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("must be one of \"table\", \"tsv\", \"csv\", \"html\", \"markdown\", or \"ndjson\"")
|
||||
return fmt.Errorf("must be one of 'table', 'tsv', 'csv', 'html', 'markdown', or 'ndjson'")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ func list(cmd *cobra.Command, args []string) error {
|
|||
if _, err := store.FindStore(dbName); err != nil {
|
||||
var notFound errNotFound
|
||||
if errors.As(err, ¬Found) {
|
||||
return fmt.Errorf("cannot ls '%s': No such store", args[0])
|
||||
return fmt.Errorf("cannot ls '%s': %w", args[0], err)
|
||||
}
|
||||
return fmt.Errorf("cannot ls '%s': %v", args[0], err)
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ func list(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if listNoKeys && listNoValues && !listTTL {
|
||||
return fmt.Errorf("cannot ls '%s': no columns selected; disable --no-keys/--no-values or pass --ttl", targetDB)
|
||||
return withHint(fmt.Errorf("cannot ls '%s': no columns selected", targetDB), "disable --no-keys/--no-values or pass --ttl")
|
||||
}
|
||||
|
||||
var columns []columnKind
|
||||
|
|
@ -145,7 +145,7 @@ func list(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if len(matchers) > 0 && len(filtered) == 0 {
|
||||
return fmt.Errorf("cannot ls '%s': No matches for pattern %s", targetDB, formatGlobPatterns(globPatterns))
|
||||
return fmt.Errorf("cannot ls '%s': no matches for pattern %s", targetDB, formatGlobPatterns(globPatterns))
|
||||
}
|
||||
|
||||
output := cmd.OutOrStdout()
|
||||
|
|
|
|||
95
cmd/msg.go
Normal file
95
cmd/msg.go
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// hinted wraps an error with an actionable hint shown on a separate line.
|
||||
type hinted struct {
|
||||
err error
|
||||
hint string
|
||||
}
|
||||
|
||||
func (h hinted) Error() string { return h.err.Error() }
|
||||
func (h hinted) Unwrap() error { return h.err }
|
||||
|
||||
func withHint(err error, hint string) error {
|
||||
return hinted{err: err, hint: hint}
|
||||
}
|
||||
|
||||
func stderrIsTerminal() bool {
|
||||
return term.IsTerminal(int(os.Stderr.Fd()))
|
||||
}
|
||||
|
||||
func stdoutIsTerminal() bool {
|
||||
return term.IsTerminal(int(os.Stdout.Fd()))
|
||||
}
|
||||
|
||||
// keyword returns a right-aligned, colored keyword (color only on TTY).
|
||||
//
|
||||
// FAIL red (stderr)
|
||||
// hint dim (stderr)
|
||||
// WARN yellow (stderr)
|
||||
// ok green (stderr)
|
||||
// ? cyan (stdout)
|
||||
// > dim (stdout)
|
||||
func keyword(code, word string, tty bool) string {
|
||||
padded := fmt.Sprintf("%4s", word)
|
||||
if tty {
|
||||
return fmt.Sprintf("\033[%sm%s\033[0m", code, padded)
|
||||
}
|
||||
return padded
|
||||
}
|
||||
|
||||
func printError(err error) {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("31", "FAIL", stderrIsTerminal()), err)
|
||||
}
|
||||
|
||||
func printHint(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("2", "hint", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func warnf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("33", "WARN", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func okf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("32", "ok", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func promptf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("36", "???", stdoutIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func progressf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("2", ">", stdoutIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func scanln(dest *string) error {
|
||||
fmt.Fprintf(os.Stdout, "%s ", keyword("2", "==>", stdoutIsTerminal()))
|
||||
_, err := fmt.Scanln(dest)
|
||||
return err
|
||||
}
|
||||
|
||||
// printErrorWithHints prints the error and any hints found in the error chain.
|
||||
func printErrorWithHints(err error) {
|
||||
printError(err)
|
||||
var h hinted
|
||||
if errors.As(err, &h) {
|
||||
printHint("%s", h.hint)
|
||||
}
|
||||
var nf errNotFound
|
||||
if errors.As(err, &nf) && len(nf.suggestions) > 0 {
|
||||
printHint("did you mean '%s'?", strings.Join(nf.suggestions, "', '"))
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ func mvImpl(cmd *cobra.Command, args []string, keepSource bool) error {
|
|||
}
|
||||
srcIdx := findEntry(srcEntries, fromSpec.Key)
|
||||
if srcIdx < 0 {
|
||||
return fmt.Errorf("cannot move '%s': No such key", fromSpec.Key)
|
||||
return fmt.Errorf("cannot move '%s': no such key", fromSpec.Key)
|
||||
}
|
||||
srcEntry := srcEntries[srcIdx]
|
||||
|
||||
|
|
@ -108,8 +108,8 @@ func mvImpl(cmd *cobra.Command, args []string, keepSource bool) error {
|
|||
|
||||
if promptOverwrite && dstIdx >= 0 {
|
||||
var confirm string
|
||||
fmt.Printf("overwrite '%s'? (y/n)\n", toSpec.Display())
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
promptf("overwrite '%s'? (y/n)", toSpec.Display())
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot move '%s': %v", fromSpec.Key, err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ func writeStoreFile(path string, entries []Entry) error {
|
|||
je := encodeJsonEntry(e)
|
||||
data, err := json.Marshal(je)
|
||||
if err != nil {
|
||||
return fmt.Errorf("key %q: %w", e.Key, err)
|
||||
return fmt.Errorf("key '%s': %w", e.Key, err)
|
||||
}
|
||||
w.Write(data)
|
||||
w.WriteByte('\n')
|
||||
|
|
@ -142,10 +142,10 @@ func decodeJsonEntry(je jsonEntry) (Entry, error) {
|
|||
var err error
|
||||
value, err = base64.StdEncoding.DecodeString(je.Value)
|
||||
if err != nil {
|
||||
return Entry{}, fmt.Errorf("decode base64 for %q: %w", je.Key, err)
|
||||
return Entry{}, fmt.Errorf("decode base64 for '%s': %w", je.Key, err)
|
||||
}
|
||||
default:
|
||||
return Entry{}, fmt.Errorf("unsupported encoding %q for %q", je.Encoding, je.Key)
|
||||
return Entry{}, fmt.Errorf("unsupported encoding '%s' for '%s'", je.Encoding, je.Key)
|
||||
}
|
||||
var expiresAt uint64
|
||||
if je.ExpiresAt != nil {
|
||||
|
|
|
|||
|
|
@ -104,10 +104,10 @@ func restore(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if len(matchers) > 0 && restored == 0 {
|
||||
return fmt.Errorf("cannot restore '%s': No matches for pattern %s", displayTarget, formatGlobPatterns(globPatterns))
|
||||
return fmt.Errorf("cannot restore '%s': no matches for pattern %s", displayTarget, formatGlobPatterns(globPatterns))
|
||||
}
|
||||
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "Restored %d entries into @%s\n", restored, dbName)
|
||||
okf("restored %d entries into @%s", restored, dbName)
|
||||
return autoSync()
|
||||
}
|
||||
|
||||
|
|
@ -169,9 +169,9 @@ func restoreEntries(decoder *json.Decoder, storePath string, opts restoreOpts) (
|
|||
idx := findEntry(existing, entry.Key)
|
||||
|
||||
if opts.promptOverwrite && idx >= 0 {
|
||||
fmt.Printf("overwrite '%s'? (y/n)\n", entry.Key)
|
||||
promptf("overwrite '%s'? (y/n)", entry.Key)
|
||||
var confirm string
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return 0, fmt.Errorf("entry %d: %v", entryNo, err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
|
|
|
|||
10
cmd/root.go
10
cmd/root.go
|
|
@ -31,18 +31,20 @@ import (
|
|||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "pda",
|
||||
Short: "A key-value store tool",
|
||||
Long: asciiArt,
|
||||
Use: "pda",
|
||||
Short: "A key-value store tool",
|
||||
Long: asciiArt,
|
||||
SilenceErrors: true, // we print errors ourselves
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
if configErr != nil {
|
||||
fmt.Fprintln(os.Stderr, "failed to load config:", configErr)
|
||||
printError(fmt.Errorf("cannot load config: %v", configErr))
|
||||
os.Exit(1)
|
||||
}
|
||||
err := rootCmd.Execute()
|
||||
if err != nil {
|
||||
printErrorWithHints(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,9 +93,9 @@ func set(cmd *cobra.Command, args []string) error {
|
|||
idx := findEntry(entries, spec.Key)
|
||||
|
||||
if promptOverwrite && idx >= 0 {
|
||||
fmt.Printf("overwrite '%s'? (y/n)\n", spec.Display())
|
||||
promptf("overwrite '%s'? (y/n)", spec.Display())
|
||||
var confirm string
|
||||
if _, err := fmt.Scanln(&confirm); err != nil {
|
||||
if err := scanln(&confirm); err != nil {
|
||||
return fmt.Errorf("cannot set '%s': %v", args[0], err)
|
||||
}
|
||||
if strings.ToLower(confirm) != "y" {
|
||||
|
|
|
|||
|
|
@ -37,14 +37,12 @@ import (
|
|||
)
|
||||
|
||||
type errNotFound struct {
|
||||
what string // "key" or "store"
|
||||
suggestions []string
|
||||
}
|
||||
|
||||
func (err errNotFound) Error() string {
|
||||
if len(err.suggestions) == 0 {
|
||||
return "No such key"
|
||||
}
|
||||
return fmt.Sprintf("No such key. Did you mean '%s'?", strings.Join(err.suggestions, ", "))
|
||||
return fmt.Sprintf("no such %s", err.what)
|
||||
}
|
||||
|
||||
type Store struct{}
|
||||
|
|
@ -129,7 +127,7 @@ func (s *Store) FindStore(k string) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", errNotFound{suggestions}
|
||||
return "", errNotFound{what: "store", suggestions: suggestions}
|
||||
}
|
||||
if statErr != nil {
|
||||
return "", statErr
|
||||
|
|
@ -205,7 +203,7 @@ func suggestKey(target string, keys []string) error {
|
|||
suggestions = append(suggestions, k)
|
||||
}
|
||||
}
|
||||
return errNotFound{suggestions}
|
||||
return errNotFound{what: "key", suggestions: suggestions}
|
||||
}
|
||||
|
||||
func ensureSubpath(base, target string) error {
|
||||
|
|
|
|||
|
|
@ -67,12 +67,12 @@ func sync(manual bool) error {
|
|||
return err
|
||||
}
|
||||
} else if manual {
|
||||
fmt.Println("no changes to commit")
|
||||
okf("no changes to commit")
|
||||
}
|
||||
|
||||
if remoteInfo.Ref == "" {
|
||||
if manual {
|
||||
fmt.Println("no remote configured; skipping push")
|
||||
warnf("no remote configured, skipping push")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ func sync(manual bool) error {
|
|||
return pushRemote(repoDir, remoteInfo)
|
||||
}
|
||||
if manual {
|
||||
fmt.Println("nothing to push")
|
||||
okf("nothing to push")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func ensureVCSInitialized() (string, error) {
|
|||
}
|
||||
if _, err := os.Stat(filepath.Join(repoDir, ".git")); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("vcs repository not initialised; run 'pda init' first")
|
||||
return "", withHint(fmt.Errorf("vcs not initialised"), "run 'pda init' first")
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ func writeGitignore(repoDir string) error {
|
|||
}
|
||||
return runGit(repoDir, "commit", "-m", "generated gitignore")
|
||||
}
|
||||
fmt.Println("Existing .gitignore found.")
|
||||
okf("existing .gitignore found")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ func wipeAllStores(store *Store) error {
|
|||
return err
|
||||
}
|
||||
if err := os.Remove(p); err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("remove store '%s': %w", db, err)
|
||||
return fmt.Errorf("cannot remove store '%s': %w", db, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue