feat(14.3-01): add summer new with a starter route and relative go.work

- build.NewApp writes sm-<name>-app: go.mod with a relative framework
  replace, go.work, summer.yaml, config/ and a starter plugin
- make:plugin gains an opt-in starter route (GET /{$}) in the same
  routes.go template; plain make:plugin output is unchanged
- plugin:add writes go.work use paths relative to the go.work directory
- bonfire accepts new as a bare tool command name
This commit is contained in:
Jakub Zych
2026-10-08 11:37:53 +02:00
parent 86fcd5d4fd
commit 7bc955a0c2
10 changed files with 423 additions and 15 deletions

View File

@@ -34,6 +34,7 @@ func toolCommands() []bonfire.Command {
makeJobCommand(),
makeAdminControllerCommand(),
addPluginCommand(),
newCommand(),
devCommand(),
parityProxyCommand(),
parityRecordCommand(),
@@ -297,3 +298,35 @@ func addPluginCommand() bonfire.Command {
},
}
}
func newCommand() bonfire.Command {
return bonfire.Command{
Name: "new",
Description: "Create a SummerCMS application in sm-<name>-app",
Args: []bonfire.Arg{{
Name: "name",
Description: "Application name: lower-case letters and digits, starting with a letter; not a Go keyword, main or internal",
Required: true,
}},
Flags: []bonfire.Flag{
{Name: "framework", Description: "Path to the framework checkout"},
},
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
name, ok := in.Argument("name")
if !ok || name == "" {
return fmt.Errorf("new requires an application name")
}
dir, err := os.Getwd()
if err != nil {
return err
}
framework, _ := in.Flag("framework")
_, err = build.NewApp(ctx, build.NewOptions{
Name: name,
Parent: dir,
Framework: framework,
}, out)
return err
},
}
}

View File

@@ -19,7 +19,7 @@ func TestToolCommandNames(t *testing.T) {
for _, c := range toolCommands() {
names = append(names, c.Name)
}
for _, want := range []string{"build", "make:plugin", "make:model", "make:migration", "make:command", "make:job", "make:admin-controller", "plugin:add", "dev", "migrate", "migrate:rollback", "migrate:status", "serve", "queue:work", "queue:clear", "schedule:run", "parity:broadcasts", "parity:upstream", "docs:build", "docs:sync", "docs:serve"} {
for _, want := range []string{"build", "make:plugin", "make:model", "make:migration", "make:command", "make:job", "make:admin-controller", "plugin:add", "new", "dev", "migrate", "migrate:rollback", "migrate:status", "serve", "queue:work", "queue:clear", "schedule:run", "parity:broadcasts", "parity:upstream", "docs:build", "docs:sync", "docs:serve"} {
if !slices.Contains(names, want) {
t.Fatalf("missing %s in %v", want, names)
}
@@ -27,6 +27,7 @@ func TestToolCommandNames(t *testing.T) {
helpWants := map[string][]string{
"make:plugin": {"vendor.plugin"},
"new": {"--framework", "name"},
"make:model": {"[plugin] [name]", "no-migration"},
"make:migration": {"[plugin] [name]"},
"make:command": {"[plugin] [name]"},