The base plugin defines the callbacks every other plugin can implement and ships the global options/flags that apply to every command. It is always loaded.
The other always-loaded plugins — Setup, Build,
Run, Mcp — sit on top of Base and form the
@base_plugins set defined in lib/marea.ex. Note that the
MCP Plugin re-exposes every leaf subcommand contributed by
any other loaded plugin as a typed MCP tool, with no extra work on
the contributing plugin's side.
When it's loaded
Marea.Plugins.Base is always part of @base_plugins in lib/marea.ex,
so you don't list it in plugins:.
Callbacks defined
Implementations are no-ops; their job is to define the chain entry points other plugins implement. See 06-plugin-development.md for the intended return values.
| Callback | Purpose |
|---|---|
Marea.Plugins.Base.marea_config_schema/1 | Plugins enrich the Zoi schema for marea.yaml. |
Marea.Plugins.Base.marea_config_args/1 | Plugins enrich the CLI subcommand tree. |
Marea.Plugins.Base.marea_cmd/2 | Plugins handle parsed commands. |
Marea.Plugins.Base.marea_release_vsn/0 | Plugins compute a release version string. |
Marea.Plugins.Base.marea_init_release_file/1 | Plugins return content for files written by setup init-release. |
Marea.Plugins.Base.marea_deploy_types/1 | Plugins contribute values to the deploys.<d>.type: enum (e.g. Marea.Plugins.Helm adds :helm). |
Marea.Plugins.Base.marea_release_types/1 | Plugins contribute values to the deploys.<d>.releases.<r>.type: enum (e.g. Marea.Plugins.Docker adds :elixir and :dockerfile_dir). |
Marea.Plugins.Docker declares one additional callback,
Marea.Plugins.Docker.marea_dockerfile_assigns/2, for plugins that
want to enrich the EEx assigns Marea passes to the rendered
Dockerfile (docker.python uses it to inject a Python build stage).
Global options and flags
These are declared in Marea.Config.Args.base_args/0 and tagged
global: true. The args builder injects them into every leaf
subcommand, so they're available everywhere:
| Name | Long | Short | Default | Description |
|---|---|---|---|---|
marea_dir | --marea-dir | marea.d | Directory holding configs/, secrets/, deploys/, templates/. | |
state_dir | --state-dir | .marea | Runtime/build state directory. | |
help | --help | -h | Show help for this command. Marea normalises positional --help so marea aws --help works as expected. | |
nopause | --nopause | false | Skip "press enter to continue" prompts before destructive commands. Useful in CI. |
Reusable option specs
Marea.Config.Args ships a few helpers other plugins use to keep CLI
surface consistent:
| Helper | Long | Description |
|---|---|---|
deploy_option/0 | --deploy / -d | Pick the deploy from marea.yaml. Defaults to last value. |
release_option/0 | --release / -r | Pick the release inside the chosen deploy. |
cookie_option/0 | --cookie | Erlang cookie for run commands. Default: marea_cookie. |
pos_option/0 | --pos | Integer offset; used by run to start multiple nodes side by side, and by helm rollback to choose a revision. |
mix_env_option/1 | --mix-env | MIX_ENV for build-time and local-run commands. |
Command-handling helpers
The Base plugin also documents the conventional return values from
Marea.Plugins.Base.marea_cmd/2. Implementations in other plugins should:
match their command prefix (e.g.
[:helm | rest]);- return
:contfor everything else, so the chain continues to the next plugin; - return
:usagefor an unrecognised subcommand to print help.
defcb marea_cmd([:my_cmd | rest], %Config{} = config), do: my_cmd(rest, config)
defcb marea_cmd(_cmds, _config), do: :contBuilt-in commands
Base also ships one user-facing command for inspecting the live, plugin-enriched schema:
marea schema
└── show [--json]marea schema show
Prints a readable, indented tree of every field in the plugin-enriched schema, with type, required/default, and description.
The schema is rebuilt on every invocation by running the
Marea.Plugins.Base.marea_config_schema/1 plugin chain, so any
fields contributed by plugins listed in marea.yaml (e.g.
Marea.Plugins.Aws adding aws:) appear in the output.
Sample output (trimmed):
:plugins (array<string>) = []
:marea_dir (string) = "marea.d"
:state_dir (string) = ".marea"
:cmd_prefix (map)
:build (string)
Shell prefix wrapping every command tagged `prefix: :build` …
:deploys (map<string, map>)
:<string> (map)
:type (enum(:helm)) = :helm
Deploy type
:releases (map<string, map>)
:<string> (map)
:type (enum(:elixir | :dockerfile_dir)) = :elixir
Build strategy. :elixir auto-generates a Dockerfile …
…Conventions in the tree:
key (type)— the field name and a compact type label.= <value>— the field has a default; the value is shown verbatim.(required)— the field has no default and must be set.:<string>/:<any>— the parent is a dynamic-key map (e.g. one entry per deploy / release / aws-id); the inner schema applies to every key.- The first indented line under a field is its
description, when the schema declared one.
Flags
| Flag | Default | Purpose |
|---|---|---|
--json | off | Emit the JSON Schema produced by Zoi.to_json_schema/1 instead of the tree view. |
The --json form is meant for machine consumption: piping into jq,
generating editor completions, or feeding tools that already speak
JSON Schema.
marea schema show --json | jq '.properties.deploys'
Implementation notes
- The tree formatter walks Zoi type structs directly (the internal Map / Default / Array / Enum types) and unwraps Default to surface the default value while still reporting the inner type.
Zoi.optional/1doesn't wrap — it just setsmeta.required = falseon the inner node — so the formatter checksmeta.requiredto decide whether to print(required).- Dynamic-key maps (
Zoi.map(key_type, value_type)) are rendered asmap<key, value>with a single placeholder child key; this matches how the schema is defined fordeploys,releases,aws, androute53zones.