Γ–ffentliche Dateiansicht: Raw-Dateien, Tree, Releases und Issues sind ohne Login verfΓΌgbar.
cmd/info.go Raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package cmd

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"envault/vault"

	"github.com/spf13/cobra"
)

func init() {
	rootCmd.AddCommand(newInfoCmd())
}

func newInfoCmd() *cobra.Command {
	var useKeychain bool

	cmd := &cobra.Command{
		Use:   "info",
		Short: "Show current project, vault, and session status",
		Args:  cobra.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			// --- Project ---
			project := resolveProject()
			projectSource := resolveProjectSource()

			fmt.Fprintf(os.Stderr, "\n  ev Β· local secret manager\n")
			fmt.Fprintf(os.Stderr, "  ─────────────────────────────────────────\n")
			fmt.Fprintf(os.Stderr, "  Project   : %s  (%s)\n", project, projectSource)

			// --- Vault ---
			vaultPath, _ := resolveVaultPath()
			if vault.Exists(vaultPath) {
				fi, _ := os.Stat(vaultPath)
				fmt.Fprintf(os.Stderr, "  Vault     : %s  (%s)\n", vaultPath, fmtSize(fi.Size()))
			} else {
				fmt.Fprintf(os.Stderr, "  Vault     : %s  (not created yet)\n", vaultPath)
			}

			// --- Session ---
			if expires, ok := vault.SessionInfo(project); ok {
				remaining := time.Until(expires).Round(time.Minute)
				fmt.Fprintf(os.Stderr, "  Session   : open Β· expires %s  (%s remaining)\n",
					expires.Local().Format("15:04:05"), fmtDuration(remaining))
			} else {
				fmt.Fprintf(os.Stderr, "  Session   : none  (run: ev open)\n")
			}

			// --- Keychain ---
			if _, err := vault.KeychainGet(); err == nil {
				fmt.Fprintf(os.Stderr, "  Keychain  : password saved\n")
			} else {
				fmt.Fprintf(os.Stderr, "  Keychain  : not set\n")
			}

			// --- Secrets count (session, keychain, or hint) ---
			if sv := trySession(); sv != nil {
				fmt.Fprintf(os.Stderr, "  Secrets   : %d (from session)\n", len(sv))
			} else if useKeychain && vault.Exists(vaultPath) {
				v, _, _, err := openVaultKeychain()
				if err == nil {
					fmt.Fprintf(os.Stderr, "  Secrets   : %d (from keychain)\n", len(v.ListKeys(project)))
				}
			} else if vault.Exists(vaultPath) {
				fmt.Fprintf(os.Stderr, "  Secrets   : run  ev list  to see keys\n")
			}

			// --- .envault file ---
			cwd, _ := os.Getwd()
			envaultFile := filepath.Join(cwd, ".envault")
			if _, err := os.Stat(envaultFile); err == nil {
				fmt.Fprintf(os.Stderr, "  .envault  : %s\n", envaultFile)
			} else {
				fmt.Fprintf(os.Stderr, "  .envault  : not found  (run: ev init)\n")
			}

			fmt.Fprintln(os.Stderr)

			// --- Project-type hint ---
			printProjectHint(project, "")

			return nil
		},
	}

	cmd.Flags().BoolVarP(&useKeychain, "keychain", "k", false, "read master password from macOS Keychain (no prompt)")
	return cmd
}

// resolveProjectSource returns a human-readable description of where the project name came from.
func resolveProjectSource() string {
	if flagProject != "" {
		return "--project flag"
	}
	cwd, err := os.Getwd()
	if err != nil {
		return "fallback"
	}
	if _, err := findProjectFile(cwd); err == nil {
		return ".envault file"
	}
	return "directory name"
}

func fmtSize(b int64) string {
	switch {
	case b >= 1024*1024:
		return fmt.Sprintf("%.1f MB", float64(b)/1024/1024)
	case b >= 1024:
		return fmt.Sprintf("%.1f KB", float64(b)/1024)
	default:
		return fmt.Sprintf("%d B", b)
	}
}