Skip to content

Commit

Permalink
Merge pull request #36 from spekary/globtest
Browse files Browse the repository at this point in the history
Fixing glob bug. Adding Go code generators.
  • Loading branch information
spekary authored Nov 29, 2024
2 parents 4c00b31 + 8b377ac commit abb0ee2
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 31 deletions.
37 changes: 26 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ got [options] [files]

options:
- o: The output directory. If not specified, files will be output at the same
location as the corresponding template.
location as the corresponding template. If using the -r option, files will
be output in subdirectories matching the directory names of the input files.
- t fileType: If set, will process all files in the current directory with this suffix.
If not set, you must specify the files at the end of the command line.
- i: Run `goimports` on the output files, rather than `go fmt`
Expand All @@ -91,9 +92,9 @@ options:
for include files.
- d directory: When using the -t option, will specify a directory to search.
- v verbose: Prints information about files being processed
- r recursive: Recursively processes directories. Used with the -t option and possibley -d.
- r recursive: Recursively processes directories. Used with the -t option and possibly -d.
- f force: Output files are normally not over-written if they are newer than the input file.
This otpion will force all input files to over-write the output files.
This option will force all input files to over-write the output files.
```
If a path described above starts with a module path, the actual disk location
will be substituted.
Expand Down Expand Up @@ -258,18 +259,17 @@ that returns a value.
Tag Description Example
{{=, {{s, or {{string Send a go string to output {{= fmt.Sprintf("I am %s", sVar) }}
{{i or {{int Send an int to output {{ The value is: {{i iVar }} }}
{{u or {{uint Send an unsigned Integer {{ The value is: {{u uVar }} }}
{{f or {{float Send a floating point number {{ The value is: {{f fVar }} }}
{{=, {{s, or {{string A go string {{= fmt.Sprintf("%9.2f", fVar) }}
{{i or {{int An int {{ The value is: {{i iVar }} }}
{{u or {{uint A uint {{ The value is: {{u uVar }} }}
{{f or {{float A floating point number {{ The value is: {{f fVar }} }}
{{b or {{bool A boolean ("true" or "false") {{ The value is: {{b bVar }} }}
{{w or {{bytes A byte slice {{ The value is: {{w byteSliceVar }} }}
{{v or {{stringer or Send any value that implements {{ The value is: {{objVar}} }}
{{v or {{stringer or Any value that implements {{ The value is: {{objVar}} }}
{{goIdentifier}} the Stringer interface.
This last tag can be slower than the other tags since it uses fmt.Sprint() internally,
so if this is a heavily used template, avoid it. Usually you will not notice a speed difference though,
The last tag can be slower than the other tags since they use fmt.Sprint() internally,
so if this is a heavily used template, avoid it. Usually you will not notice a speed difference though,
and the third option can be very convenient. This third option is simply any go variable surrounded by mustaches
with no spaces.
Expand Down Expand Up @@ -320,6 +320,21 @@ func OutTemplate(toPrint string, buf bytes.Buffer) error {
}
```
### Generating Go Code
These tags are useful if your templates will be generating Go code.
{{L The value as a Go literal (uses %#v from fmt package)
{{T The Go type of the value without package name (uses %T from the fmt package)
{{PT The Go type of the value WITH the package name (uses %T from the fmt package)
The {{L tag will quote strings, but not quote numbers.
The {{PT tag will produce the Go type with a package name if given. Built in types will not
have a package name, but standard library types will. For example, a time.Time type will
result in the string "time.Time". The {{T tag will strip off the package name if there is one
in the value's type.
### Include Files
#### Include a GoT source file
Expand Down
14 changes: 14 additions & 0 deletions internal/got/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ func (a *astWalker) walk(item tokenItem) error {
case itemInterface:
fallthrough
case itemBytes:
fallthrough
case itemGoLiteral:
fallthrough
case itemGoType:
fallthrough
case itemGoTypeWithPackage:
return a.outputValue(item)

case itemGoErr:
Expand Down Expand Up @@ -220,6 +226,14 @@ func (a *astWalker) outputValue(item tokenItem) (err error) {
formatter = `strconv.FormatFloat(float64(%s), 'g', -1, 64)`
case itemBytes:
formatter = `string(%s[:])`
case itemGoLiteral:
formatter = `fmt.Sprintf("%%#v", %s)`
case itemGoType:
formatter = `fmt.Sprintf("%%T", %s)`
writer = `io.WriteString(_w, func()string {a,b,f := strings.Cut(%s, "."); if f {return b} else {return a}}())`
case itemGoTypeWithPackage:
formatter = `fmt.Sprintf("%%T", %s)`

default:
formatter = `%s`
}
Expand Down
6 changes: 6 additions & 0 deletions internal/got/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ func (p *parser) parseRunItem(item tokenItem) tokenItem {
fallthrough
case itemInterface:
fallthrough
case itemGoLiteral:
fallthrough
case itemGoType:
fallthrough
case itemGoTypeWithPackage:
fallthrough
case itemBytes:
fallthrough
case itemGoErr:
Expand Down
17 changes: 1 addition & 16 deletions internal/got/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ func Run(outDir string,
return err
}

if outDir, err = filepath.Abs(outDir); err != nil {
return err
}

if inputDirectory != "" {
inputDirectory = getRealPath(inputDirectory)
if inputDirectory[len(inputDirectory)-1] != filepath.Separator {
Expand Down Expand Up @@ -84,9 +80,7 @@ func Run(outDir string,
f = filepath.FromSlash(f)
dir, _ := filepath.Split(f)
if dir != "" {
if err = os.Chdir(dir); err != nil {
return fmt.Errorf("could not change to directory %s:%s", dir, err.Error())
}
dir, _ = filepath.Abs(dir)
}

var includeFiles []string
Expand Down Expand Up @@ -125,11 +119,6 @@ func Run(outDir string,

err = processFile(f, outDir2, asts, runImports)

if dir != "" {
if err2 := os.Chdir(cwd); err2 != nil {
return fmt.Errorf("could not change to cwd %s:%s", cwd, err2.Error())
}
}
if err != nil {
return err
}
Expand Down Expand Up @@ -234,10 +223,6 @@ func getRealPath(path string) string {
log.Fatal(err)
}
newPath = filepath.FromSlash(newPath)
newPath, err = filepath.Abs(path)
if err != nil {
log.Fatal(err)
}
return newPath
}

Expand Down
6 changes: 6 additions & 0 deletions internal/got/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ const (
itemFloat
itemInterface
itemBytes
itemGoLiteral
itemGoType
itemGoTypeWithPackage

itemComment

Expand Down Expand Up @@ -124,6 +127,9 @@ func init() {
tokens["{{!stringer,err"] = tokenItem{typ: itemInterface, escaped: true, withError: true}
tokens["{{ve"] = tokenItem{typ: itemInterface, escaped: false, withError: true}
tokens["{{stringer,err"] = tokenItem{typ: itemInterface, escaped: false, withError: true}
tokens["{{L"] = tokenItem{typ: itemGoLiteral, escaped: false, withError: false}
tokens["{{T"] = tokenItem{typ: itemGoType, escaped: false, withError: false}
tokens["{{PT"] = tokenItem{typ: itemGoTypeWithPackage, escaped: false, withError: false}

tokens["{{#"] = tokenItem{typ: itemComment}
tokens["{{//"] = tokenItem{typ: itemComment}
Expand Down
6 changes: 6 additions & 0 deletions internal/testdata/expected/TestVars.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Boolean: true
Escaped: This<>
That: That<br>
The Other

Literal string: "Me"
Literal int: -5
Type string: string
Type struct: MyStruct
Type struct 2: template.MyStruct
Num = 0
Num = 1
Num = 2
Expand Down
10 changes: 10 additions & 0 deletions internal/testdata/src/testVars.tpl.got
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

{{= "Evaluates to a string" }}

type MyStruct struct {
a int
}

{{
Here is a number: {{i givesInt() }}
And another: {{u givesUint() }}
Expand All @@ -18,6 +22,12 @@ Boolean: {{b 2 == 4/2}}

Escaped: {{!= "This<>"}}
That: {{!h "That\nThe Other"}}

Literal string: {{L givesString() }}
Literal int: {{L givesInt() }}
Type string: {{T givesString() }}
Type struct: {{T MyStruct{a:1} }}
Type struct 2: {{PT MyStruct{a:1} }}
}}

// Test for newlines here
Expand Down
10 changes: 6 additions & 4 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ func TestGot(t *testing.T) {
main()

// main seems to be changing working dir
_ = os.Chdir(curDir)
curDir2, _ := os.Getwd()
assert.Equal(t, curDir, curDir2)

if _, err := sys.ExecuteShellCommand(cmd); err != nil {
if e, ok := err.(*exec.Error); ok {
Expand Down Expand Up @@ -89,12 +90,13 @@ func TestRecursiveGot(t *testing.T) {
assert.NoError(t, err)

// main seems to be changing working dir
_ = os.Chdir(curDir)
curDir2, _ := os.Getwd()
assert.Equal(t, curDir, curDir2)

// verify outputs were created

files1, _ := filepath.Glob(outPath1 + string(os.PathSeparator) + "*.go")
files2, _ := filepath.Glob(outPath2 + string(os.PathSeparator) + "*.go")
files1, _ := filepath.Glob(filepath.Join(outPath1, "*.go"))
files2, _ := filepath.Glob(filepath.Join(outPath2, "*.go"))

assert.Len(t, files1, 1)
assert.Equal(t, "r1.tpl.go", filepath.Base(files1[0]))
Expand Down

0 comments on commit abb0ee2

Please sign in to comment.