1package cmd
2
3import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strings"
8
9 "charm.land/lipgloss/v2"
10 "charm.land/lipgloss/v2/table"
11 "github.com/charmbracelet/crush/internal/config"
12 "github.com/charmbracelet/x/term"
13 "github.com/spf13/cobra"
14)
15
16var dirsCmd = &cobra.Command{
17 Use: "dirs",
18 Short: "Print directories used by Crush",
19 Long: `Print the directories where Crush stores its configuration and data files.
20This includes the global configuration directory and data directory.`,
21 Example: `
22# Print all global directories
23crush dirs
24
25# Print data directory and all project specific config directories
26crush dirs -p
27
28# Print only global config directory
29crush dirs config
30
31# Print only project specific config directories
32crush dirs -p config
33
34# Print only the data directory
35crush dirs data
36 `,
37 RunE: func(cmd *cobra.Command, args []string) error {
38 dirs, err := configDirs(cmd)
39 if err != nil {
40 return fmt.Errorf("cannot collect config directories: %w", err)
41 }
42
43 if term.IsTerminal(os.Stdout.Fd()) {
44 // We're in a TTY: make it fancy.
45 t := table.New().
46 Border(lipgloss.RoundedBorder()).
47 StyleFunc(func(row, col int) lipgloss.Style {
48 return lipgloss.NewStyle().Padding(0, 2)
49 }).
50 Row("Config", dirs).
51 Row("Data", filepath.Dir(config.GlobalConfigData()))
52 lipgloss.Println(t)
53 return nil
54 }
55 // Not a TTY.
56 cmd.Println(dirs)
57 cmd.Println(filepath.Dir(config.GlobalConfigData()))
58
59 return nil
60 },
61}
62
63var configDirCmd = &cobra.Command{
64 Use: "config",
65 Short: "Print the configuration directory used by Crush",
66 RunE: func(cmd *cobra.Command, args []string) error {
67 dirs, err := configDirs(cmd)
68 if err != nil {
69 return fmt.Errorf("cannot collect config directories: %w", err)
70 }
71 cmd.Println(dirs)
72 return nil
73 },
74}
75
76var dataDirCmd = &cobra.Command{
77 Use: "data",
78 Short: "Print the datauration directory used by Crush",
79 Run: func(cmd *cobra.Command, args []string) {
80 cmd.Println(filepath.Dir(config.GlobalConfigData()))
81 },
82}
83
84// configDirs returns formatted string with one or more project config paths
85func configDirs(cmd *cobra.Command) (string, error) {
86 configDir := filepath.Dir(config.GlobalConfig())
87 if ok, _ := cmd.Flags().GetBool("project"); !ok {
88 return configDir, nil
89 }
90
91 cwd, err := ResolveCwd(cmd)
92 if err != nil {
93 return "", fmt.Errorf("cannot resolve current working directory: %w", err)
94 }
95
96 var sb strings.Builder
97 for i, path := range config.ProjectConfigs(cwd) {
98 if i > 0 {
99 sb.WriteByte('\n')
100 }
101 sb.WriteString(filepath.Dir(path))
102 }
103 return sb.String(), nil
104}
105
106func init() {
107 dirsCmd.PersistentFlags().BoolP("project", "p", false, "Print project specific configs")
108
109 dirsCmd.AddCommand(configDirCmd, dataDirCmd)
110}