diff --git a/cmd/dump.go b/cmd/dump.go index 00d6cac..7a3cccf 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -2,6 +2,8 @@ package cmd import ( "log" + "path/filepath" + "strings" "github.com/simonwhitaker/gibo/utils" "github.com/spf13/cobra" @@ -17,10 +19,43 @@ var dumpCmd = &cobra.Command{ Args: cobra.MinimumNArgs(1), ValidArgs: utils.ListBoilerplatesNoError(), Run: func(cmd *cobra.Command, args []string) { - for _, boilerplate := range args { - if err := utils.PrintBoilerplate(boilerplate); err != nil { - log.Fatalf("On dumping %v: %v", boilerplate, err) + if isAppendMode(args) { + results, err := findBoilerplatesInGitignoreFile(filepath.Join(".", gitignoreFileName)) + if err != nil { + log.Fatal(err.Error()) } + dumpBoilerplate(concatNames(results, args)) + } else { + dumpBoilerplate(args) } }, } + +func concatNames(results []string, args []string) []string { + for _, arg := range args { + if strings.HasPrefix(arg, "+") { + results = append(results, arg[1:]) + } else { + results = append(results, arg) + } + } + return results +} + +func isAppendMode(args []string) bool { + for _, arg := range args { + if strings.HasPrefix(arg, "+") { + return true + } + } + return false +} + +func dumpBoilerplate(args []string) error { + for _, boilerplate := range args { + if err := utils.PrintBoilerplate(boilerplate); err != nil { + log.Fatalf("On dumping %v: %v", boilerplate, err) + } + } + return nil +} diff --git a/cmd/list-ignore.go b/cmd/list-ignore.go new file mode 100644 index 0000000..4436b55 --- /dev/null +++ b/cmd/list-ignore.go @@ -0,0 +1,99 @@ +package cmd + +import ( + "bufio" + "fmt" + "io" + "log" + "os" + "path/filepath" + "strings" + + "github.com/simonwhitaker/gibo/utils" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +const gitignoreFileName string = ".gitignore" + +func init() { + giboCmd.AddCommand(listIgnoreCmd) +} + +var listIgnoreCmd = &cobra.Command{ + Use: "list-ignore", + Short: "List boilerplates in the .gitignore file", + Run: func(cmd *cobra.Command, args []string) { + list, err := findRegisteredBoilerplates(args) + if err != nil { + log.Fatal(err) + } + if term.IsTerminal(int(os.Stdout.Fd())) { + w, _, err := term.GetSize(int(os.Stdout.Fd())) + if err == nil { + utils.PrintInColumns(list, w) + os.Exit(0) + } + } + for _, el := range list { + fmt.Println(el) + } + }, +} + +func findRegisteredBoilerplates(args []string) ([]string, error) { + if len(args) == 0 { + return findBoilerplatesInGitignoreFile(filepath.Join(".", gitignoreFileName)) + } + gitIgnorePath := args[0] + if filepath.Base(gitIgnorePath) == gitignoreFileName { + gitIgnorePath = filepath.Join(gitIgnorePath, gitignoreFileName) + } + return findBoilerplatesInGitignoreFile(gitIgnorePath) +} + +func Exists(filename string) bool { + _, err := os.Stat(filename) + return err == nil +} + +func findBoilerplatesInGitignoreFile(gitIgnoreFile string) ([]string, error) { + if !Exists(gitIgnoreFile) { + return []string{}, nil + } + in, err := os.Open(gitIgnoreFile) + if err != nil { + return nil, err + } + defer in.Close() + + var results []string + reader := bufio.NewReader(in) + for { + line, _, err := reader.ReadLine() + results = appendBoilerplateNameIfNeeded(results, string(line)) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + } + return results, nil +} + +func appendBoilerplateNameIfNeeded(results []string, line string) []string { + if isBoilerplateName(line) { + results = append(results, extractBoilerplateName(line)) + } + return results +} + +func extractBoilerplateName(line string) string { + index := strings.LastIndex(line, "/") + return strings.TrimSuffix(line[index+1:], ".gitignore") +} + +func isBoilerplateName(line string) bool { + return strings.HasPrefix(line, "###") && strings.HasSuffix(line, ".gitignore") +}