|
| 1 | +--- |
| 2 | +name: mops-cli |
| 3 | +description: Manage Motoko projects with the mops CLI — toolchain pinning, dependency management, type-checking, building, and linting. Use when working with mops.toml, mops.lock, running mops commands, adding/removing packages, pinning moc or lintoko versions, checking or building canisters, configuring moc flags, or setting up a new Motoko project. |
| 4 | +--- |
| 5 | + |
| 6 | +# Mops CLI |
| 7 | + |
| 8 | +Opinionated guide for Motoko projects. Covers project config, dependency management, type-checking, building, and linting. |
| 9 | + |
| 10 | +## Key Principles |
| 11 | + |
| 12 | +1. **No dfx** — always pin `moc` in `[toolchain]`. Use the newest `moc` version. |
| 13 | +2. **No `mo:base`** — it is deprecated. Always use `mo:core` (`import Array "mo:core/Array"`). |
| 14 | +3. **All config in `mops.toml`** — canisters, moc flags, toolchain versions, build settings. |
| 15 | +4. **Canister-centric workflow** — define all canisters in `[canisters]`; never pass file paths to `mops check`. Exception: library packages (no `[canisters]`) use file paths directly: `mops check src/**/*.mo`. |
| 16 | + |
| 17 | +## Project Setup |
| 18 | + |
| 19 | +### Minimal `mops.toml` |
| 20 | + |
| 21 | +```toml |
| 22 | +[toolchain] |
| 23 | +moc = "1.5.1" |
| 24 | +lintoko = "0.9.0" |
| 25 | + |
| 26 | +[dependencies] |
| 27 | +core = "2.2.0" |
| 28 | + |
| 29 | +[moc] |
| 30 | +args = ["--default-persistent-actors", "-W=M0223,M0236,M0237"] |
| 31 | + |
| 32 | +[canisters.backend] |
| 33 | +main = "src/backend/main.mo" |
| 34 | +args = ["--enhanced-migration=src/backend/migrations", "-A=M0254"] |
| 35 | + |
| 36 | +[canisters.backend.check-stable] |
| 37 | +path = ".old/src/backend/dist/backend.most" |
| 38 | + |
| 39 | +[build] |
| 40 | +outputDir = "src/backend/dist" |
| 41 | +args = ["--release"] |
| 42 | +``` |
| 43 | + |
| 44 | +`check-stable` verifies stable variable compatibility against a `.most` file from the deployed version. For a new project with no prior deployment, create a trivial `.most` file representing an empty actor: |
| 45 | + |
| 46 | +```most |
| 47 | +// Version: 1.0.0 |
| 48 | +actor { |
| 49 | + |
| 50 | +}; |
| 51 | +``` |
| 52 | + |
| 53 | +Optional canister fields: `candid` (path to .did for compatibility checking), `initArg` (Candid-encoded init args). |
| 54 | + |
| 55 | +### Warning Flags |
| 56 | + |
| 57 | +`-W=M0223,M0236,M0237` — redundant type instantiation (M0223), suggest contextual dot notation (M0236), suggest redundant explicit arguments (M0237). These are allowed (disabled) by default; `-W=` enables them as warnings. |
| 58 | + |
| 59 | +### Moc Args Layering |
| 60 | + |
| 61 | +Flags are applied in this order (later overrides earlier): |
| 62 | + |
| 63 | +1. `[moc].args` — global, all commands (check, build, test, etc.) |
| 64 | +2. `[build].args` — build only (e.g. `--release`) |
| 65 | +3. `[canisters.<name>].args` — per-canister (e.g. `--enhanced-migration=...`) |
| 66 | +4. CLI `-- <flags>` — one-off overrides |
| 67 | + |
| 68 | +## Core Commands |
| 69 | + |
| 70 | +### `mops install` |
| 71 | + |
| 72 | +```bash |
| 73 | +mops install |
| 74 | +``` |
| 75 | + |
| 76 | +Run after cloning or after manual `mops.toml` edits. Updates `mops.lock`. In CI, uses `--lock check` by default (fails if lockfile is stale). |
| 77 | + |
| 78 | +### `mops add <package>` |
| 79 | + |
| 80 | +```bash |
| 81 | +mops add core # latest version |
| 82 | +mops add core@2.2.0 # specific version |
| 83 | +mops add --dev test # dev dependency |
| 84 | +``` |
| 85 | + |
| 86 | +Updates `mops.toml` and `mops.lock`. |
| 87 | + |
| 88 | +### `mops check` |
| 89 | + |
| 90 | +Primary correctness command — runs moc check, then check-stable (if configured), then lint (if lintoko is in toolchain). |
| 91 | + |
| 92 | +```bash |
| 93 | +mops check # all canisters |
| 94 | +mops check backend # single canister |
| 95 | +mops check --fix # autofix + check + stable + lint |
| 96 | +mops check --verbose # show moc invocations |
| 97 | +mops check -- -Werror # treat warnings as errors |
| 98 | +``` |
| 99 | + |
| 100 | +**Always use canister names, not file paths.** Per-canister args from `mops.toml` are applied automatically. |
| 101 | + |
| 102 | +`--fix` applies machine-applicable fixes from both moc and lintoko in one pass. |
| 103 | + |
| 104 | +### `mops build` |
| 105 | + |
| 106 | +```bash |
| 107 | +mops build # all canisters |
| 108 | +mops build backend # single canister |
| 109 | +mops build --verbose # show compiler commands |
| 110 | +mops build -- --ai-errors # pass extra moc flags |
| 111 | +``` |
| 112 | + |
| 113 | +Produces `.wasm`, `.did`, and `.most` files in `[build].outputDir` (default `.mops/.build`). |
| 114 | + |
| 115 | +### `mops toolchain` |
| 116 | + |
| 117 | +```bash |
| 118 | +mops toolchain use moc 1.5.1 # pin specific version |
| 119 | +mops toolchain use moc latest # pin latest version (non-interactive) |
| 120 | +mops toolchain use lintoko 0.9.0 # pin specific version |
| 121 | +mops toolchain update moc # update to latest (requires existing [toolchain] entry) |
| 122 | +mops toolchain update # update all tools to latest |
| 123 | +mops toolchain bin moc # print path to binary |
| 124 | +``` |
| 125 | + |
| 126 | +**Agent note**: `toolchain use <tool>` without a version opens an interactive picker — do not use in scripts or agents. Always pass a version or `latest`. `toolchain update` only works when the tool already has a `[toolchain]` entry. |
| 127 | + |
| 128 | +### `mops remove <package>` |
| 129 | + |
| 130 | +```bash |
| 131 | +mops remove base |
| 132 | +``` |
| 133 | + |
| 134 | +### Dependency Management |
| 135 | + |
| 136 | +```bash |
| 137 | +mops outdated # list outdated dependencies |
| 138 | +mops update # update all to latest compatible |
| 139 | +mops update core # update specific package |
| 140 | +mops sync # add missing / remove unused packages |
| 141 | +``` |
| 142 | + |
| 143 | +## Other Commands |
| 144 | + |
| 145 | +### `mops test` |
| 146 | + |
| 147 | +Tests live in `test/*.test.mo`: |
| 148 | + |
| 149 | +```bash |
| 150 | +mops test # run all tests |
| 151 | +mops test my-test # filter by name |
| 152 | +mops test --mode wasi # use wasmtime (for to_candid/from_candid) |
| 153 | +mops test --reporter verbose # show Debug.print output |
| 154 | +mops test --watch # re-run on file changes |
| 155 | +``` |
| 156 | + |
| 157 | +### `mops lint` |
| 158 | + |
| 159 | +Runs lintoko (also runs automatically as part of `mops check` when lintoko is in toolchain): |
| 160 | + |
| 161 | +```bash |
| 162 | +mops lint # lint all .mo files |
| 163 | +mops lint --fix # autofix lint issues |
| 164 | +``` |
| 165 | + |
| 166 | +### `mops format` |
| 167 | + |
| 168 | +```bash |
| 169 | +mops format # format all .mo files |
| 170 | +mops format --check # check formatting without modifying |
| 171 | +``` |
| 172 | + |
| 173 | +## Common Patterns |
| 174 | + |
| 175 | +### Warning suppression for a canister |
| 176 | + |
| 177 | +Use per-canister `args` (not global) for suppressions: |
| 178 | + |
| 179 | +```toml |
| 180 | +[canisters.backend] |
| 181 | +main = "src/backend/main.mo" |
| 182 | +args = ["-A=M0198"] |
| 183 | +``` |
| 184 | + |
| 185 | +### New project |
| 186 | + |
| 187 | +```bash |
| 188 | +mops init -y |
| 189 | +mops toolchain use moc latest # pin latest moc (non-interactive) |
| 190 | +mops toolchain use lintoko latest # pin latest lintoko |
| 191 | +mops add core |
| 192 | +``` |
| 193 | + |
| 194 | +Then configure `[moc].args`, `[canisters]`, and `[build]` in `mops.toml`. |
| 195 | + |
| 196 | +To update tools later: `mops toolchain update moc` or `mops toolchain update` (all tools). |
0 commit comments