docs/content/start/cli.md (4953B)
1 +++
2 title = "Command line"
3 description = "Commands, flags, exit codes and machine-readable output"
4 weight = 40
5 toc = true
6 +++
7
8 ```
9 sqzass init [DIR]
10 sqzass build [-i DIR] [-o DIR] [--drafts] [--base-url URL] [--profile]
11 sqzass serve [-i DIR] [-b ADDR] [-p PORT] [--drafts] [--base-url URL]
12 sqzass doctor [-i DIR] [--fail-on note|warn] [--drafts]
13 ```
14
15 `--json` works on any of them.
16
17 ## init
18
19 Writes a new site into `DIR` (default `.`), creating it if needed. Refuses to
20 run where a `sqzass.toml` already exists. See
21 [Your first site](@/start/first-site.md).
22
23 ## build
24
25 | Flag | Default | |
26 |---|---|---|
27 | `-i`, `--input` | `.` | Site root — the directory holding `sqzass.toml`. |
28 | `-o`, `--output` | `<input>/public` | Resolved against your shell's directory, not the site root. |
29 | `--drafts` | | Include pages marked `draft = true`. |
30 | `--base-url` | from config | Useful for preview deployments. |
31 | `--profile` | | Per-phase timings on stderr; stdout stays as is. |
32
33 The output directory is emptied first, so a page you deleted does not linger as
34 a ghost in the built site.
35
36 `--profile` prints one line per phase — discover, assets, feeds, templates,
37 render, search, generate, write — which is how you learn whether a slow build
38 is your content or this tool:
39
40 ```
41 discover 750.8µs
42 assets 1.4ms
43 render 198.9ms
44 write 1.3ms
45 ```
46
47 ## serve
48
49 Serves from memory with live reload on <http://127.0.0.1:3000>. See
50 [Development server](@/features/dev-server.md).
51
52 ## doctor
53
54 ```bash
55 sqzass doctor -i mysite
56 ```
57
58 `build` already refuses anything it cannot resolve — a broken `@/` link, a
59 missing template, two pages claiming one URL, a misspelled configuration key.
60 `doctor` is for what the build accepts and you might not have meant.
61
62 | Check | | |
63 |---|---|---|
64 | `base-url` | warn | `base_url` is still the placeholder `https://example.com`. |
65 | `untranslated` | warn | A page exists in some languages and not others. |
66 | `empty-section` | warn | A section has no pages and its index has no body — the navigation entry leads nowhere. A single-page section whose `_index.md` carries content is fine. |
67 | `description` | note | A page has no `description`. |
68 | `draft` | note | A page is excluded from the build. |
69 | `unused-template` | note | No page selects this template, and no template names it. |
70
71 `--fail-on` sets the gate, `warn` by default, and a gated run exits `7`. The
72 default is not `note` on purpose: notes are things to know, and a pipeline that
73 stops for them gets switched off rather than fixed.
74
75 ```bash
76 sqzass doctor -i mysite --fail-on note # strict
77 sqzass doctor -i mysite --json # every finding as data
78 ```
79
80 ## Exit codes
81
82 A build either succeeds or tells you which part of your site it could not
83 accept. The code is the answer to "whose fault is it" — CI can branch on it
84 without parsing text.
85
86 | Code | Identifier | |
87 |---|---|---|
88 | `0` | | Success. |
89 | `1` | `SQZASS_E` | Something unclassified went wrong. |
90 | `2` | | Bad command line. This one is clap's, not ours. |
91 | `3` | `SQZASS_E_CONFIG` | `sqzass.toml` — unreadable, malformed, or a key that does not exist. |
92 | `4` | `SQZASS_E_CONTENT` | Something under `content/` — front matter, a missing title, two pages claiming one URL, an unresolved `@/` link. |
93 | `5` | `SQZASS_E_TEMPLATE` | `templates/`, `i18n/`, or an asset a template asked for and did not get. |
94 | `6` | `SQZASS_E_IO` | Reading or writing failed. |
95 | `7` | | `doctor` found something at or above the `--fail-on` gate. |
96
97 The identifier is printed with the message, so it can be searched for:
98
99 ```
100 error: [SQZASS_E_CONTENT] content/_index.md: 어디도 가리키지 않는 링크가 있습니다:
101 @/nope.md
102 ```
103
104 These numbers are a contract. They will not be reassigned to different meanings,
105 because a condition in someone's pipeline should not quietly start testing for
106 something else.
107
108 ## --json
109
110 One JSON object on stdout, and nothing else, so a script reads a single pipe.
111
112 ```console
113 $ sqzass build -i docs --json
114 {"ok":true,"output":"docs/public","pages":40}
115 ```
116
117 Failures go to **stdout** too, rather than being split across two streams:
118
119 ```console
120 $ sqzass build -i broken --json
121 {"code":4,"error":"[SQZASS_E_CONTENT] …","kind":"SQZASS_E_CONTENT","ok":false}
122 $ echo $?
123 4
124 ```
125
126 `init` and `doctor` have their own shapes:
127
128 ```console
129 $ sqzass init mysite --json
130 {"dir":"mysite","files":["sqzass.toml","content/_index.md","templates/page.html"],"ok":true}
131
132 $ sqzass doctor -i mysite --json
133 {"findings":[{"check":"base-url","file":"sqzass.toml","message":"…","severity":"warn"}],"gated":1,"ok":false}
134 ```
135
136 For `doctor`, `ok` is false whenever anything reached the `--fail-on` gate, and
137 `gated` counts those. `file` is omitted when a finding has none. The `check`
138 strings are stable — they are what a script should match on, not the message.
139
140 Without `--json`, messages go to stderr and results to stdout, which is what a
141 person at a terminal expects.