@@ -1,8 +1,10 @@
package cmd
import (
+ "fmt"
"os"
"path/filepath"
+ "strings"
"charm.land/lipgloss/v2"
"charm.land/lipgloss/v2/table"
@@ -17,16 +19,27 @@ var dirsCmd = &cobra.Command{
Long: `Print the directories where Crush stores its configuration and data files.
This includes the global configuration directory and data directory.`,
Example: `
-# Print all directories
+# Print all global directories
crush dirs
-# Print only the config directory
+# Print data directory and all project specific config directories
+crush dirs -p
+
+# Print only global config directory
crush dirs config
+# Print only project specific config directories
+crush dirs -p config
+
# Print only the data directory
crush dirs data
`,
- Run: func(cmd *cobra.Command, args []string) {
+ RunE: func(cmd *cobra.Command, args []string) error {
+ dirs, err := configDirs(cmd)
+ if err != nil {
+ return fmt.Errorf("cannot collect config directories: %w", err)
+ }
+
if term.IsTerminal(os.Stdout.Fd()) {
// We're in a TTY: make it fancy.
t := table.New().
@@ -34,22 +47,29 @@ crush dirs data
StyleFunc(func(row, col int) lipgloss.Style {
return lipgloss.NewStyle().Padding(0, 2)
}).
- Row("Config", filepath.Dir(config.GlobalConfig())).
+ Row("Config", dirs).
Row("Data", filepath.Dir(config.GlobalConfigData()))
lipgloss.Println(t)
- return
+ return nil
}
// Not a TTY.
- cmd.Println(filepath.Dir(config.GlobalConfig()))
+ cmd.Println(dirs)
cmd.Println(filepath.Dir(config.GlobalConfigData()))
+
+ return nil
},
}
var configDirCmd = &cobra.Command{
Use: "config",
Short: "Print the configuration directory used by Crush",
- Run: func(cmd *cobra.Command, args []string) {
- cmd.Println(filepath.Dir(config.GlobalConfig()))
+ RunE: func(cmd *cobra.Command, args []string) error {
+ dirs, err := configDirs(cmd)
+ if err != nil {
+ return fmt.Errorf("cannot collect config directories: %w", err)
+ }
+ cmd.Println(dirs)
+ return nil
},
}
@@ -61,6 +81,30 @@ var dataDirCmd = &cobra.Command{
},
}
+// configDirs returns formatted string with one or more project config paths
+func configDirs(cmd *cobra.Command) (string, error) {
+ configDir := filepath.Dir(config.GlobalConfig())
+ if ok, _ := cmd.Flags().GetBool("project"); !ok {
+ return configDir, nil
+ }
+
+ cwd, err := ResolveCwd(cmd)
+ if err != nil {
+ return "", fmt.Errorf("cannot resolve current working directory: %w", err)
+ }
+
+ var sb strings.Builder
+ for i, path := range config.ProjectConfigs(cwd) {
+ if i > 0 {
+ sb.WriteByte('\n')
+ }
+ sb.WriteString(filepath.Dir(path))
+ }
+ return sb.String(), nil
+}
+
func init() {
+ dirsCmd.PersistentFlags().BoolP("project", "p", false, "Print project specific configs")
+
dirsCmd.AddCommand(configDirCmd, dataDirCmd)
}
@@ -849,6 +849,11 @@ func GlobalCacheDir() string {
return filepath.Join(home.Dir(), ".cache", appName)
}
+// ProjectConfigs returns list of current project configs paths.
+func ProjectConfigs(cwd string) []string {
+ return lookupConfigs(cwd)
+}
+
// GlobalConfigData returns the path to the main data directory for the application.
// this config is used when the app overrides configurations instead of updating the global config.
func GlobalConfigData() string {