diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 5319e42..3290de0 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -2,8 +2,9 @@ package main import ( "fmt" - "github.com/urfave/cli/v2" "os" + + "github.com/urfave/cli/v2" ) func main() { @@ -14,7 +15,8 @@ func main() { tailwindCmd(), setupCmd(), vueGenCmd(), - serveCmd(), // New command for server interpreter + serveCmd(), // New command for server interpreter + templateCmd(), // New command for template interpreter } app := &cli.App{ diff --git a/cmd/cli/commands.go b/cmd/cli/commands.go index ae3d10d..9cc5fdd 100644 --- a/cmd/cli/commands.go +++ b/cmd/cli/commands.go @@ -576,65 +576,90 @@ func serveCmd() *cli.Command { func templateCmd() *cli.Command { return &cli.Command{ - Name: "template", - Aliases: []string{"tmpl"}, - Usage: "Generate code from templates using Masonry DSL", + Name: "template", + Aliases: []string{"tmpl"}, + Usage: "Generate code from templates using Masonry DSL", + Description: "This command parses a Masonry file and applies template files to generate code.", + Category: "generator", Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "templates", - Usage: "Path to template directory", - Value: "./lang_templates", - Aliases: []string{"t"}, - }, - &cli.StringFlag{ - Name: "output", - Usage: "Output destination directory", - Value: "./output", - Aliases: []string{"o"}, - }, &cli.StringFlag{ Name: "input", - Usage: "Input Masonry file path", + Usage: "Path to the Masonry input file", Required: true, Aliases: []string{"i"}, }, + &cli.StringFlag{ + Name: "template", + Usage: "Path to a single template file", + Aliases: []string{"t"}, + }, + &cli.StringFlag{ + Name: "template-dir", + Usage: "Path to a directory containing template files", + Aliases: []string{"d"}, + }, + &cli.StringFlag{ + Name: "root-template", + Usage: "Name of the root template file when using template-dir (defaults to main.tmpl)", + Value: "main.tmpl", + Aliases: []string{"r"}, + }, + &cli.StringFlag{ + Name: "output", + Usage: "Output file path (if not specified, prints to stdout)", + Aliases: []string{"o"}, + }, }, Action: func(c *cli.Context) error { - templateDir := c.String("templates") - outputDir := c.String("output") inputFile := c.String("input") + templateFile := c.String("template") + templateDir := c.String("template-dir") + rootTemplate := c.String("root-template") + outputFile := c.String("output") - fmt.Printf("Processing templates from: %s\n", templateDir) - fmt.Printf("Input file: %s\n", inputFile) - fmt.Printf("Output directory: %s\n", outputDir) - - // Read the Masonry file - content, err := os.ReadFile(inputFile) - if err != nil { - return fmt.Errorf("error reading Masonry file: %w", err) + // Validate input parameters + if templateFile == "" && templateDir == "" { + return fmt.Errorf("either --template or --template-dir must be specified") + } + if templateFile != "" && templateDir != "" { + return fmt.Errorf("cannot specify both --template and --template-dir") } - // Parse the Masonry file - parser, err := participle.Build[lang.AST]( - participle.Unquote("String"), - ) - if err != nil { - return fmt.Errorf("error building parser: %w", err) + // Set default template directory and root template if none specified + if templateFile == "" && templateDir == "" { + templateDir = "./lang_templates" + rootTemplate = "basic_go_server.tmpl" } - ast, err := parser.ParseString("", string(content)) - if err != nil { - return fmt.Errorf("error parsing Masonry file: %w", err) - } - - // Create template interpreter and process templates + // Create template templateInterpreter templateInterpreter := interpreter.NewTemplateInterpreter() - err = templateInterpreter.ProcessTemplates(*ast, templateDir, outputDir) - if err != nil { - return fmt.Errorf("error processing templates: %w", err) + + var result string + var err error + + if templateFile != "" { + // Use single template file + result, err = templateInterpreter.InterpretFromFile(inputFile, templateFile) + } else { + // Use template directory + result, err = templateInterpreter.InterpretFromDirectory(inputFile, templateDir, rootTemplate) + } + + if err != nil { + return fmt.Errorf("error generating code: %w", err) + } + + // Output result + if outputFile != "" { + err = os.WriteFile(outputFile, []byte(result), 0644) + if err != nil { + return fmt.Errorf("error writing output file: %w", err) + } + fmt.Printf("Generated code written to: %s\n", outputFile) + } else { + fmt.Print(result) } - fmt.Println("Template processing completed successfully!") return nil }, }