package cmd import ( "errors" "fmt" "os" "path/filepath" "strings" "github.com/urfave/cli/v2" ) var Identity = &cli.Command{ Name: "identity", Aliases: []string{"ident"}, Description: "Manage identity files", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "remove", Aliases: []string{"r"}, Usage: "Remove an identity file", }, &cli.BoolFlag{ Name: "list", Aliases: []string{"l"}, Usage: "List identity files", }, }, Action: actionIdentity, } func actionIdentity(ctx *cli.Context) error { keyFiles, err := listIdentities() if err != nil && !errors.Is(err, ErrNoIdentities) { return err } if ctx.Bool("list") { return actionListIdentities(ctx, keyFiles) } if ctx.NArg() != 1 { return errors.New("identity requires 1 argument") } file := ctx.Args().First() if strings.HasPrefix(file, "~") { home, err := os.UserHomeDir() if err != nil { return err } file = filepath.Join(home, strings.TrimPrefix(file, "~")) } file = os.ExpandEnv(file) file, err = filepath.Abs(file) if err != nil { return err } exists := -1 for idx, keyFile := range keyFiles { if file == keyFile { exists = idx break } } if exists >= 0 && !ctx.Bool("remove") { return fmt.Errorf("identity file %q already exists", file) } else if exists == -1 && ctx.Bool("remove") { return fmt.Errorf("identity file %q doesn't exist", file) } if ctx.Bool("remove") { keyFiles = append(keyFiles[:exists], keyFiles[exists+1:]...) } else { if _, err := parseIdentityFile(file); err != nil { return fmt.Errorf("could not add invalid identity file: %w", err) } keyFiles = append(keyFiles, file) } cmd("git", "config", "--unset-all", "git-age.identity") for _, keyFile := range keyFiles { if _, err := cmd("git", "config", "--add", "git-age.identity", keyFile); err != nil { return err } } return nil } func actionListIdentities(ctx *cli.Context, files []string) error { var sb strings.Builder for _, file := range files { _, err := parseIdentityFile(file) valid := "✓" if err != nil { valid = "x" } sb.WriteString(fmt.Sprintf("%s %q\n", valid, file)) } fmt.Print(sb.String()) return nil }