Skip to content

Commit

Permalink
Merge pull request #146 from hofstadter-io/adhoc-datafiles
Browse files Browse the repository at this point in the history
hof/gen: support datafiles in adhoc mode
  • Loading branch information
verdverm authored Mar 4, 2023
2 parents 4060c7b + af1dc3c commit 3e17e81
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .hof/shadow/cli/cmd/hof/cmd/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ var genLong = `hof unifies CUE with Go's text/template system and diff3
# Templated output path, braces need quotes
-T templateA.txt:='{{ .name | lower }}.txt'
# Data Files are created when no template
-T :sub.val='{{ .name | lower }}.json'
# Repeated templates are used when
# 1. the output has a '[]' prefix
# 2. the input is a list or array
# The template will be processed per entry
# This also requires using a templated outpath
-T template.txt:items='[]out/{{ .filepath }}.txt'
-T :items='[]out/{{ .filepath }}.yaml'
# Output everything to a directory (out name is the same)
-O out -T types.go -T handlers.go
Expand Down
4 changes: 4 additions & 0 deletions cmd/hof/cmd/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,16 @@ var genLong = `hof unifies CUE with Go's text/template system and diff3
# Templated output path, braces need quotes
-T templateA.txt:='{{ .name | lower }}.txt'
# Data Files are created when no template
-T :sub.val='{{ .name | lower }}.json'
# Repeated templates are used when
# 1. the output has a '[]' prefix
# 2. the input is a list or array
# The template will be processed per entry
# This also requires using a templated outpath
-T template.txt:items='[]out/{{ .filepath }}.txt'
-T :items='[]out/{{ .filepath }}.yaml'
# Output everything to a directory (out name is the same)
-O out -T types.go -T handlers.go
Expand Down
4 changes: 4 additions & 0 deletions design/cmds/gen.cue
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,16 @@ hof unifies CUE with Go's text/template system and diff3
# Templated output path, braces need quotes
-T templateA.txt:='{{ .name | lower }}.txt'
# Data Files are created when no template
-T :sub.val='{{ .name | lower }}.json'
# Repeated templates are used when
# 1. the output has a '[]' prefix
# 2. the input is a list or array
# The template will be processed per entry
# This also requires using a templated outpath
-T template.txt:items='[]out/{{ .filepath }}.txt'
-T :items='[]out/{{ .filepath }}.yaml'
# Output everything to a directory (out name is the same)
-O out -T types.go -T handlers.go
Expand Down
4 changes: 4 additions & 0 deletions docs/code/cmd-help/gen
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@ hof unifies CUE with Go's text/template system and diff3
# Templated output path, braces need quotes
-T templateA.txt:='{{ .name | lower }}.txt'

# Data Files are created when no template
-T :sub.val='{{ .name | lower }}.json'

# Repeated templates are used when
# 1. the output has a '[]' prefix
# 2. the input is a list or array
# The template will be processed per entry
# This also requires using a templated outpath
-T template.txt:items='[]out/{{ .filepath }}.txt'
-T :items='[]out/{{ .filepath }}.yaml'

# Output everything to a directory (out name is the same)
-O out -T types.go -T handlers.go
Expand Down
23 changes: 22 additions & 1 deletion docs/content/getting-started/code-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ $ hof gen data.cue schema.cue -T template.txt="{{ .name }}.txt"
These can be combined so you can control
where output goes and how files are named.

{{<codeInner title="> terminal" lang="sh">}}
$ hof gen data.cue schema.cue \
-O out \
-T template.txt="{{ .name }}.txt"
{{</codeInner>}}

### Write Data Files

Omit the template path at the beginning
and `hof` will infer the data format
from the outpath file extension

{{<codeInner title="> terminal" lang="sh">}}
# full value to a single data file
$ hof gen data.cue schema.cue -T =data.yaml

# data file per item in iterable value
$ hof gen data.cue schema.cue \
-O out \
-T :items="[]{{ .name }}.json"
{{</codeInner>}}

### Multiple Templates

Expand All @@ -111,7 +132,7 @@ Each is independent and can have different options applied to
the data and schemas from the CUE entrypoints. (we'll see this below)

{{<codeInner title="> terminal" lang="sh">}}
$ hof gen data.cue schema.cue -T template.txt -T debug.yaml -O out/
$ hof gen data.cue schema.cue -T template.txt -T =debug.yaml -O out/
{{</codeInner>}}


Expand Down
1 change: 0 additions & 1 deletion lib/fmt/fmtrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ func FormatSource(filename string, content []byte, fmtrName string, config inter
return content, fmt.Errorf("error while formatting %s", filename)
}

fmt.Println(" lens:", len(content), len(body), resp.StatusCode, string(body))
content = body

if !bytes.HasSuffix(content, []byte{'\n'}) {
Expand Down
49 changes: 42 additions & 7 deletions lib/gen/adhoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gen

import (
"fmt"
"path/filepath"
"strings"

"cuelang.org/go/cue"
Expand All @@ -27,6 +28,9 @@ type AdhocTemplateConfig struct {

// Is this a repeated template
Repeated bool

// Is this a data file? What type?
DataFormat string
}

func (R *Runtime) CreateAdhocGenerator() error {
Expand All @@ -49,7 +53,9 @@ func (R *Runtime) CreateAdhocGenerator() error {
fmt.Printf("%s -> %#v\n", tf, cfg)
}
tcfgs = append(tcfgs, cfg)
globs = append(globs, cfg.Filepath)
if cfg.Filepath != "" {
globs = append(globs, cfg.Filepath)
}
}

G := NewGenerator("AdhocGen", R.CueRuntime.CueValue, R)
Expand All @@ -76,13 +82,25 @@ func (R *Runtime) CreateAdhocGenerator() error {

addFile := func(val cue.Value) (err error) {
f := new(File)
f.TemplatePath = cfg.Filepath

err = val.Decode(&f.In)
// we need this for rendering the output
// and/or setting the input for the file
var V any
err = val.Decode(&V)
if err != nil {
return err
}

// data or template file
if cfg.DataFormat != "" {
// fmt.Println("data file:", cfg.DataFormat)
f.DatafileFormat = cfg.DataFormat
f.Value = val
} else {
f.TemplatePath = cfg.Filepath
f.In = V
}

// Set output filepath, always render as a template
op := cfg.Outpath
if op == "" {
Expand All @@ -94,16 +112,24 @@ func (R *Runtime) CreateAdhocGenerator() error {
stdout += 1
}
}

//
ft, err := templates.CreateFromString("outpath", op, nil)
if err != nil {
return err
}
bs, err := ft.Render(f.In)
bs, err := ft.Render(V)
if err != nil {
return err
}
f.Filepath = string(bs)

/*
if cfg.DataFormat != "" {
fmt.Println(*f)
}
*/

G.Out = append(G.Out, f)
return nil
}
Expand Down Expand Up @@ -154,14 +180,17 @@ func (R *Runtime) CreateAdhocGenerator() error {
}

// deconstructs the flag into struct
// semicolon separated: <filepath>:<?cuepath>@<schema>;<?outpath>
// semicolon separated: <filepath>:<?cuepath>@<schema>=<?outpath>
func parseTemplateFlag(tf string) (cfg AdhocTemplateConfig, err error) {
// look for ;
// We work our way from end to start of the string,

// look for =
parts := strings.Split(tf, "=")
if len(parts) > 1 {
tf = parts[0]
cfg.Outpath = parts[1]
}

// repeated template?
if strings.HasPrefix(cfg.Outpath, "[]") {
cfg.Outpath = strings.TrimPrefix(cfg.Outpath, "[]")
Expand All @@ -187,7 +216,13 @@ func parseTemplateFlag(tf string) (cfg AdhocTemplateConfig, err error) {
}

// should only have template path left
cfg.Filepath = tf
// if no template, then data file format
// infer from Outpath ext
if tf == "" {
cfg.DataFormat = filepath.Ext(cfg.Outpath)[1:] // trim '.' from ext
} else {
cfg.Filepath = tf
}

return cfg, nil
}
32 changes: 32 additions & 0 deletions test/render/datafiles.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
exec hof gen data.cue -T =all.yaml
cmp all.yaml expected-all.yaml

exec hof gen data.cue -T :vals=vals.yaml
cmp vals.yaml expected-vals.yaml

exec hof gen data.cue schema.cue -T =all.yaml
cmp all.yaml expected-all.yaml

-- schema.cue --
vals: [...{ name: string, data: int }]
-- data.cue --
foo: "bar"
vals: [{
name: "a"
data: 1
},{
name: "b"
data: 2
}]
-- expected-all.yaml --
foo: bar
vals:
- name: a
data: 1
- name: b
data: 2
-- expected-vals.yaml --
- name: a
data: 1
- name: b
data: 2
19 changes: 19 additions & 0 deletions test/render/repeated-datafile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exec hof gen data.cue -T :vals='[]{{ .name }}.yaml'
cmp a.yaml expected-a.yaml
cmp b.yaml expected-b.yaml

-- data.cue --
vals: [{
name: "a"
data: 1
},{
name: "b"
data: 2
}]

-- expected-a.yaml --
name: a
data: 1
-- expected-b.yaml --
name: b
data: 2

0 comments on commit 3e17e81

Please sign in to comment.