Skip to content

Commit

Permalink
working up to directory recursive templating, but stil wip
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-huganir committed Mar 21, 2024
1 parent d9d71f6 commit 2c0c727
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 129 deletions.
116 changes: 11 additions & 105 deletions cmd/yutc/main.go
Original file line number Diff line number Diff line change
@@ -1,114 +1,16 @@
package main

import (
"bytes"
"github.com/adam-huganir/yutc/internal"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"os"
"path/filepath"
)

var YutcLog = &internal.YutcLog

var runSettings = &internal.CLISettings{}
var rootCommand = &cobra.Command{
Use: "yutc [ OPTIONS ... ] templates ...",
Example: "yutc -d data.yaml -c common.tmpl -o output.yaml template.tmpl",

Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var err error

// Define flags
//var err error
//
//_, err = internal.ReadTar("eg.tgz")
//if err != nil {
// panic(err)
//}

if err != nil {
YutcLog.Error().Msg(err.Error())
//os.Exit(10)
}
runSettings.TemplateFiles = cmd.Flags().Args()
if runSettings.Version {
internal.PrintVersion()
os.Exit(0)
}

YutcLog.Trace().Msg("Settings:")
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
YutcLog.Trace().Msgf("\t%s: %s", flag.Name, flag.Value.String())
})

valCode := internal.ValidateArguments(runSettings)
if valCode > 0 {
YutcLog.Error().Msg("Invalid arguments")
os.Exit(int(valCode))
}

data, err := internal.MergeData(runSettings.DataFiles)
if err != nil {
panic(err)
}

commonTemplates := internal.LoadSharedTemplates(runSettings.CommonTemplateFiles)

templates, err := internal.LoadTemplates(runSettings.TemplateFiles, commonTemplates)
for templateIndex, tmpl := range templates {
var outData *bytes.Buffer
outData = new(bytes.Buffer)
err = tmpl.Execute(outData, data)
if err != nil {
panic(err)
}
basename := filepath.Base(runSettings.TemplateFiles[templateIndex])
// stdin not handled here, gotta do that
if runSettings.Output != "-" {
var outputPath string
if len(templates) > 1 {
outputPath = filepath.Join(runSettings.Output, basename)
} else {
outputPath = runSettings.Output
}
if err != nil {
panic(err)
}
isDir, err := checkIfDir(outputPath)
if err == nil && *isDir && len(templates) == 1 {
// behavior for single template file and output is a directory
// matches normal behavior expected by commands like cp, mv etc.
outputPath = filepath.Join(runSettings.Output, basename)
}
// check again in case the output path was changed and the file still exists,
// we can probably make this into just one case statement but it's late and i am tired
isDir, err = checkIfDir(outputPath)
// error here is going to be that the file doesnt exist
if err != nil || (!*isDir && runSettings.Overwrite) {
YutcLog.Debug().Msg("Overwrite enabled, writing to file(s): " + runSettings.Output)
err = os.WriteFile(outputPath, outData.Bytes(), 0644)
if err != nil {
panic(err)
}
} else {
YutcLog.Error().Msg("file exists and overwrite is not set: " + outputPath)
}
} else {
YutcLog.Debug().Msg("Writing to stdout")
_, err = os.Stdout.Write(outData.Bytes())
if err != nil {
panic(err)
}
}
}
},
}

func init() {
internal.InitLogger("")
YutcLog.Trace().Msg("yutc.init() called")

internal.InitLogger()
rootCommand.Flags().SortFlags = false
rootCommand.Flags().StringArrayVarP(
&runSettings.DataFiles,
Expand All @@ -128,16 +30,20 @@ func init() {
rootCommand.Flags().StringVarP(&runSettings.Output, "output", "o", "-", "Output file/directory, defaults to stdout")
rootCommand.Flags().BoolVarP(&runSettings.Overwrite, "overwrite", "w", false, "Overwrite existing files")
rootCommand.Flags().BoolVar(&runSettings.Version, "version", false, "Print the version and exit")
}

func main() {
rootCommand.Flags().BoolVarP(&runSettings.Recursive, "recursive", "r", false, "Recursively process directories")
rootCommand.Flags().StringArrayVar(&runSettings.ExcludePatterns, "exclude", nil, "Exclude files matching the pattern")
rootCommand.Flags().StringArrayVar(&runSettings.IncludePatterns, "include", nil, "Include files matching the pattern")

internal.InitLogger()
YutcLog.Trace().Msg("Starting yutc...")
rootCommand.PersistentFlags().BoolVarP(&runSettings.Verbose, "verbose", "v", false, "Verbose output")
}

func main() {
YutcLog.Trace().Msg("yutc.main() called, executing rootCommand")
err := rootCommand.Execute()
if err != nil {
YutcLog.Error().Msg(err.Error())
os.Exit(10101)
os.Exit(1)
}
os.Exit(0)
}
124 changes: 124 additions & 0 deletions cmd/yutc/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"bytes"
"github.com/adam-huganir/yutc/internal"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"os"
"path/filepath"
)

var runSettings = &internal.CLISettings{}

var rootCommand = &cobra.Command{
Use: "yutc",
Short: "Yet Unnamed Template CLI",
Args: cobra.MinimumNArgs(1),
Run: runRoot,
}

func runRoot(cmd *cobra.Command, args []string) {
var err error

// Define flags
//var err error
//
//_, err = internal.ReadTar("eg.tgz")
//if err != nil {
// panic(err)
//}

if err != nil {
YutcLog.Error().Msg(err.Error())
//os.Exit(10)
}
runSettings.TemplateFiles = cmd.Flags().Args()
if runSettings.Version {
internal.PrintVersion()
os.Exit(0)
}

if YutcLog.GetLevel() < 0 {
YutcLog.Trace().Msg("Settings:")
yamlSettings, err := yaml.Marshal(runSettings)
if err != nil {
panic(err) // this should never happen unless we goofed up
}
for _, line := range bytes.Split(yamlSettings, []byte("\n")) {
YutcLog.Trace().Msg(" " + string(line))
}
}

valCode := internal.ValidateArguments(runSettings)
if valCode > 0 {
YutcLog.Error().Msg("Invalid arguments")
os.Exit(int(valCode))
}

var templateFiles []string
if runSettings.Recursive {
for _, templateFile := range runSettings.TemplateFiles {
rootDirFS := os.DirFS(templateFile)
filteredPaths := internal.WalkDir(rootDirFS, runSettings.IncludePatterns, runSettings.ExcludePatterns)
templateFiles = append(templateFiles, filteredPaths...)
}
} else {
templateFiles = runSettings.TemplateFiles
}

data, err := internal.MergeData(runSettings.DataFiles)
if err != nil {
panic(err)
}

commonTemplates := internal.LoadSharedTemplates(runSettings.CommonTemplateFiles)

templates, err := internal.LoadTemplates(templateFiles, commonTemplates)
for templateIndex, tmpl := range templates {
var outData *bytes.Buffer
outData = new(bytes.Buffer)
err = tmpl.Execute(outData, data)
if err != nil {
panic(err)
}
basename := filepath.Base(templateFiles[templateIndex])
// stdin not handled here, gotta do that
if runSettings.Output != "-" {
var outputPath string
if len(templates) > 1 {
outputPath = filepath.Join(runSettings.Output, basename)
} else {
outputPath = runSettings.Output
}
if err != nil {
panic(err)
}
isDir, err := checkIfDir(outputPath)
if err == nil && *isDir && len(templates) == 1 {
// behavior for single template file and output is a directory
// matches normal behavior expected by commands like cp, mv etc.
outputPath = filepath.Join(runSettings.Output, basename)
}
// check again in case the output path was changed and the file still exists,
// we can probably make this into just one case statement but it's late and i am tired
isDir, err = checkIfDir(outputPath)
// error here is going to be that the file doesnt exist
if err != nil || (!*isDir && runSettings.Overwrite) {
YutcLog.Debug().Msg("Overwrite enabled, writing to file(s): " + runSettings.Output)
err = os.WriteFile(outputPath, outData.Bytes(), 0644)
if err != nil {
panic(err)
}
} else {
YutcLog.Error().Msg("file exists and overwrite is not set: " + outputPath)
}
} else {
YutcLog.Debug().Msg("Writing to stdout")
_, err = os.Stdout.Write(outData.Bytes())
if err != nil {
panic(err)
}
}
}
}
1 change: 1 addition & 0 deletions cmd/yutc/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main
Loading

0 comments on commit 2c0c727

Please sign in to comment.