From 4ddf65e6d12486aa6b479fcfb1e0dfd4917b2876 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 6 Jan 2026 13:58:57 -0500 Subject: [PATCH] Now have a ./bin/fgen command that can generate the stubs of a new feature. --- Makefile | 5 +- features/init.go | 8 +++ static/style.css | 8 +++ tools/cmd/fgen/main.go | 78 +++++++++++++++++++++++ tools/cmd/fgen/templates/feature/api.go | 15 +++++ tools/cmd/fgen/templates/feature/db.go | 9 +++ tools/cmd/fgen/templates/feature/init.go | 10 +++ tools/cmd/fgen/templates/feature/views.go | 11 ++++ tools/cmd/fgen/templates/views/index.html | 3 + 9 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 features/init.go create mode 100644 tools/cmd/fgen/main.go create mode 100644 tools/cmd/fgen/templates/feature/api.go create mode 100644 tools/cmd/fgen/templates/feature/db.go create mode 100644 tools/cmd/fgen/templates/feature/init.go create mode 100644 tools/cmd/fgen/templates/feature/views.go create mode 100644 tools/cmd/fgen/templates/views/index.html diff --git a/Makefile b/Makefile index 1d9855f..937b7dc 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,12 @@ else curl http://127.0.0.1:9999/webapp || true endif -build: +build: cmds go build -o bin/webapp . +cmds: + go build -o bin/fgen ./tools/cmd/fgen + site: go tool ssgod diff --git a/features/init.go b/features/init.go new file mode 100644 index 0000000..0948953 --- /dev/null +++ b/features/init.go @@ -0,0 +1,8 @@ +package features + +import ( + "github.com/gofiber/fiber/v2" +) + +func Setup(app *fiber.App) { +} diff --git a/static/style.css b/static/style.css index 2e3d29d..2f6c688 100644 --- a/static/style.css +++ b/static/style.css @@ -307,6 +307,9 @@ .min-w-md { min-width: var(--container-md); } + .grow { + flex-grow: 1; + } .transform { transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); } @@ -395,6 +398,11 @@ } } } + .debug { + border-style: var(--tw-border-style) !important; + border-width: 1px !important; + border-color: var(--color-red-900) !important; + } .border-1 { border-style: var(--tw-border-style); border-width: 1px; diff --git a/tools/cmd/fgen/main.go b/tools/cmd/fgen/main.go new file mode 100644 index 0000000..5713c7f --- /dev/null +++ b/tools/cmd/fgen/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "embed" + "fmt" + "io/fs" + "flag" + "path/filepath" + "text/template" + "strings" + "os" +) + +//go:embed templates +var templates embed.FS + +type Config struct { + Name string +} + +func WriteTemplate(config Config, from string, to string) error { + source, err := templates.ReadFile(from) + if err != nil { return err } + + t := template.Must(template.New(from).Parse(string(source))) + + out, err := os.Create(to) + if err != nil { return err } + + err = t.Execute(out, config) + if err != nil { panic(err) } + + return nil +} + +func main() { + var config Config + + flag.StringVar(&config.Name, "name", "", "name of the feature to generate") + flag.Parse() + + if config.Name == "" { + fmt.Println("USAGE: fgen -name name") + return + } + + feature_dir := filepath.Join("features", config.Name) + view_dir := filepath.Join("views", config.Name) + + err := os.MkdirAll(feature_dir, 0755) + if err != nil { panic(err) } + + err = os.MkdirAll(view_dir, 0755) + if err != nil { panic(err) } + + err = fs.WalkDir(templates, "templates", + func(path string, d fs.DirEntry, err error) error { + if err != nil { return err } + target := filepath.Base(path) + + if !d.IsDir() { + switch { + case strings.HasPrefix(path, "templates/views"): + out_path := filepath.Join("views", config.Name, target) + err := WriteTemplate(config, path, out_path) + if err != nil { panic(err) } + case strings.HasPrefix(path, "templates/feature"): + out_path := filepath.Join("features", config.Name, target) + err := WriteTemplate(config, path, out_path) + if err != nil { panic(err) } + } + } + + return nil + }) + + if err != nil { panic(err) } +} diff --git a/tools/cmd/fgen/templates/feature/api.go b/tools/cmd/fgen/templates/feature/api.go new file mode 100644 index 0000000..040ed75 --- /dev/null +++ b/tools/cmd/fgen/templates/feature/api.go @@ -0,0 +1,15 @@ +package features_{{ .Name }} + +import ( + "github.com/gofiber/fiber/v2" +) + +func GetApiExample(c *fiber.Ctx) error { + tables := []string{"test", "that"} + + return c.JSON(tables) +} + +func SetupApi(app *fiber.App) { + app.Get("/api/{{ .Name }}/example", GetApiExample) +} diff --git a/tools/cmd/fgen/templates/feature/db.go b/tools/cmd/fgen/templates/feature/db.go new file mode 100644 index 0000000..15c9f29 --- /dev/null +++ b/tools/cmd/fgen/templates/feature/db.go @@ -0,0 +1,9 @@ +package features_{{ .Name }} + +import ( +// "MY/webapp/data" +// _ "github.com/mattn/go-sqlite3" +// sq "github.com/Masterminds/squirrel" +) + + diff --git a/tools/cmd/fgen/templates/feature/init.go b/tools/cmd/fgen/templates/feature/init.go new file mode 100644 index 0000000..b76fcd6 --- /dev/null +++ b/tools/cmd/fgen/templates/feature/init.go @@ -0,0 +1,10 @@ +package features_{{ .Name }} + +import ( + "github.com/gofiber/fiber/v2" +) + +func Setup(app *fiber.App) { + SetupApi(app) + SetupViews(app) +} diff --git a/tools/cmd/fgen/templates/feature/views.go b/tools/cmd/fgen/templates/feature/views.go new file mode 100644 index 0000000..013267b --- /dev/null +++ b/tools/cmd/fgen/templates/feature/views.go @@ -0,0 +1,11 @@ +package features_{{ .Name }} + +import ( + "github.com/gofiber/fiber/v2" + . "MY/webapp/common" +) + +func SetupViews(app *fiber.App) { + err := ConfigViews(app, "views/{{ .Name }}") + if err != nil { panic(err) } +} diff --git a/tools/cmd/fgen/templates/views/index.html b/tools/cmd/fgen/templates/views/index.html new file mode 100644 index 0000000..874e5c9 --- /dev/null +++ b/tools/cmd/fgen/templates/views/index.html @@ -0,0 +1,3 @@ +

{{ .Name }}

+ +

Replace me.