diff --git a/internal/build/new_golden_test.go b/internal/build/new_golden_test.go new file mode 100644 index 0000000..cf7fda9 --- /dev/null +++ b/internal/build/new_golden_test.go @@ -0,0 +1,152 @@ +package build + +import ( + "bytes" + "encoding/base64" + "flag" + "os" + "path/filepath" + "strings" + "testing" +) + +var update = flag.Bool("update", false, "rewrite golden files") + +// goldenAppKey is the base64 of the bytes 0x00..0x1f: a fixed, non-secret +// key that keeps .env byte-stable in the goldens. +var goldenAppKey = func() string { + raw := make([]byte, 32) + for i := range raw { + raw[i] = byte(i) + } + return base64.StdEncoding.EncodeToString(raw) +}() + +// newGoldenApp runs NewApp for "demo" in a temp parent whose sibling +// summercms is a symlink to this repository, so auto-detection yields the +// relative replace ../summercms. It returns the app dir and the output with +// the parent path replaced by . +func newGoldenApp(t *testing.T, noPlugin bool) (string, []byte) { + t.Helper() + repo, err := filepath.Abs(filepath.Join("..", "..")) + if err != nil { + t.Fatal(err) + } + parent := t.TempDir() + if err := os.Symlink(repo, filepath.Join(parent, "summercms")); err != nil { + t.Fatal(err) + } + var out bytes.Buffer + dir, err := NewApp(t.Context(), NewOptions{ + Name: "demo", + Parent: parent, + AppKey: goldenAppKey, + NoGit: true, + NoPlugin: noPlugin, + }, &out) + if err != nil { + t.Fatalf("NewApp: %v\n%s", err, out.String()) + } + return dir, bytes.ReplaceAll(out.Bytes(), []byte(parent), []byte("")) +} + +// goldenName maps an app-relative path to its golden file name: "/" becomes +// "__" and a leading "." becomes "dot-", which keeps .env goldens clear of +// the framework's .env ignore rules. +func goldenName(rel string) string { + name := strings.ReplaceAll(rel, "/", "__") + if strings.HasPrefix(name, ".") { + name = "dot-" + name[1:] + } + return name + ".golden" +} + +// assertGolden compares got with testdata//, rewriting the file +// first when -update is set. +func assertGolden(t *testing.T, dir, rel string, got []byte) { + t.Helper() + path := filepath.Join("testdata", dir, goldenName(rel)) + if *update { + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(path, got, 0o644); err != nil { + t.Fatal(err) + } + } + want, err := os.ReadFile(path) + if err != nil { + t.Fatalf("%s: %v (run go test -run %s -update to create it)", rel, err, t.Name()) + } + if !bytes.Equal(got, want) { + t.Errorf("%s differs from %s\n%s", rel, path, firstDiff(want, got)) + } +} + +// firstDiff prints the first differing lines of want and got with a little +// context, in a unified-diff-like form. +func firstDiff(want, got []byte) string { + wl := strings.Split(string(want), "\n") + gl := strings.Split(string(got), "\n") + i := 0 + for i < len(wl) && i < len(gl) && wl[i] == gl[i] { + i++ + } + var b strings.Builder + start := max(i-2, 0) + for j := start; j < i; j++ { + b.WriteString(" " + wl[j] + "\n") + } + for j := i; j < len(wl) && j < i+3; j++ { + b.WriteString("- " + wl[j] + "\n") + } + for j := i; j < len(gl) && j < i+3; j++ { + b.WriteString("+ " + gl[j] + "\n") + } + return b.String() +} + +func readAppFile(t *testing.T, dir, rel string) []byte { + t.Helper() + data, err := os.ReadFile(filepath.Join(dir, filepath.FromSlash(rel))) + if err != nil { + t.Fatal(err) + } + return data +} + +// TestNewGolden pins every file summer new writes for the default app. +// AGENTS.md (a symlink) and the starter plugin's go.mod/go.sum (dependency +// versions drift) are asserted instead of pinned. +func TestNewGolden(t *testing.T) { + dir, out := newGoldenApp(t, false) + for _, rel := range []string{ + "go.mod", "go.work", "summer.yaml", "main.go", "plugins.gen.go", + "config/app.yaml", "config/database.yaml", "config/http.yaml", "config/storage.yaml", + ".env", ".env.example", ".gitignore", "compose.yaml", "CLAUDE.md", + "plugins/demo/plugin.go", "plugins/demo/routes.go", + } { + assertGolden(t, "new", rel, readAppFile(t, dir, rel)) + } + assertGolden(t, "new", "next-steps.txt", out) + + pluginMod := readAppFile(t, dir, "plugins/demo/go.mod") + if !bytes.Contains(pluginMod, []byte("replace git.golem15.com/golem15/summercms => ../../../summercms")) { + t.Errorf("plugins/demo/go.mod lacks the relative framework replace:\n%s", pluginMod) + } + if _, err := os.Stat(filepath.Join(dir, "go.sum")); !os.IsNotExist(err) { + t.Errorf("app root go.sum exists or stat failed: %v", err) + } +} + +// TestNewGoldenNoPlugin pins the files that differ for summer new --no-plugin. +func TestNewGoldenNoPlugin(t *testing.T) { + dir, out := newGoldenApp(t, true) + for _, rel := range []string{"go.mod", "go.work", "summer.yaml", "plugins.gen.go", "CLAUDE.md"} { + assertGolden(t, "new-no-plugin", rel, readAppFile(t, dir, rel)) + } + assertGolden(t, "new-no-plugin", "next-steps.txt", out) + if _, err := os.Stat(filepath.Join(dir, "plugins")); !os.IsNotExist(err) { + t.Errorf("--no-plugin created plugins/ or stat failed: %v", err) + } +} diff --git a/internal/build/testdata/new-no-plugin/CLAUDE.md.golden b/internal/build/testdata/new-no-plugin/CLAUDE.md.golden new file mode 100644 index 0000000..1787850 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/CLAUDE.md.golden @@ -0,0 +1,44 @@ +# CLAUDE.md + +Guidance for AI coding agents working in this repository. `AGENTS.md` is a symlink to this file. + +## What this is + +`sm-demo-app` is a SummerCMS application: a Go program built on the SummerCMS framework, module `git.golem15.com/golem15/summercms`. `go.mod` replaces the framework with the local checkout at `../summercms`. That checkout is shared with every other application next to it: do not edit the framework from here. Change this application, or report the framework problem. + +Framework documentation for agents: + +- https://summercms.io/docs/llms.txt (index) +- https://summercms.io/docs/llms-full.txt (full text in one file) + +## Commands + +Run them from this directory. + +```sh +docker compose up -d --wait # start PostgreSQL 16 on 127.0.0.1:54320 +summer build # generate main.go and plugins.gen.go, build bin/demo +summer dev # watch sources and rebuild +summer migrate # run plugin migrations +summer serve # start the HTTP server +summer make:plugin golem15. # scaffold a plugin module under plugins/ +summer plugin:add plugins/ # register it in summer.yaml, go.mod and go.work +``` + +## Layout + +- `summer.yaml`: the application manifest (module path, binary name, ordered plugin list). +- `plugins/`: local plugin modules. +- `config/`: YAML configuration (`app.yaml`, `database.yaml`, `http.yaml`, `storage.yaml`). Any key can be overridden with a `SUMMER_` environment variable, a double underscore separating path segments (`SUMMER_DATABASE__DSN` sets `database.dsn`). +- `.env`: local secrets (database DSN, application key). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables. +- `compose.yaml`: the local PostgreSQL 16. +- `main.go`, `plugins.gen.go`: generated by `summer build` from `summer.yaml`. Do not edit them by hand; they are committed. +- `go.work`: the workspace that joins the application and its plugin modules. + +Plugins are Go modules compiled into the binary at build time; there is no runtime plugin loading. Add a plugin with `summer make:plugin` and `summer plugin:add`, then run `summer build`. + +## Naming convention + +- `sm--app`: an application, like this repository. +- `sm--plugin`: a standalone plugin module. +- `sm--theme`: a Nuxt/Vue frontend. diff --git a/internal/build/testdata/new-no-plugin/go.mod.golden b/internal/build/testdata/new-no-plugin/go.mod.golden new file mode 100644 index 0000000..53bbae9 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/go.mod.golden @@ -0,0 +1,9 @@ +module git.golem15.com/golem15/sm-demo-app + +go 1.27.0 + +toolchain go1.27.0 + +require git.golem15.com/golem15/summercms v0.0.0 + +replace git.golem15.com/golem15/summercms => ../summercms diff --git a/internal/build/testdata/new-no-plugin/go.work.golden b/internal/build/testdata/new-no-plugin/go.work.golden new file mode 100644 index 0000000..f748088 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/go.work.golden @@ -0,0 +1,7 @@ +go 1.27.0 + +toolchain go1.27.0 + +use ( + . +) diff --git a/internal/build/testdata/new-no-plugin/next-steps.txt.golden b/internal/build/testdata/new-no-plugin/next-steps.txt.golden new file mode 100644 index 0000000..e0f56b0 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/next-steps.txt.golden @@ -0,0 +1,10 @@ +created /sm-demo-app + +Next steps, inside sm-demo-app: + docker compose up -d --wait + summer build + summer migrate + summer serve + +The app has no plugins yet. Add one with summer make:plugin golem15. +and summer plugin:add plugins/, then run summer build again. diff --git a/internal/build/testdata/new-no-plugin/plugins.gen.go.golden b/internal/build/testdata/new-no-plugin/plugins.gen.go.golden new file mode 100644 index 0000000..e4fafd9 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/plugins.gen.go.golden @@ -0,0 +1,6 @@ +// Code generated by summer build. DO NOT EDIT. + +package main + +// PluginIDs is the ordered plugin list from summer.yaml. +var PluginIDs = []string{} diff --git a/internal/build/testdata/new-no-plugin/summer.yaml.golden b/internal/build/testdata/new-no-plugin/summer.yaml.golden new file mode 100644 index 0000000..1c57d49 --- /dev/null +++ b/internal/build/testdata/new-no-plugin/summer.yaml.golden @@ -0,0 +1,3 @@ +module: git.golem15.com/golem15/sm-demo-app +binary: demo +plugins: diff --git a/internal/build/testdata/new/CLAUDE.md.golden b/internal/build/testdata/new/CLAUDE.md.golden new file mode 100644 index 0000000..cdf0295 --- /dev/null +++ b/internal/build/testdata/new/CLAUDE.md.golden @@ -0,0 +1,44 @@ +# CLAUDE.md + +Guidance for AI coding agents working in this repository. `AGENTS.md` is a symlink to this file. + +## What this is + +`sm-demo-app` is a SummerCMS application: a Go program built on the SummerCMS framework, module `git.golem15.com/golem15/summercms`. `go.mod` replaces the framework with the local checkout at `../summercms`. That checkout is shared with every other application next to it: do not edit the framework from here. Change this application, or report the framework problem. + +Framework documentation for agents: + +- https://summercms.io/docs/llms.txt (index) +- https://summercms.io/docs/llms-full.txt (full text in one file) + +## Commands + +Run them from this directory. + +```sh +docker compose up -d --wait # start PostgreSQL 16 on 127.0.0.1:54320 +summer build # generate main.go and plugins.gen.go, build bin/demo +summer dev # watch sources and rebuild +summer migrate # run plugin migrations +summer serve # start the HTTP server +summer make:plugin golem15. # scaffold a plugin module under plugins/ +summer plugin:add plugins/ # register it in summer.yaml, go.mod and go.work +``` + +## Layout + +- `summer.yaml`: the application manifest (module path, binary name, ordered plugin list). +- `plugins/`: local plugin modules. `plugins/demo` is the starter plugin `golem15.demo`; its `routes.go` answers `GET /` with JSON. +- `config/`: YAML configuration (`app.yaml`, `database.yaml`, `http.yaml`, `storage.yaml`). Any key can be overridden with a `SUMMER_` environment variable, a double underscore separating path segments (`SUMMER_DATABASE__DSN` sets `database.dsn`). +- `.env`: local secrets (database DSN, application key). Never commit it; `.gitignore` excludes it. `.env.example` lists the variables. +- `compose.yaml`: the local PostgreSQL 16. +- `main.go`, `plugins.gen.go`: generated by `summer build` from `summer.yaml`. Do not edit them by hand; they are committed. +- `go.work`: the workspace that joins the application and its plugin modules. + +Plugins are Go modules compiled into the binary at build time; there is no runtime plugin loading. Add a plugin with `summer make:plugin` and `summer plugin:add`, then run `summer build`. + +## Naming convention + +- `sm--app`: an application, like this repository. +- `sm--plugin`: a standalone plugin module. +- `sm--theme`: a Nuxt/Vue frontend. diff --git a/internal/build/testdata/new/compose.yaml.golden b/internal/build/testdata/new/compose.yaml.golden new file mode 100644 index 0000000..c635ef9 --- /dev/null +++ b/internal/build/testdata/new/compose.yaml.golden @@ -0,0 +1,22 @@ +# Local development database: docker compose up -d --wait +# PostgreSQL is published on the loopback address only, and the credentials +# match SUMMER_DATABASE__DSN in .env. +services: + postgres: + image: postgres:16 + environment: + POSTGRES_USER: summer + POSTGRES_PASSWORD: summer + POSTGRES_DB: demo + ports: + - "127.0.0.1:54320:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U summer -d demo"] + interval: 2s + timeout: 3s + retries: 30 + +volumes: + pgdata: diff --git a/internal/build/testdata/new/config__app.yaml.golden b/internal/build/testdata/new/config__app.yaml.golden new file mode 100644 index 0000000..cff5741 --- /dev/null +++ b/internal/build/testdata/new/config__app.yaml.golden @@ -0,0 +1,5 @@ +name: demo +debug: false +# The application key encrypts data at rest. Set SUMMER_APP__KEY in .env (a +# 32-byte base64 value); keep it out of this file and out of git. +key: "" diff --git a/internal/build/testdata/new/config__database.yaml.golden b/internal/build/testdata/new/config__database.yaml.golden new file mode 100644 index 0000000..fbec289 --- /dev/null +++ b/internal/build/testdata/new/config__database.yaml.golden @@ -0,0 +1,2 @@ +# Set SUMMER_DATABASE__DSN in .env; compose.yaml runs the matching PostgreSQL. +dsn: "" diff --git a/internal/build/testdata/new/config__http.yaml.golden b/internal/build/testdata/new/config__http.yaml.golden new file mode 100644 index 0000000..e15d567 --- /dev/null +++ b/internal/build/testdata/new/config__http.yaml.golden @@ -0,0 +1,5 @@ +body_limits: + # Request body limits in bytes. Keep them YAML numbers: values from the + # environment are strings and are rejected at boot. + default_bytes: 1048576 + upload_bytes: 10485760 diff --git a/internal/build/testdata/new/config__storage.yaml.golden b/internal/build/testdata/new/config__storage.yaml.golden new file mode 100644 index 0000000..17a6c4d --- /dev/null +++ b/internal/build/testdata/new/config__storage.yaml.golden @@ -0,0 +1,5 @@ +# Uploads bucket, required by summer serve. A file:// URL is a local +# directory under the application working directory. +uploads: + bucket_url: "file://./storage/app/uploads" + public_path_prefix: "/storage/uploads" diff --git a/internal/build/testdata/new/dot-env.example.golden b/internal/build/testdata/new/dot-env.example.golden new file mode 100644 index 0000000..c731889 --- /dev/null +++ b/internal/build/testdata/new/dot-env.example.golden @@ -0,0 +1,10 @@ +# The variables .env sets. summer new wrote a .env with a fresh key; copy this +# file to .env only when you need to start over. +SUMMER_DATABASE__DSN=postgres://summer:summer@127.0.0.1:54320/demo?sslmode=disable +# A 32-byte base64 application key. Generate one with ./bin/demo key:generate +# and paste only the key, without the leading check mark. +SUMMER_APP__KEY= +# Uploads bucket; config/storage.yaml already sets this default. +# SUMMER_STORAGE__UPLOADS__BUCKET_URL=file://./storage/app/uploads +# Configuration environment; selects the config overlay (default production). +# SUMMER_ENV=development diff --git a/internal/build/testdata/new/dot-env.golden b/internal/build/testdata/new/dot-env.golden new file mode 100644 index 0000000..698bce0 --- /dev/null +++ b/internal/build/testdata/new/dot-env.golden @@ -0,0 +1,5 @@ +# Local secrets for this application: the database DSN and the application +# key. .gitignore excludes this file; never commit it. Real environment +# variables override the values here. +SUMMER_DATABASE__DSN=postgres://summer:summer@127.0.0.1:54320/demo?sslmode=disable +SUMMER_APP__KEY=AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8= diff --git a/internal/build/testdata/new/dot-gitignore.golden b/internal/build/testdata/new/dot-gitignore.golden new file mode 100644 index 0000000..384a504 --- /dev/null +++ b/internal/build/testdata/new/dot-gitignore.golden @@ -0,0 +1,6 @@ +/bin/ +/tmp/ +/storage/ +.env +go.work.sum +*.exe diff --git a/internal/build/testdata/new/go.mod.golden b/internal/build/testdata/new/go.mod.golden new file mode 100644 index 0000000..1b01942 --- /dev/null +++ b/internal/build/testdata/new/go.mod.golden @@ -0,0 +1,14 @@ +module git.golem15.com/golem15/sm-demo-app + +go 1.27.0 + +toolchain go1.27.0 + +require ( + git.golem15.com/golem15/sm-demo-app/plugins/demo v0.0.0 + git.golem15.com/golem15/summercms v0.0.0 +) + +replace git.golem15.com/golem15/summercms => ../summercms + +replace git.golem15.com/golem15/sm-demo-app/plugins/demo => ./plugins/demo diff --git a/internal/build/testdata/new/go.work.golden b/internal/build/testdata/new/go.work.golden new file mode 100644 index 0000000..937d47f --- /dev/null +++ b/internal/build/testdata/new/go.work.golden @@ -0,0 +1,8 @@ +go 1.27.0 + +toolchain go1.27.0 + +use ( + . + ./plugins/demo +) diff --git a/internal/build/testdata/new/main.go.golden b/internal/build/testdata/new/main.go.golden new file mode 100644 index 0000000..2dfcd67 --- /dev/null +++ b/internal/build/testdata/new/main.go.golden @@ -0,0 +1,59 @@ +// Code generated by summer build. DO NOT EDIT. + +package main + +import ( + "fmt" + "io" + "os" + + "git.golem15.com/golem15/summercms/modules/backpack" + "git.golem15.com/golem15/summercms/modules/bonfire" + "git.golem15.com/golem15/summercms/modules/cabana" + "git.golem15.com/golem15/summercms/modules/compass" + "git.golem15.com/golem15/summercms/modules/conga" + "git.golem15.com/golem15/summercms/modules/lagoon" + "git.golem15.com/golem15/summercms/modules/pact" + "git.golem15.com/golem15/summercms/modules/party" + "git.golem15.com/golem15/summercms/modules/sunscreen" + "git.golem15.com/golem15/summercms/modules/surf" +) + +func main() { + if err := run(os.Args[1:], os.Stdout); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run(args []string, out io.Writer) error { + sunscreen.InstallDefault(os.Stderr) + cfg, err := compass.Load("config") + if err != nil { + return err + } + app := backpack.New(cfg) + plugins, err := party.Activate(app, PluginIDs) + if err != nil { + return err + } + commands := lagoon.RuntimeCommands(app, plugins) + commands = append(commands, conga.RuntimeCommands(app, plugins)...) + commands = append(commands, surf.ServeCommand(app, plugins)) + commands = append(commands, surf.RouteListCommand(app, plugins)) + commands = append(commands, cabana.RuntimeCommands(app)...) + for _, plugin := range plugins { + if hasCommands, ok := plugin.(pact.HasCommands); ok { + commands = append(commands, hasCommands.Commands()...) + } + } + if err := app.Publish(bonfire.NewCatalog(commands)); err != nil { + return err + } + root, err := bonfire.NewRoot("demo", commands, out) + if err != nil { + return err + } + root.SetArgs(args) + return root.Execute() +} diff --git a/internal/build/testdata/new/next-steps.txt.golden b/internal/build/testdata/new/next-steps.txt.golden new file mode 100644 index 0000000..6aebac5 --- /dev/null +++ b/internal/build/testdata/new/next-steps.txt.golden @@ -0,0 +1,10 @@ +created /sm-demo-app + +Next steps, inside sm-demo-app: + docker compose up -d --wait + summer build + summer migrate + summer serve + +Then, from another terminal: + curl http://127.0.0.1:8080/ diff --git a/internal/build/testdata/new/plugins.gen.go.golden b/internal/build/testdata/new/plugins.gen.go.golden new file mode 100644 index 0000000..2dc017e --- /dev/null +++ b/internal/build/testdata/new/plugins.gen.go.golden @@ -0,0 +1,12 @@ +// Code generated by summer build. DO NOT EDIT. + +package main + +import ( + _ "git.golem15.com/golem15/sm-demo-app/plugins/demo" +) + +// PluginIDs is the ordered plugin list from summer.yaml. +var PluginIDs = []string{ + "golem15.demo", +} diff --git a/internal/build/testdata/new/plugins__demo__plugin.go.golden b/internal/build/testdata/new/plugins__demo__plugin.go.golden new file mode 100644 index 0000000..fb0f51a --- /dev/null +++ b/internal/build/testdata/new/plugins__demo__plugin.go.golden @@ -0,0 +1,60 @@ +package demo + +import ( + "embed" + "io/fs" + + "git.golem15.com/golem15/summercms/modules/backpack" + "git.golem15.com/golem15/summercms/modules/bonfire" + "git.golem15.com/golem15/summercms/modules/pact" + "git.golem15.com/golem15/summercms/modules/party" + "github.com/go-gormigrate/gormigrate/v2" +) + +var ( + _ pact.HasConfig = (*Plugin)(nil) + _ pact.HasLang = (*Plugin)(nil) + _ pact.HasMailTemplates = (*Plugin)(nil) + _ pact.HasModels = (*Plugin)(nil) + _ pact.HasMigrations = (*Plugin)(nil) + _ pact.HasCommands = (*Plugin)(nil) + _ pact.HasJobs = (*Plugin)(nil) + _ pact.HasAdminControllers = (*Plugin)(nil) +) + +//go:embed config +var configFS embed.FS + +//go:embed lang +var langFS embed.FS + +//go:embed views/mail +var mailFS embed.FS + +// Plugin is the golem15.demo plugin. +type Plugin struct{} + +func (p *Plugin) ID() string { return "golem15.demo" } +func (p *Plugin) Requires() []string { return nil } + +func (p *Plugin) Register(*backpack.App) error { return nil } +func (p *Plugin) Boot(*backpack.App) error { return nil } + +func (p *Plugin) ConfigFS() fs.FS { return configFS } +func (p *Plugin) LangFS() fs.FS { return langFS } + +func (p *Plugin) MailTemplatesFS() fs.FS { return mailFS } +func (p *Plugin) MailTemplates() []string { return nil } +func (p *Plugin) MailLayouts() map[string]string { return nil } + +func (p *Plugin) Models() []any { return generatedModels() } +func (p *Plugin) Migrations() []*gormigrate.Migration { return generatedMigrations() } +func (p *Plugin) Commands() []bonfire.Command { return generatedCommands() } +func (p *Plugin) Jobs() []pact.Job { return generatedJobs() } +func (p *Plugin) AdminControllers() []pact.AdminController { + return generatedAdminControllers() +} + +func init() { + party.Register(&Plugin{}) +} diff --git a/internal/build/testdata/new/plugins__demo__routes.go.golden b/internal/build/testdata/new/plugins__demo__routes.go.golden new file mode 100644 index 0000000..ca8dd04 --- /dev/null +++ b/internal/build/testdata/new/plugins__demo__routes.go.golden @@ -0,0 +1,23 @@ +package demo + +import ( + "encoding/json" + "net/http" + + "git.golem15.com/golem15/summercms/modules/pact" +) + +var _ pact.HasRoutes = (*Plugin)(nil) + +// Routes registers the starter route: GET / answers with a JSON greeting +// naming this plugin. +func (p *Plugin) Routes(r pact.Router) error { + r.Get("/{$}", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{ + "message": "Hello from SummerCMS", + "plugin": p.ID(), + }) + }) + return nil +} diff --git a/internal/build/testdata/new/summer.yaml.golden b/internal/build/testdata/new/summer.yaml.golden new file mode 100644 index 0000000..03979a2 --- /dev/null +++ b/internal/build/testdata/new/summer.yaml.golden @@ -0,0 +1,5 @@ +module: git.golem15.com/golem15/sm-demo-app +binary: demo +plugins: + - id: golem15.demo + module: git.golem15.com/golem15/sm-demo-app/plugins/demo