-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
394 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,39 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"log/slog" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/flowtemplates/cli/internal/config" | ||
"github.com/flowtemplates/cli/internal/controller/cli" | ||
"github.com/flowtemplates/cli/internal/repository/templates" | ||
"github.com/flowtemplates/cli/internal/service" | ||
) | ||
|
||
var rootCmd = &cobra.Command{ | ||
Use: "flow", | ||
Short: "TemplatesFlow CLI", | ||
Long: `A sample CLI application that showcases: | ||
- Command/subcommand structure | ||
- Flag parsing | ||
- Auto-generated help and usage information | ||
- Shell completion support for commands and flags`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
log.Println("Welcome to your CLI app!") | ||
}, | ||
} | ||
|
||
// completionCmd generates shell completion scripts. | ||
var completionCmd = &cobra.Command{ | ||
Use: "completion [bash|zsh|fish|powershell]", | ||
Short: "Generate shell completion scripts", | ||
Long: `To load completions: | ||
const defaultConfigName = "flow" | ||
|
||
Bash: | ||
$ source <(app completion bash) | ||
func run() error { | ||
ctx := context.Background() | ||
|
||
Zsh: | ||
$ source <(app completion zsh) | ||
cfg, err := config.GetConfig(defaultConfigName) | ||
if err != nil { | ||
return fmt.Errorf("failed to get config: %w", err) | ||
} | ||
|
||
Fish: | ||
$ app completion fish | source | ||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) | ||
|
||
PowerShell: | ||
PS> app completion powershell | Out-String | Invoke-Expression | ||
`, | ||
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), | ||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
var err error | ||
switch args[0] { | ||
case "bash": | ||
err = rootCmd.GenBashCompletion(os.Stdout) | ||
case "zsh": | ||
err = rootCmd.GenZshCompletion(os.Stdout) | ||
case "fish": | ||
err = rootCmd.GenFishCompletion(os.Stdout, true) | ||
case "powershell": | ||
err = rootCmd.GenPowerShellCompletionWithDesc(os.Stdout) | ||
} | ||
r := templates.New(cfg.TemplatesFolder) | ||
s := service.New(r) | ||
c := cli.New(s, logger) | ||
|
||
log.Fatalf("%s\n", err) | ||
}, | ||
return c.Cmd().ExecuteContext(ctx) // nolint: wrapcheck | ||
} | ||
|
||
func main() { | ||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||
rootCmd.AddCommand(completionCmd) | ||
|
||
if err := rootCmd.Execute(); err != nil { | ||
log.Fatalf("%s\n", err) | ||
if err := run(); err != nil { | ||
log.Fatalln(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package config | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"gopkg.in/yaml.v3" | ||
) | ||
|
||
// Config struct defining expected fields | ||
type Config struct { | ||
TemplatesFolder string `json:"templatesFolder" yaml:"templatesFolder"` | ||
} | ||
|
||
// fileExists checks if a file exists | ||
func fileExists(filename string) bool { | ||
_, err := os.Stat(filename) | ||
return err == nil | ||
} | ||
|
||
// findConfig searches for the config file in the current directory and its parents | ||
func findConfig(baseName string) (string, error) { | ||
dir, err := os.Getwd() | ||
if err != nil { | ||
return "", fmt.Errorf("failed to get pwd: %w", err) | ||
} | ||
|
||
extensions := []string{".json", ".yaml", ".yml"} | ||
|
||
for { | ||
for _, ext := range extensions { | ||
configPath := filepath.Join(dir, baseName+ext) | ||
if fileExists(configPath) { | ||
return configPath, nil | ||
} | ||
} | ||
|
||
parentDir := filepath.Dir(dir) | ||
if parentDir == dir { | ||
break | ||
} | ||
dir = parentDir | ||
} | ||
|
||
return "", fmt.Errorf("config file %s[.json/.yaml/.yml] not found", baseName) | ||
} | ||
|
||
// ReadConfigFile reads and parses a JSON or YAML file into the provided struct | ||
func ReadConfigFile(filename string, v *Config) error { | ||
data, err := os.ReadFile(filename) | ||
if err != nil { | ||
return fmt.Errorf("failed to read file: %w", err) | ||
} | ||
|
||
// Detect file type and parse accordingly | ||
switch filepath.Ext(filename) { | ||
case ".json": | ||
err = json.Unmarshal(data, v) | ||
case ".yaml", ".yml": | ||
err = yaml.Unmarshal(data, v) | ||
default: | ||
return fmt.Errorf("unsupported file format: %s", filename) | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("failed to parse %s: %w", filename, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// GetConfig searches for a config file, reads, and parses it into a Config struct | ||
func GetConfig(baseName string) (*Config, error) { | ||
configPath, err := findConfig(baseName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var config Config | ||
if err := ReadConfigFile(configPath, &config); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &config, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package cli | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
func (c CliController) newListCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "list", | ||
Short: "List all components", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
jsonOutput, _ := cmd.Flags().GetBool("json") | ||
|
||
templates, err := c.service.ListTemplates() | ||
if err != nil { | ||
return fmt.Errorf("failed to list templates: %w", err) | ||
} | ||
|
||
if jsonOutput { | ||
data, _ := json.Marshal(templates) | ||
fmt.Printf("%s\n", data) | ||
} else { | ||
for _, c := range templates { | ||
fmt.Printf("- %s\n", c) | ||
} | ||
} | ||
return nil | ||
}, | ||
} | ||
|
||
cmd.Flags().Bool("json", false, "Output in JSON format") | ||
return cmd | ||
} | ||
|
||
func (c CliController) newAddCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "add", | ||
Short: "Add component to dir", | ||
Args: cobra.MinimumNArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
templateName := args[0] | ||
err := c.service.Add(templateName, args[1:]...) | ||
if err != nil { | ||
return fmt.Errorf("failed to add: %w", err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
cmd.Flags().Bool("json", false, "Output in JSON format") | ||
return cmd | ||
} | ||
|
||
func (c CliController) newGetCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "get", | ||
Short: "Get component", | ||
Args: cobra.MinimumNArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
fmt.Println(args) | ||
templateName := args[0] | ||
err := c.service.Add(templateName, args[1:]...) | ||
if err != nil { | ||
return fmt.Errorf("failed to get template: %w", err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
cmd.Flags().Bool("json", false, "Output in JSON format") | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package cli | ||
|
||
import ( | ||
"log/slog" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
type iService interface { | ||
ListTemplates() ([]string, error) | ||
Add(templateName string, dests ...string) error | ||
} | ||
|
||
type CliController struct { | ||
service iService | ||
logger *slog.Logger | ||
} | ||
|
||
func New(service iService, logger *slog.Logger) *CliController { | ||
return &CliController{ | ||
service: service, | ||
logger: logger, | ||
} | ||
} | ||
|
||
func (c CliController) Cmd() *cobra.Command { | ||
rootCmd := &cobra.Command{ | ||
Use: "flow", | ||
Short: "FlowTemplates CLI", | ||
} | ||
|
||
rootCmd.AddCommand(c.newListCmd()) | ||
rootCmd.AddCommand(c.newGetCmd()) | ||
rootCmd.AddCommand(c.newAddCmd()) | ||
|
||
return rootCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package source | ||
|
||
type SourceRepo struct { | ||
baseDir string | ||
} | ||
|
||
func New(baseDir string) *SourceRepo { | ||
return &SourceRepo{ | ||
baseDir: baseDir, | ||
} | ||
} |
Oops, something went wrong.