diff --git a/lib/gen/asmodule.go b/lib/gen/asmodule.go index 5138f8eff..ce917691c 100644 --- a/lib/gen/asmodule.go +++ b/lib/gen/asmodule.go @@ -3,12 +3,14 @@ package gen import ( "fmt" "os" + "path/filepath" "sort" "strings" "cuelang.org/go/cue" "github.com/hofstadter-io/hof/lib/templates" + "github.com/hofstadter-io/hof/lib/yagu" ) func (R *Runtime) AsModule() error { @@ -99,51 +101,66 @@ func (R *Runtime) AsModule() error { "WatchXcue": FP.WatchXcue, } - // render template - ft, err := templates.CreateFromString("as-module", asModuleTemplate, nil) - if err != nil { - return err - } - bs, err := ft.Render(data) - if err != nil { - return err + // local helper to render and write embedded templates + render := func(outpath, content string) error { + if R.Verbosity > 0 { + fmt.Println("rendering:", outpath) + } + ft, err := templates.CreateFromString(outpath, content, nil) + if err != nil { + return err + } + bs, err := ft.Render(data) + if err != nil { + return err + } + if outpath == "-" { + fmt.Println(string(bs)) + return nil + } else { + if strings.Contains(outpath, "/") { + dir, _ := filepath.Split(outpath) + err := os.MkdirAll(dir, 0755) + if err != nil { + return err + } + } + return os.WriteFile(outpath, bs, 0644) + } } - // stdout or write file + if R.Verbosity > 0 { + fmt.Println("writing:", name) + } if name == "-" { - fmt.Println(string(bs)) - } else { - // write to file - err := os.WriteFile(name + ".cue", bs, 0644) + err = render(name, asModuleTemplate) if err != nil { return err } - - // also write mod file - // render template - ft, err := templates.CreateFromString("cue-mods", cuemodsTemplate, nil) + } else { + err = render(name + ".cue", asModuleTemplate) if err != nil { return err } - bs, err := ft.Render(data) + err = render("cue.mods", cuemodsTemplate) if err != nil { return err } - err = os.WriteFile("cue.mods", bs, 0644) - - // todo, init module and fetch deps - - // parting message - ft, err = templates.CreateFromString("final-msg", finalMsg, nil) + // err = render("cue.mod/module.cue", cuemodFileTemplate) if err != nil { return err } - bs, err = ft.Render(data) + // todo, fetch deps + msg, err := yagu.Bash("hof mod vendor cue") + fmt.Println(msg) if err != nil { return err } - fmt.Println(string(bs)) + err = render("-", finalMsg) + if err != nil { + return err + } } if R.Verbosity > 0 { @@ -153,13 +170,6 @@ func (R *Runtime) AsModule() error { return nil } -const finalMsg = ` -Now run - hof mod init cue hof.io/{{ .Name }} - hof mod vendor cue - hof gen -G {{ .Name }} -` - const asModuleTemplate = ` package {{ .Name }} @@ -301,6 +311,10 @@ import ( } ` +const cuemodFileTemplate = ` +module: "hof.io/{{ .Name }}" +` + const cuemodsTemplate = ` module hof.io/{{ .Name }} @@ -310,3 +324,5 @@ require ( github.com/hofstadter-io/hof v0.6.3 ) ` + +const finalMsg = `Now run hof gen -G {{ .Name }}` diff --git a/lib/gen/generator.go b/lib/gen/generator.go index facc478c5..685df9de6 100644 --- a/lib/gen/generator.go +++ b/lib/gen/generator.go @@ -3,6 +3,7 @@ package gen import ( "fmt" "path/filepath" + "strings" "time" "cuelang.org/go/cue" @@ -277,6 +278,19 @@ func (G *Generator) initFileGens() []error { var errs []error for _, F := range G.Out { + // support text/template in output file path + if strings.Contains(F.Filepath, "{{") { + ft, err := templates.CreateFromString("filepath", F.Filepath, nil) + if err != nil { + errs = append(errs, err) + } + bs, err := ft.Render(F.In) + if err != nil { + errs = append(errs, err) + } + F.Filepath = string(bs) + } + G.OrderedFiles = append(G.OrderedFiles, F) G.Files[F.Filepath] = F } diff --git a/lib/templates/helpers.go b/lib/templates/helpers.go index 476b297fa..62eae4149 100644 --- a/lib/templates/helpers.go +++ b/lib/templates/helpers.go @@ -61,6 +61,7 @@ var funcMap = template.FuncMap{ "replace": Helper_replace, "hasprefix": Helper_hasprefix, "hassuffix": Helper_hassuffix, + "trimspace": Helper_trimspace, "trimprefix": Helper_trimprefix, "trimsuffix": Helper_trimsuffix, "trimto": Helper_trimto_first, @@ -290,6 +291,9 @@ func Helper_hassuffix(str, suf string) string { } return "" } +func Helper_trimspace(str string) string { + return strings.TrimSpace(str) +} func Helper_trimprefix(str, pre string) string { return strings.TrimPrefix(str, pre) } diff --git a/test/watch/.hof/shadow/DemoExample/out.txt b/test/watch/.hof/shadow/DemoExample/out.txt deleted file mode 100644 index 31b086ddb..000000000 --- a/test/watch/.hof/shadow/DemoExample/out.txt +++ /dev/null @@ -1,25 +0,0 @@ - -NAME: ALICE -name: alice -role: user - - - -NAME: COW -name: cow -role: mooer - - - -NAME: DARTH -name: darth -role: evil - - - -NAME: MARY -name: mary -role: admin - - - diff --git a/test/watch/.hof/shadow/DemoExample/users.txt b/test/watch/.hof/shadow/DemoExample/users.txt deleted file mode 100644 index 299a9ddd1..000000000 --- a/test/watch/.hof/shadow/DemoExample/users.txt +++ /dev/null @@ -1,30 +0,0 @@ -package foo - -// function Alice pretend time -func Alice( User int ) error { - fmt.Println("hey ALICE!!") - - return nil -} - -// function Cow pretend time -func Cow( Mooer int ) error { - fmt.Println("hey COW!!") - - return nil -} - -// function Darth pretend time -func Darth( Evil int ) error { - fmt.Println("hey DARTH!!") - - return nil -} - -// function Mary pretend time -func Mary( Admin int ) error { - fmt.Println("hey MARY!!") - - return nil -} - diff --git a/test/watch/cue.mods b/test/watch/cue.mods deleted file mode 100644 index 1248e3651..000000000 --- a/test/watch/cue.mods +++ /dev/null @@ -1,5 +0,0 @@ -package hof.io/demo - -require ( - github.com/hofstadter-io/hof/v0.6.3-rc.2 -) diff --git a/test/watch/data.cue b/test/watch/data.cue index 4fcbd2cec..652d8df3a 100644 --- a/test/watch/data.cue +++ b/test/watch/data.cue @@ -5,11 +5,6 @@ import "strings" users: [n=string]: {name: n, NAME: strings.ToUpper(n)} users: { alice: role: "user" - cow: role: "mooer" darth: role: "evil" mary: role: "admin" } - -data: { - foo: "bar" -} diff --git a/test/watch/demo.cue b/test/watch/demo.cue deleted file mode 100644 index 3c05d509b..000000000 --- a/test/watch/demo.cue +++ /dev/null @@ -1,86 +0,0 @@ -package demo - -import ( - "github.com/hofstadter-io/hof/schema/gen" -) - -// This is example usage of your generator -DemoExample: #DemoGenerator & { - @gen(demo) - - // inputs to the generator - "users": users - "data": data - - // other settings - Diff3: false - Outdir: "./" - - // required by examples inside the same module - // your users do not set or see this field - PackageName: "" -} - -// This is your reusable generator module -// -#DemoGenerator: gen.#Generator & { - - // - // user input fields - // - - // this is the interface for this generator module - // typically you enforce schema(s) here - users: _ - data: _ - - // - // Internal Fields - // - - // This is the global input data the templates will see - // You can reshape and transform the user inputs - // While we put it under internal, you can expose In - In: { - // if you want to user your input data - // add top-level fields from your - // CUE entrypoints here, adjusting as needed - // Since you made this a module for others, - // it won't output until this field is filled - - "users": users - "data": data - - ... - } - - // required for hof CUE modules to work - // your users do not set or see this field - PackageName: string | *"hof.io/demo" - - // Templates: [{Globs: ["./templates/**/*"], TrimPrefix: "./templates/"}] - Templates: [ {Globs: [ "min.txt", "ext.txt"]}] - - // Partials: [#Templates & {Globs: ["./partials/**/*"], TrimPrefix: "./partials/"}] - Partials: [] - - // The final list of files for hof to generate - Out: [...gen.#File] & [ - t_0, - t_1, - - ] - - // These are the -T mappings - t_0: { - TemplatePath: "min.txt" - Filepath: "out.txt" - } - t_1: { - TemplatePath: "ext.txt" - Filepath: "users.txt" - } - - // so your users can build on this - ... -} diff --git a/test/watch/out.txt b/test/watch/out.txt deleted file mode 100644 index 67ef58b27..000000000 --- a/test/watch/out.txt +++ /dev/null @@ -1,21 +0,0 @@ -NAME: ALICE -name: alice -role: user - - - -NAME: COW -name: cow -role: mooer - - - -NAME: DARTH -name: darth -role: evil - - - -NAME: MARY -name: mary -role: admin \ No newline at end of file diff --git a/test/watch/users.txt b/test/watch/users.txt deleted file mode 100644 index 24ffe1d22..000000000 --- a/test/watch/users.txt +++ /dev/null @@ -1,29 +0,0 @@ -package foo - -// function Alice pretend time -func Alice( User int ) error { - fmt.Println("hey ALICE!!") - - return nil -} - -// function Cow pretend time -func Cow( Mooer int ) error { - fmt.Println("hey COW!!") - - return nil -} - -// function Darth pretend time -func Darth( Evil int ) error { - fmt.Println("hey DARTH!!") - - return nil -} - -// function Mary pretend time -func Mary( Admin int ) error { - fmt.Println("hey MARY!!") - - return nil -} \ No newline at end of file