From 6af8b3bcc26bbbb0e731585a8b08af3a3829f447 Mon Sep 17 00:00:00 2001 From: Joe Davidson Date: Fri, 19 Apr 2024 15:30:39 +0100 Subject: [PATCH] feat: support build tags by copying template header over (#688) --- .version | 2 +- generator/generator.go | 15 ++ parser/v2/templatefile.go | 2 +- parser/v2/templatefile_test.go | 147 ------------------ .../templatefile_can_be_round_tripped.txt | 13 ++ .../templatefile_can_start_with_comments.txt | 14 ++ ...can_start_with_comments_and_whitespace.txt | 16 ++ ...with_multiline_comments_and_whitespace.txt | 20 +++ ..._with_multiple_comments_and_whitespace.txt | 32 ++++ .../templateheader_with_build_tags.txt | 10 ++ parser/v2/types.go | 13 +- 11 files changed, 133 insertions(+), 151 deletions(-) create mode 100644 parser/v2/testdata/templatefile_can_be_round_tripped.txt create mode 100644 parser/v2/testdata/templatefile_can_start_with_comments.txt create mode 100644 parser/v2/testdata/templatefile_can_start_with_comments_and_whitespace.txt create mode 100644 parser/v2/testdata/templatefile_can_start_with_multiline_comments_and_whitespace.txt create mode 100644 parser/v2/testdata/templatefile_can_start_with_multiple_comments_and_whitespace.txt create mode 100644 parser/v2/testdata/templateheader_with_build_tags.txt diff --git a/.version b/.version index f2511d891..9aa3ce1a8 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.663 \ No newline at end of file +0.2.664 \ No newline at end of file diff --git a/generator/generator.go b/generator/generator.go index df9c0a66f..139a8fe70 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -101,6 +101,9 @@ func (g *generator) generate() (err error) { if err = g.writeGeneratedDateComment(); err != nil { return } + if err = g.writeHeader(); err != nil { + return + } if err = g.writePackage(); err != nil { return } @@ -132,6 +135,18 @@ func (g *generator) writeGeneratedDateComment() (err error) { return err } +func (g *generator) writeHeader() (err error) { + if len(g.tf.Header) == 0 { + return nil + } + for _, n := range g.tf.Header { + if err := g.writeGoExpression(n); err != nil { + return err + } + } + return err +} + func (g *generator) writePackage() error { var r parser.Range var err error diff --git a/parser/v2/templatefile.go b/parser/v2/templatefile.go index 7c8d8ae01..91efdfb8f 100644 --- a/parser/v2/templatefile.go +++ b/parser/v2/templatefile.go @@ -102,7 +102,7 @@ func (p TemplateFileParser) Parse(pi *parse.Input) (tf TemplateFile, ok bool, er } var newLine string newLine, _, _ = parse.NewLine.Parse(pi) - tf.Header = append(tf.Header, TemplateFileGoExpression{Expression: NewExpression(line+newLine, from, pi.Position())}) + tf.Header = append(tf.Header, TemplateFileGoExpression{Expression: NewExpression(line+newLine, from, pi.Position()), BeforePackage: true}) } // Strip any whitespace between the template declaration and the first template. diff --git a/parser/v2/templatefile_test.go b/parser/v2/templatefile_test.go index cd0b91aa9..f7b7e21fb 100644 --- a/parser/v2/templatefile_test.go +++ b/parser/v2/templatefile_test.go @@ -2,10 +2,7 @@ package parser import ( "reflect" - "strings" "testing" - - "github.com/google/go-cmp/cmp" ) func TestTemplateFileParser(t *testing.T) { @@ -160,150 +157,6 @@ templ template( }) } -func TestTemplateFileRoundTrip(t *testing.T) { - tests := []struct { - name string - input string - expected string - }{ - { - name: "template files can be round tripped", - input: `package goof - -templ Hello() { - Hello -} -`, - expected: `package goof - -templ Hello() { - Hello -} -`, - }, - { - name: "template files can start with comments", - input: `// Go comment -package goof - -templ Hello() { - Hello -} -`, - expected: `// Go comment -package goof - -templ Hello() { - Hello -} -`, - }, - { - name: "template files can start with comments, mixed with whitespace", - input: ` -// Go comment - -package goof - -templ Hello() { - Hello -} -`, - expected: ` -// Go comment - -package goof - -templ Hello() { - Hello -} -`, - }, - { - name: "template files can start with multiline comments", - input: ` -/******************** -* multiline message * -********************/ - -package goof - -templ Hello() { - Hello -} -`, - expected: ` -/******************** -* multiline message * -********************/ - -package goof - -templ Hello() { - Hello -} -`, - }, - { - name: "template files can start with comments, mixed with whitespace", - input: ` -// Go comment - -/* Multiline comment on a single line */ - -/* - -Multi-line comment on multiple lines - -*/ - -package goof - -templ Hello() { - Hello -} -`, - expected: ` -// Go comment - -/* Multiline comment on a single line */ - -/* - -Multi-line comment on multiple lines - -*/ - -package goof - -templ Hello() { - Hello -} -`, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tf, err := ParseString(tt.input) - if err != nil { - t.Fatalf("failed to parse template file: %v", err) - } - - sb := new(strings.Builder) - err = tf.Write(sb) - if err != nil { - t.Fatalf("failed to write template file: %v", err) - } - output := sb.String() - - if diff := cmp.Diff(tt.expected, output); diff != "" { - t.Errorf("unexpected output (-want +got):\n%s", diff) - } - }) - } -} - func TestDefaultPackageName(t *testing.T) { tests := []struct { name string diff --git a/parser/v2/testdata/templatefile_can_be_round_tripped.txt b/parser/v2/testdata/templatefile_can_be_round_tripped.txt new file mode 100644 index 000000000..e83da95b4 --- /dev/null +++ b/parser/v2/testdata/templatefile_can_be_round_tripped.txt @@ -0,0 +1,13 @@ +-- in -- +package goof + +templ Hello() { + Hello +} + +-- out -- +package goof + +templ Hello() { + Hello +} diff --git a/parser/v2/testdata/templatefile_can_start_with_comments.txt b/parser/v2/testdata/templatefile_can_start_with_comments.txt new file mode 100644 index 000000000..fbe8ebf10 --- /dev/null +++ b/parser/v2/testdata/templatefile_can_start_with_comments.txt @@ -0,0 +1,14 @@ +-- in -- +// Go comment +package goof + +templ Hello() { + Hello +} +-- out -- +// Go comment +package goof + +templ Hello() { + Hello +} diff --git a/parser/v2/testdata/templatefile_can_start_with_comments_and_whitespace.txt b/parser/v2/testdata/templatefile_can_start_with_comments_and_whitespace.txt new file mode 100644 index 000000000..ef0c93c71 --- /dev/null +++ b/parser/v2/testdata/templatefile_can_start_with_comments_and_whitespace.txt @@ -0,0 +1,16 @@ +-- in -- +// Go comment + +package goof + +templ Hello() { + Hello +} +-- out -- +// Go comment + +package goof + +templ Hello() { + Hello +} diff --git a/parser/v2/testdata/templatefile_can_start_with_multiline_comments_and_whitespace.txt b/parser/v2/testdata/templatefile_can_start_with_multiline_comments_and_whitespace.txt new file mode 100644 index 000000000..f02789d2e --- /dev/null +++ b/parser/v2/testdata/templatefile_can_start_with_multiline_comments_and_whitespace.txt @@ -0,0 +1,20 @@ +-- in -- +/******************** +* multiline message * +********************/ + +package goof + +templ Hello() { + Hello +} +-- out -- +/******************** +* multiline message * +********************/ + +package goof + +templ Hello() { + Hello +} diff --git a/parser/v2/testdata/templatefile_can_start_with_multiple_comments_and_whitespace.txt b/parser/v2/testdata/templatefile_can_start_with_multiple_comments_and_whitespace.txt new file mode 100644 index 000000000..da2c1b3a1 --- /dev/null +++ b/parser/v2/testdata/templatefile_can_start_with_multiple_comments_and_whitespace.txt @@ -0,0 +1,32 @@ +-- in -- +// Go comment + +/* Multiline comment on a single line */ + +/* + +Multi-line comment on multiple lines + +*/ + +package goof + +templ Hello() { + Hello +} +-- out -- +// Go comment + +/* Multiline comment on a single line */ + +/* + +Multi-line comment on multiple lines + +*/ + +package goof + +templ Hello() { + Hello +} diff --git a/parser/v2/testdata/templateheader_with_build_tags.txt b/parser/v2/testdata/templateheader_with_build_tags.txt new file mode 100644 index 000000000..c8a27e0f5 --- /dev/null +++ b/parser/v2/testdata/templateheader_with_build_tags.txt @@ -0,0 +1,10 @@ +-- in -- +//go:build dev + +package p + +-- out -- +//go:build dev + +package p + diff --git a/parser/v2/types.go b/parser/v2/types.go index 7ff842b24..dcc817213 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -172,15 +172,24 @@ type TemplateFileNode interface { // TemplateFileGoExpression within a TemplateFile type TemplateFileGoExpression struct { - Expression Expression + Expression Expression + BeforePackage bool } func (exp TemplateFileGoExpression) IsTemplateFileNode() bool { return true } func (exp TemplateFileGoExpression) Write(w io.Writer, indent int) error { - data, err := format.Source([]byte(exp.Expression.Value)) + in := exp.Expression.Value + + if exp.BeforePackage { + in += "\\\\formatstring\npackage p\n\\\\formatstring" + } + data, err := format.Source([]byte(in)) if err != nil { return writeIndent(w, indent, exp.Expression.Value) } + if exp.BeforePackage { + data = bytes.TrimSuffix(data, []byte("\\\\formatstring\npackage p\n\\\\formatstring")) + } _, err = w.Write(data) return err }