--- title: Scaffolding description: Build and watch an application, and generate plugins, models, migrations, console commands, jobs and admin controllers with the summer make commands. section: console order: 30 --- # Scaffolding The `summer` tool builds applications and generates the files a plugin is made of, the way `create:plugin`, `create:model` and the other `create:` commands do in WinterCMS. Every generated file compiles as written, so you can build straight after running a command. ## Building and watching | Command | Purpose | |---------|---------| | `summer build` | Reads `summer.yaml`, generates `plugins.gen.go` and `main.go`, and builds the binary into `bin/`. Run it from the application directory or any directory below it. | | `summer dev` | Builds the application, starts the binary, and rebuilds and restarts it whenever a Go or YAML source, `go.mod`, `go.work`, `.env` or `summer.yaml` changes. | ```sh summer build summer dev ``` Do not edit `main.go` or `plugins.gen.go`: `summer build` rewrites them from the manifest. ## Creating a plugin `summer make:plugin` takes a plugin ID in `vendor.plugin` form and creates the plugin module in `plugins/` of the current application, with the directory layout described in [Plugin registration](../plugins/registration.md): ```sh summer make:plugin acme.blog summer plugin:add plugins/blog ``` `summer plugin:add` then registers the local module: it adds the plugin to `summer.yaml`, adds a `require` and a local `replace` to the application's `go.mod`, and adds the directory to `go.work`. The next `summer build` compiles the plugin in. ## Generating plugin parts The other `make:` commands add one artifact to an existing plugin. Each takes the plugin ID and an exported Go name: ```sh summer make:model acme.blog Post summer make:migration acme.blog AddPublishedAt summer make:command acme.blog Publish summer make:job acme.blog ImportPosts summer make:admin-controller acme.blog Posts ``` When you run a command inside a plugin directory, leave the ID out and pass only the name. The tool finds the plugin from the nearest `plugin.go` above the current directory: ```sh cd plugins/blog summer make:model Comment ``` | Command | Writes | Notes | |---------|--------|-------| | `summer make:model` | `models/.go` and `updates/_create_.go` | The table name is the plugin ID and the plural name in snake case, such as `acme_blog_posts`. `--no-migration` skips the migration. | | `summer make:migration` | `updates/_.go` | An empty gormigrate migration with up and down steps to fill in. | | `summer make:command` | `console/.go` | A `bonfire.Command` named `:`, such as `blog:publish`. | | `summer make:job` | `jobs/.go` | A typed job built with `conga.Job`; the plugin never imports the queue library. | | `summer make:admin-controller` | `controllers/.go`, `controllers//config_form.yaml`, `controllers//config_list.yaml`, `models//fields.yaml`, `models//columns.yaml` | A `pact.AdminController` with WinterCMS-shaped form and list configuration. | File names are the snake-case form of the name: `AddPublishedAt` becomes `add_published_at`. Migration file names start with a 14-digit timestamp, so they sort in the order you created them; migrations created in the same second get consecutive timestamps. After writing the files, every `make:` command regenerates the plugin's `registry.gen.go`, which lists the plugin's models, migrations, commands, jobs and admin controllers, and runs `go mod tidy` in the plugin. The capability methods of a scaffolded `plugin.go` return those generated lists. If your `plugin.go` was written by hand and does not call them, the command prints a note naming the accessors to add. A command refuses to overwrite an existing file or to declare a name the package already has.