mirror of
https://github.com/onyx-and-iris/ignr.git
synced 2025-07-26 22:01:57 +00:00
109 lines
3.1 KiB
Go
109 lines
3.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/charmbracelet/huh"
|
|
"github.com/charmbracelet/lipgloss"
|
|
"github.com/google/go-github/v72/github"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
const gitignoreFileName = ".gitignore"
|
|
|
|
// newCmd represents the new command.
|
|
var newCmd = &cobra.Command{
|
|
Use: "new",
|
|
Short: "Create a new .gitignore file",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return runNewCommand(cmd, args)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(newCmd)
|
|
}
|
|
|
|
// runNewCommand is the handler for the 'new' command.
|
|
// It retrieves available .gitignore templates from GitHub, prompts the user to select one,
|
|
// and writes the selected template to a new .gitignore file.
|
|
func runNewCommand(cmd *cobra.Command, _ []string) error {
|
|
client, ok := getClientFromContext(cmd.Context())
|
|
if !ok {
|
|
return errors.New("failed to get GitHub client from context")
|
|
}
|
|
|
|
templates, _, err := client.Gitignores.List(context.Background())
|
|
if err != nil {
|
|
return fmt.Errorf("error listing gitignore templates: %w", err)
|
|
}
|
|
|
|
var selection string
|
|
if err := runPrompt(templates, &selection); err != nil {
|
|
return fmt.Errorf("error running selection prompt: %w", err)
|
|
}
|
|
|
|
content, _, err := client.Gitignores.Get(context.Background(), selection)
|
|
if err != nil {
|
|
return fmt.Errorf("error retrieving gitignore template '%s': %w", selection, err)
|
|
}
|
|
|
|
f, err := os.OpenFile(gitignoreFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o600)
|
|
if err != nil {
|
|
return fmt.Errorf("error opening file '%s': %w", gitignoreFileName, err)
|
|
}
|
|
defer f.Close()
|
|
|
|
if err = commitGitignore(content, f); err != nil {
|
|
return fmt.Errorf("error committing gitignore file: %w", err)
|
|
}
|
|
|
|
style := lipgloss.NewStyle().
|
|
Bold(true).
|
|
Foreground(lipgloss.Color("#7D56F4")) // nolint: misspell
|
|
|
|
fmt.Println(style.Render("Created"), selection, style.Render(".gitignore file ✓"))
|
|
|
|
return nil
|
|
}
|
|
|
|
// runPrompt is a helper function to run the selection prompt for .gitignore templates.
|
|
func runPrompt(templates []string, selection *string) error {
|
|
var options []huh.Option[string]
|
|
for _, template := range templates {
|
|
options = append(options, huh.NewOption(template, template))
|
|
}
|
|
|
|
selectionPrompt := huh.NewSelect[string]().
|
|
Title("Select a .gitignore template").
|
|
Options(options...).
|
|
Value(selection)
|
|
|
|
if err := selectionPrompt.Run(); err != nil {
|
|
return fmt.Errorf("error running selection prompt: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// commitGitignore writes the content of the selected gitignore template to the .gitignore file.
|
|
func commitGitignore(content *github.Gitignore, w io.Writer) error {
|
|
if _, err := fmt.Fprintf(w, "# Generated by ignr-cli: github.com/onyx-and-iris/ignr-cli\n"); err != nil {
|
|
return fmt.Errorf("error writing header to file '%s': %w", gitignoreFileName, err)
|
|
}
|
|
|
|
if _, err := fmt.Fprintf(w, "%s", *content.Source); err != nil {
|
|
return fmt.Errorf("error writing to file '%s': %w", gitignoreFileName, err)
|
|
}
|
|
|
|
if _, err := fmt.Fprintf(w, "\n# End of ignr-cli\n"); err != nil {
|
|
return fmt.Errorf("error writing footer to file '%s': %w", gitignoreFileName, err)
|
|
}
|
|
|
|
return nil
|
|
}
|