- architecture: introduction, Go modules and workspaces, application lifecycle, request lifecycle - plugins: registration, scheduling, extending, testing - verified Examples for backpack services, towel request context, pact schedules and festival events - TestDocsRequiredPages lists the eight new pages
70 lines
3.3 KiB
Markdown
70 lines
3.3 KiB
Markdown
---
|
|
title: Go modules and workspaces
|
|
description: Require the framework module, develop plugins as local modules in a Go workspace, list them in summer.yaml and fork a plugin with a replace directive.
|
|
section: architecture
|
|
order: 20
|
|
---
|
|
# Go modules and workspaces
|
|
|
|
WinterCMS uses Composer to pull in the framework and plugins. SummerCMS uses Go modules: the framework is one module, each plugin is its own module, and the application module requires them all.
|
|
|
|
## The framework module
|
|
|
|
The framework is the module `git.golem15.com/golem15/summercms`. Every framework package is imported from `git.golem15.com/golem15/summercms/modules/<name>`, for example `git.golem15.com/golem15/summercms/modules/party`.
|
|
|
|
An application requires the framework in its `go.mod`. While you work against a local checkout of the framework, point the requirement at it with a `replace` directive. For an application module `acme` in a directory next to the framework checkout:
|
|
|
|
```text
|
|
module git.golem15.com/acme/acme
|
|
|
|
go 1.27.0
|
|
|
|
require git.golem15.com/golem15/summercms v0.0.0
|
|
|
|
replace git.golem15.com/golem15/summercms => ../summercms.go
|
|
```
|
|
|
|
`summer make:plugin` copies this framework `replace` into the new plugin's `go.mod`, rewritten relative to the plugin directory, so the plugin builds against the same checkout.
|
|
|
|
## The summer.yaml manifest
|
|
|
|
The manifest in the application root names the application module, the binary `summer build` writes to `bin/`, and the plugins in activation order:
|
|
|
|
```yaml
|
|
module: git.golem15.com/acme/acme
|
|
binary: acme
|
|
plugins:
|
|
- id: acme.user
|
|
module: git.golem15.com/acme/acme/plugins/user
|
|
- id: acme.blog
|
|
module: git.golem15.com/acme/acme/plugins/blog
|
|
```
|
|
|
|
`summer build` turns this list into `plugins.gen.go`. The order is the manifest order, adjusted so that each plugin comes after the plugins it requires. Plugins with no dependency between them keep the order you wrote.
|
|
|
|
## Local plugins in a workspace
|
|
|
|
A plugin you develop inside the application lives in `plugins/<name>` as its own module. `summer make:plugin acme.blog` creates it there, and `summer plugin:add plugins/blog` registers it:
|
|
|
|
- it adds the plugin to `summer.yaml`;
|
|
- it adds a `require` and a `replace` pointing at the local directory to the application's `go.mod`;
|
|
- it adds the plugin directory to the nearest `go.work`, creating one in the application root when there is none.
|
|
|
|
With a `go.work` in place, `go build`, `go test` and your editor see every local plugin module together. `summer build` uses the nearest `go.work` it finds; without one it builds in module mode.
|
|
|
|
```sh
|
|
summer make:plugin acme.blog
|
|
summer plugin:add plugins/blog
|
|
summer build
|
|
```
|
|
|
|
## Replacing and forking a plugin
|
|
|
|
WinterCMS lets you replace a plugin by overriding its classes. In SummerCMS you fork the plugin's module and point the application at your fork with a `replace` directive. The plugin ID and the import path stay the same, so nothing else in the application changes:
|
|
|
|
```text
|
|
replace git.golem15.com/acme/user => ../forks/user
|
|
```
|
|
|
|
Keep the fork's plugin ID unchanged when it must stand in for the original, since other plugins require it by ID. If you want both to exist side by side, give the fork a new module path and a new ID and list it in `summer.yaml` instead. To extend a plugin without forking it, see [Extending plugins](../plugins/extending.md).
|