Files
summercms/docs/console/introduction.md
Jakub Zych 6c606c666b feat(diary): boot list, help and completion requests quietly (quick-261028-rqc)
- helpOnly also counts no command word, list, help, cobra's shell
  completion requests and --help=<bool>, read the way pflag does
- TestHelpOnlyAgreesWithCobra pins the classification against bonfire's
  real dispatch, with the passthrough --help case as the exception
- console and logging docs describe which invocations boot quietly
2026-10-28 21:47:42 +01:00

9.8 KiB

title, description, section, order
title description section order
Console introduction The two command-line programs of SummerCMS, the summer developer tool and the application binary, and how summer delegates runtime commands. console 10

Console introduction

WinterCMS has one console entry point, php artisan. SummerCMS has two programs, because the developer tooling and the running application are separate binaries:

Program Where it comes from What it does
summer Installed once, by the curl -fsSL https://summercms.io/new | bash -s -- <name> one-liner or from a framework checkout with go install ./cmd/summer. Creates, builds and watches applications, scaffolds plugins and their parts, records API parity fixtures and builds these docs.
The application binary, for example ./bin/acme Written by summer build into the application's bin/ directory. Runs the application: the HTTP server, migrations, workers, the scheduler, admin accounts and every command its plugins add.

The application binary is what you deploy, so everything that must run in production, such as migrations and workers, is a command of the binary rather than of summer.

Run with no arguments, the binary prints the list of every command it has, the framework's and those its plugins add, the way php artisan does; --help and list print the same:

./bin/acme
./bin/acme --help
./bin/acme list
SummerCMS acme v1.4.0 (framework v0.3.2)

Usage:
  bin/acme <command> [options] [arguments]

Options:
  -h, --help            Display help for the given command
  -q, --quiet           Do not output any message
  -v|vv|vvv             Increase verbosity
      --ansi|no-ansi    Force (or disable) ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env             The environment the command runs under

Available commands:
  help                  Display help for a command
  list                  List commands
  migrate               Run plugin migrations in dependency order
  serve                 Serve the application HTTP API
 admin
  admin:create          Create an activated backend administrator
  admin:reset-password  Reset a backend administrator password and revoke existing tokens
  admin:token:create    Create a personal API token for a backend administrator
 migrate
  migrate:rollback      Roll back the last migration of a plugin
  migrate:status        Show per-plugin migration history
 queue
  queue:work            Run background job workers in the foreground

The header names the application, its version and the framework version it was built against (local when the framework comes from a local checkout). Commands without a namespace come first, then one block per namespace, the part of the name before the first colon. summer with no arguments prints its own list in the same layout.

Getting help

Both programs list their commands with no arguments, with --help and with list, and every command accepts --help for its arguments and flags:

summer
summer make:model --help
summer help migrate
./bin/acme --help
./bin/acme migrate:rollback --help
./bin/acme help migrate:rollback
./bin/acme list --all
./bin/acme list --format=json

A command's help shows its description, usage, arguments, options with their defaults, the global options, the long help and examples. list --all includes hidden commands, and list --format=json prints every command with its arguments, options and examples for scripts and agents.

A command that summer delegates to the application binary, such as summer serve, answers --help with the binary's own help, so run it inside an application directory. Asking the help command of summer about a delegated command instead prints a short description and its common flags without running the binary.

Global options

Every command of both programs accepts these options, before or after the command name:

Option Effect
-v, -vv, -vvv (--verbose) More output: -v shows info logs of every component, -vv debug logs, -vvv also source locations and SQL traces.
-q, --quiet Hides info and success lines, spinners and progress, and shows only warnings and errors in the console log; data a command prints (tokens, keys, JSON) and errors still appear. Implies -n.
--ansi, --no-ansi Forces or turns off colors and styling; --no-ansi also stops animations. The last one given wins. Without either, colors follow the terminal, NO_COLOR and FORCE_COLOR.
-n, --no-interaction Asks no questions: prompts take their defaults, and a password prompt reads piped stdin or fails with a hint.
--env The configuration environment, as SUMMER_ENV would set it: --env staging or --env=staging.

The application binary reads these options before it loads config/ and starts plugins, so --env picks the configuration and -vv applies from the first log line:

./bin/acme -vv migrate
./bin/acme migrate:status --env staging
./bin/acme -v serve --help

An invocation that only lists or describes commands (no command, list, help, --help or -h, and shell completion requests) starts the plugins with the console log at warnings, as -q would, so the info lines plugins log while they register and boot do not print above the help; -v shows them, as in the last line above. serve, queue:work, migrate and every other command boot at the configured levels, and log files keep their levels. It works for both programs and needs no rebuild of the generated main.go, only the framework version. A command that passes its arguments through unparsed counts as asking for help when --help follows it, but its console log is back at the configured levels before it runs.

Exit codes

Code Meaning
0 The command succeeded.
1 The command failed; the error is printed on stderr.
2 The command was called wrongly: an unknown command or flag, or a wrong number of arguments.

Commands that summer delegates

During development you often work from the application directory with summer alone. These summer commands find the application's summer.yaml, build bin/<binary> when it does not exist yet, and run the same command of the binary with the same arguments:

summer command Runs
summer migrate ./bin/acme migrate
summer migrate:rollback ./bin/acme migrate:rollback
summer migrate:status ./bin/acme migrate:status
summer serve ./bin/acme serve
summer queue:work ./bin/acme queue:work
summer queue:clear ./bin/acme queue:clear
summer schedule:run ./bin/acme schedule:run
summer route:list ./bin/acme route:list
summer key:generate ./bin/acme key:generate
summer admin:create ./bin/acme admin:create
summer admin:reset-password ./bin/acme admin:reset-password
summer admin:token:create ./bin/acme admin:token:create
summer admin:token:list ./bin/acme admin:token:list
summer admin:token:revoke ./bin/acme admin:token:revoke
summer admin:token:scopes ./bin/acme admin:token:scopes

summer parses no flags of these commands: every flag and argument, including --help, goes to the binary unchanged, and the binary's input is your terminal, so the password prompts of admin:create and admin:reset-password work as usual:

summer serve --addr 127.0.0.1:8123
summer serve --help
summer migrate:rollback --plugin acme.blog
summer admin:create --email admin@example.com --superuser

One leading -- is ignored, so summer serve -- --addr 127.0.0.1:8123 behaves the same as summer serve --addr 127.0.0.1:8123.

The global options go to the binary too, wherever you put them: summer -v migrate --pretend runs ./bin/acme -v migrate --pretend, and summer -q key:generate prints only the key. summer help migrate shows each delegate's examples; the binary's own help, with every flag, is summer migrate --help:

summer -v migrate --pretend
summer admin:token:create jane --scope journal.posts --json

The binary writes to your terminal directly, so it asks the production question, prints its styled startup summary and animates its spinners as if you had run it yourself. Its error stream stays separate from its output: summer route:list --json > routes.json captures only the JSON, while warnings and log lines still reach the terminal on stderr.

When the binary fails, summer exits with the binary's exit code (a usage error stays 2) and prints nothing more: the binary has already printed its error. A binary that dies by a signal makes summer exit with 128 plus the signal number, as a shell reports it: 130 for Ctrl+C (SIGINT), 143 for SIGTERM, 137 for SIGKILL. After SIGINT or SIGTERM summer prints nothing more; any other signal gets an error block from summer that names the command with the values of secret-looking flags (--password, --api-token=...) masked as ***.

When summer receives SIGINT or SIGTERM while the binary runs, it passes the signal on and waits for the binary to shut down, so stopping summer serve with Ctrl+C or kill frees its port.

summer does not rebuild an existing binary before it delegates. Run summer build after you change code, or keep summer dev running. Every other runtime command, such as deferred:purge or the commands your plugins add, is run on the binary directly.

The sections of this chapter