Shared helpers used by every plugin.
Most functions fall in one of these groups:
- Shell —
cmd!/3,shell/3,result!/3,pause_cmd!/3run external commands with optionalcmd_prefixwrapping (e.g. to run a build inside a remote shell). - Paths —
marea_path/3andstate_path/3resolve paths undermarea_dirandstate_dirfrom aMarea.Config. - Deploy/release lookup —
get_deploy!/1andget_release!/1resolve the active deploy/release fromconfig.values. - Persistence —
save_last_values!/1/ stored values, plusget_maybe_secret/2to resolvesecret!file!keyreferences. - UI —
print/1,print_table/2,confirm?/1,stop/1.
Summary
Functions
Merges values into state.values, with new keys winning.
Prompts Yn. Returns true for everything except n/N.
Returns {deploy_name, deploy_data} for the deploy in state.values.
Returns a release version of the form YYYY_MM_DD-HH_MM_SS-<sha>.
Resolves a secret!<file>!<key> reference against config.secrets.
Returns {deploy, deploy_data, release, release_data} for the active
deploy/release. stop/1s if either is missing.
Returns config.values.
Deep-merge of two maps; on conflict, scalar values from update win.
Joins a path under config.marea_dir.
Like cmd!/3, but prints the command and waits for the user to press
enter (or Ctrl-C to abort) before running.
Prints text (ANSI iolist) to stdout with formatting applied.
Renders rows as an ANSI table with title.
Runs cmd and returns its stdout as a string. stop/1s on non-zero exit.
Persists state.values to <state_dir>/last_values (Erlang term).
Selects how stop/1 aborts in the current process.
Runs a shell command, streaming output to stdout.
Joins a path under config.state_dir (default .marea).
Aborts the current command.
Converts _ to - (used to derive CLI subcommand names from atoms).
Recursively converts a (possibly nested) keyword list or map to a plain map.
Stages mix.lock; commits if the index has changes.
Writes a deferred shell command to .marea/next_cmd.
Writes data to path only if path does not already exist.
Functions
@spec add_values(Marea.Config.t(), map()) :: Marea.Config.t()
Merges values into state.values, with new keys winning.
@spec cmd!(String.t() | [String.t()], keyword(), Marea.Config.t() | nil) :: :ok | no_return()
Like shell/3, but stop/1s the program if the command exits non-zero.
Prompts Yn. Returns true for everything except n/N.
@spec get_deploy!(Marea.Config.t()) :: {String.t(), map()}
Returns {deploy_name, deploy_data} for the deploy in state.values.
stop/1s if no deploy is selected or it isn't defined in marea.yaml.
Returns a release version of the form YYYY_MM_DD-HH_MM_SS-<sha>.
Aborts (interactively) if the working tree has uncommitted changes.
@spec get_maybe_secret(Marea.Config.t(), String.t()) :: String.t() | no_return()
Resolves a secret!<file>!<key> reference against config.secrets.
Plain (non-secret!) values are returned unchanged. Aborts if the
reference cannot be resolved.
@spec get_release!(Marea.Config.t()) :: {String.t(), map(), String.t(), map()}
Returns {deploy, deploy_data, release, release_data} for the active
deploy/release. stop/1s if either is missing.
@spec get_values(Marea.Config.t()) :: map()
Returns config.values.
Deep-merge of two maps; on conflict, scalar values from update win.
@spec marea_path(Marea.Config.t(), Path.t()) :: String.t()
@spec marea_path(Marea.Config.t(), Path.t(), Path.t()) :: String.t()
Joins a path under config.marea_dir.
@spec pause_cmd!( String.t() | [String.t()], keyword() | Marea.Config.t(), Marea.Config.t() | nil ) :: :ok | no_return()
Like cmd!/3, but prints the command and waits for the user to press
enter (or Ctrl-C to abort) before running.
When the --nopause flag is set, runs immediately without prompting.
@spec print(IO.ANSI.ansidata()) :: :ok
Prints text (ANSI iolist) to stdout with formatting applied.
Renders rows as an ANSI table with title.
@spec result!(String.t() | [String.t()], keyword(), Marea.Config.t() | nil) :: String.t() | no_return()
Runs cmd and returns its stdout as a string. stop/1s on non-zero exit.
Same options as shell/3.
@spec save_last_values!(Marea.Config.t()) :: :ok
Persists state.values to <state_dir>/last_values (Erlang term).
@spec set_stop_mode(:halt | :raise) :: :halt | :raise | nil
Selects how stop/1 aborts in the current process.
:halt (default) calls System.halt/1; :raise raises
Marea.Stop. Inherited only by processes that explicitly copy the
value (e.g. the MCP runner copies it into each spawned task).
@spec shell(String.t() | [String.t()], keyword(), Marea.Config.t() | nil) :: {Collectable.t(), non_neg_integer()}
Runs a shell command, streaming output to stdout.
Options
:silent— don't echo the command before running.:env— list of{name, value}env pairs.:prefix— atom key intoconfig.cmd_prefix; if set, the command is wrapped as<prefix> sh -c '<cmd>'(e.g. to run inside a remote builder).
@spec state_path(Marea.Config.t(), Path.t()) :: String.t()
@spec state_path(Marea.Config.t(), Path.t(), Path.t()) :: String.t()
Joins a path under config.state_dir (default .marea).
Aborts the current command.
Default behaviour prints text in red and halts the VM with status
126 — appropriate for the one-shot escript path.
Long-running hosts (the MCP server) cannot afford a VM halt. They
call set_stop_mode(:raise) before invoking a command so this
function raises a Marea.Stop exception instead, letting the host
catch the error and return it to the caller.
Converts _ to - (used to derive CLI subcommand names from atoms).
Recursively converts a (possibly nested) keyword list or map to a plain map.
@spec update_git!() :: :ok
Stages mix.lock; commits if the index has changes.
@spec write_cmd!(String.t() | nil, Marea.Config.t()) :: :ok
Writes a deferred shell command to .marea/next_cmd.
When cmd is nil, writes an empty (but executable) script. The escript
wrapper executes this file after the escript exits.
Writes data to path only if path does not already exist.