Skip to content

Commit f217754

Browse files
authored
feat: show templ CLI and go.mod version mismatch warning (#338)
1 parent 99fd97f commit f217754

File tree

5 files changed

+70
-8
lines changed

5 files changed

+70
-8
lines changed

cmd/templ/generatecmd/main.go

+58-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import (
3131
"github.com/cenkalti/backoff/v4"
3232
"github.com/cli/browser"
3333
"github.com/fatih/color"
34+
"golang.org/x/mod/modfile"
35+
"golang.org/x/mod/semver"
3436
)
3537

3638
type Arguments struct {
@@ -92,7 +94,7 @@ func runCmd(ctx context.Context, w io.Writer, args Arguments) (err error) {
9294
}
9395
var opts []generator.GenerateOpt
9496
if args.IncludeVersion {
95-
opts = append(opts, generator.WithVersion(templ.Version))
97+
opts = append(opts, generator.WithVersion(templ.Version()))
9698
}
9799
if args.IncludeTimestamp {
98100
opts = append(opts, generator.WithTimestamp(time.Now()))
@@ -176,6 +178,10 @@ func runCmd(ctx context.Context, w io.Writer, args Arguments) (err error) {
176178
}()
177179
}
178180
}
181+
if err = checkTemplVersion(args.Path); err != nil {
182+
logWarning(w, "templ version check failed: %v\n", err)
183+
err = nil
184+
}
179185
if firstRunComplete {
180186
if changesFound > 0 {
181187
bo.Reset()
@@ -400,3 +406,54 @@ func logWithDecoration(w io.Writer, decoration string, col color.Attribute, form
400406
color.New(col).Fprintf(w, "(%s) ", decoration)
401407
fmt.Fprintf(w, format, a...)
402408
}
409+
410+
func checkTemplVersion(dir string) error {
411+
// Walk up the directory tree, starting at dir, until we find a go.mod file.
412+
// If it contains a go.mod file, parse it and find the templ version.
413+
dir, err := filepath.Abs(dir)
414+
if err != nil {
415+
return fmt.Errorf("failed to get absolute path: %w", err)
416+
}
417+
for {
418+
current := filepath.Join(dir, "go.mod")
419+
_, err := os.Stat(current)
420+
if err != nil && !os.IsNotExist(err) {
421+
return fmt.Errorf("failed to stat go.mod file: %w", err)
422+
}
423+
if os.IsNotExist(err) {
424+
// Move up.
425+
prev := dir
426+
dir = filepath.Dir(dir)
427+
if dir == prev {
428+
return fmt.Errorf("could not find go.mod file")
429+
}
430+
continue
431+
}
432+
// Found a go.mod file.
433+
// Read it and find the templ version.
434+
m, err := os.ReadFile(current)
435+
if err != nil {
436+
return fmt.Errorf("failed to read go.mod file: %w", err)
437+
}
438+
mf, err := modfile.Parse(current, m, nil)
439+
if err != nil {
440+
return fmt.Errorf("failed to parse go.mod file: %w", err)
441+
}
442+
if mf.Module.Mod.Path == "github.com/a-h/templ" {
443+
// The go.mod file is for templ itself.
444+
return nil
445+
}
446+
for _, r := range mf.Require {
447+
if r.Mod.Path == "github.com/a-h/templ" {
448+
cmp := semver.Compare(r.Mod.Version, templ.Version())
449+
if cmp < 0 {
450+
return fmt.Errorf("generator %v is newer than templ version %v found in go.mod file, consider running `go get github.com/a-h/templ`", templ.Version(), r.Mod.Version)
451+
}
452+
if cmp > 0 {
453+
return fmt.Errorf("generator %v is older than templ version %v found in go.mod file, consider upgrading templ CLI", templ.Version(), r.Mod.Version)
454+
}
455+
return nil
456+
}
457+
}
458+
}
459+
}

cmd/templ/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ func run(w io.Writer, args []string) (code int) {
5151
case "lsp":
5252
return lspCmd(w, args[2:])
5353
case "version":
54-
fmt.Fprintln(w, templ.Version)
54+
fmt.Fprintln(w, templ.Version())
5555
return 0
5656
case "--version":
57-
fmt.Fprintln(w, templ.Version)
57+
fmt.Fprintln(w, templ.Version())
5858
return 0
5959
}
6060
fmt.Fprint(w, usageText)

cmd/templ/main_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ func TestMain(t *testing.T) {
3636
{
3737
name: `"templ version" prints version`,
3838
args: []string{"templ", "version"},
39-
expected: templ.Version + "\n",
39+
expected: templ.Version() + "\n",
4040
expectedCode: 0,
4141
},
4242
{
4343
name: `"templ --version" prints version`,
4444
args: []string{"templ", "--version"},
45-
expected: templ.Version + "\n",
45+
expected: templ.Version() + "\n",
4646
expectedCode: 0,
4747
},
4848
{

flake.nix

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
name = "templ";
3535
src = gitignore.lib.gitignoreSource ./.;
3636
subPackages = [ "cmd/templ" ];
37-
vendorHash = "sha256-skftApJDp52ZMFf4+jG0sNWK2jIXi3rDQP199suRgNw=";
37+
vendorHash = "sha256-buJArvaaKGRg3yS7BdcVY0ydyi4zah57ABeo+CHkZQU=";
3838
CGO_ENABLED = 0;
3939
flags = [
4040
"-trimpath"
@@ -82,4 +82,5 @@
8282
templ-docs = self.packages.${final.stdenv.system}.templ-docs;
8383
};
8484
};
85-
}
85+
}
86+

version.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ package templ
33
import _ "embed"
44

55
//go:embed .version
6-
var Version string
6+
var version string
7+
8+
func Version() string {
9+
return "v" + version
10+
}

0 commit comments

Comments
 (0)