diff --git a/cmd/root.go b/cmd/root.go index 50c4f9e..412117c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,6 +16,7 @@ var ( programDesc string outputDir string logLevel string + verbose bool ) // rootCmd renders templates using CLI flags @@ -23,19 +24,23 @@ var rootCmd = &cobra.Command{ Use: "bubblewand", Short: "A tool to generate a go project template for building a terminal application with bubbletea + cobra + viper + log", Run: func(cmd *cobra.Command, args []string) { - // Fill ProgramData from CLI input - data := render.ProgramData{ - ModName: modName, - PackageName: packageName, - ProgramVersion: programVersion, - ProgramDesc: programDesc, - } + // Initialize logging with log level and flags + initLogging() - // Render templates to the specified output directory - if err := render.RenderTemplates(data, outputDir); err != nil { - logger.Log.Fatalf("rendering failed: %v",err) - } + // Fill ProgramData from CLI input + data := render.ProgramData{ + ModName: modName, + PackageName: packageName, + ProgramVersion: programVersion, + ProgramDesc: programDesc, + } + + // Render templates to the specified output directory + if err := render.RenderTemplates(data, outputDir, verbose); err != nil { + logger.Log.Fatalf("rendering failed: %v", err) + } }, + } @@ -48,6 +53,7 @@ func init() { rootCmd.Flags().StringVar(&programDesc, "program-desc", "", "Program description") rootCmd.Flags().StringVarP(&outputDir, "output", "o", "output", "Output directory for rendered files") rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Log level (debug, info, warn, error)") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output") // Mark required rootCmd.MarkFlagRequired("mod-name") rootCmd.MarkFlagRequired("package-name") diff --git a/cmd/tui.go b/cmd/tui.go index 51c1aff..17c7acf 100644 --- a/cmd/tui.go +++ b/cmd/tui.go @@ -31,7 +31,7 @@ var tuiCmd = &cobra.Command{ } // Render templates with user input - if err := render.RenderTemplates(data, data.OutputDir); err != nil { + if err := render.RenderTemplates(data, data.OutputDir, verbose); err != nil { logger.Log.Fatalf("rendering failed: %v", err) } }, diff --git a/internal/render/render.go b/internal/render/render.go index df1840f..4eea7c2 100644 --- a/internal/render/render.go +++ b/internal/render/render.go @@ -1,60 +1,71 @@ package render import ( - "fmt" - "os" - "path/filepath" - "strings" - "text/template" - "specCon18/bubblewand/internal/logger" + "os" + "path/filepath" + "strings" + "text/template" + "specCon18/bubblewand/internal/logger" ) // ProgramData holds user-supplied template values type ProgramData struct { - ModName string - PackageName string - ProgramVersion string - ProgramDesc string - OutputDir string + ModName string + PackageName string + ProgramVersion string + ProgramDesc string + OutputDir string } // RenderTemplates renders all .tmpl files from the templates/ directory into outputDir -func RenderTemplates(data ProgramData, outputDir string) error { - return filepath.Walk("templates", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() || !strings.HasSuffix(info.Name(), ".tmpl") { - return nil - } +func RenderTemplates(data ProgramData, outputDir string, verbose bool) error { + var renderedFiles int - // Create relative output path (preserving subdirs) - relPath, err := filepath.Rel("templates", path) - if err != nil { - return err - } - outputPath := filepath.Join(outputDir, strings.TrimSuffix(relPath, ".tmpl")) + err := filepath.Walk("templates", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() || !strings.HasSuffix(info.Name(), ".tmpl") { + return nil + } - // Ensure parent directories exist - if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil { - return err - } + relPath, err := filepath.Rel("templates", path) + if err != nil { + return err + } + outputPath := filepath.Join(outputDir, strings.TrimSuffix(relPath, ".tmpl")) - // Parse and execute template - tmpl, err := template.ParseFiles(path) - if err != nil { - return err - } + if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil { + return err + } - outFile, err := os.Create(outputPath) - if err != nil { - return err - } - defer outFile.Close() - - logString := fmt.Sprintf("Rendering %s → %s\n", path, outputPath) - logger.Log.Info(logString) - return tmpl.Execute(outFile, data) - }) + tmpl, err := template.ParseFiles(path) + if err != nil { + return err + } + + outFile, err := os.Create(outputPath) + if err != nil { + return err + } + defer outFile.Close() + + if verbose { + logger.Log.Infof("Rendering %s → %s", path, outputPath) + } + + renderedFiles++ + return tmpl.Execute(outFile, data) + }) + + if err != nil { + return err + } + + if !verbose && renderedFiles > 0 { + logger.Log.Info("Rendering templates") + } + + return nil }