ic-mops 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/RELEASE.md +198 -0
- package/bundle/cli.tgz +0 -0
- package/check-requirements.ts +3 -8
- package/cli.ts +94 -11
- package/commands/bench/bench-canister.mo +17 -6
- package/commands/bench.ts +13 -16
- package/commands/build.ts +5 -6
- package/commands/check.ts +121 -0
- package/commands/format.ts +3 -18
- package/commands/lint.ts +92 -0
- package/commands/sync.ts +2 -8
- package/commands/test/test.ts +10 -20
- package/commands/toolchain/index.ts +21 -8
- package/commands/toolchain/lintoko.ts +54 -0
- package/commands/toolchain/toolchain-utils.ts +2 -0
- package/commands/watch/error-checker.ts +8 -2
- package/commands/watch/warning-checker.ts +8 -2
- package/constants.ts +23 -0
- package/dist/check-requirements.js +3 -8
- package/dist/cli.js +73 -11
- package/dist/commands/bench/bench-canister.mo +17 -6
- package/dist/commands/bench.js +7 -15
- package/dist/commands/build.js +5 -6
- package/dist/commands/check.d.ts +6 -0
- package/dist/commands/check.js +82 -0
- package/dist/commands/format.js +3 -16
- package/dist/commands/lint.d.ts +7 -0
- package/dist/commands/lint.js +69 -0
- package/dist/commands/sync.js +2 -7
- package/dist/commands/test/test.js +10 -18
- package/dist/commands/toolchain/index.d.ts +2 -2
- package/dist/commands/toolchain/index.js +18 -7
- package/dist/commands/toolchain/lintoko.d.ts +8 -0
- package/dist/commands/toolchain/lintoko.js +36 -0
- package/dist/commands/toolchain/toolchain-utils.d.ts +1 -0
- package/dist/commands/toolchain/toolchain-utils.js +1 -0
- package/dist/commands/watch/error-checker.js +8 -2
- package/dist/commands/watch/warning-checker.js +8 -2
- package/dist/constants.d.ts +15 -0
- package/dist/constants.js +21 -0
- package/dist/environments/nodejs/cli.js +6 -1
- package/dist/error.d.ts +1 -1
- package/dist/helpers/autofix-motoko.d.ts +26 -0
- package/dist/helpers/autofix-motoko.js +150 -0
- package/dist/helpers/get-moc-version.d.ts +2 -0
- package/dist/helpers/get-moc-version.js +10 -1
- package/dist/mops.d.ts +1 -0
- package/dist/mops.js +12 -1
- package/dist/package.json +3 -2
- package/dist/tests/build-no-dfx.test.d.ts +1 -0
- package/dist/tests/build-no-dfx.test.js +9 -0
- package/dist/tests/build.test.d.ts +1 -0
- package/dist/tests/build.test.js +18 -0
- package/dist/tests/check-candid.test.d.ts +1 -0
- package/dist/tests/check-candid.test.js +20 -0
- package/dist/tests/check-fix.test.d.ts +1 -0
- package/dist/tests/check-fix.test.js +89 -0
- package/dist/tests/check.test.d.ts +1 -0
- package/dist/tests/check.test.js +37 -0
- package/dist/tests/cli.test.js +4 -57
- package/dist/tests/helpers.d.ts +22 -0
- package/dist/tests/helpers.js +43 -0
- package/dist/tests/lint.test.d.ts +1 -0
- package/dist/tests/lint.test.js +15 -0
- package/dist/tests/moc-args.test.d.ts +1 -0
- package/dist/tests/moc-args.test.js +17 -0
- package/dist/tests/toolchain.test.d.ts +1 -0
- package/dist/tests/toolchain.test.js +11 -0
- package/dist/types.d.ts +8 -1
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/environments/nodejs/cli.ts +7 -1
- package/error.ts +1 -1
- package/helpers/autofix-motoko.ts +240 -0
- package/helpers/get-moc-version.ts +12 -1
- package/mops.ts +15 -1
- package/package.json +3 -2
- package/tests/__snapshots__/build-no-dfx.test.ts.snap +11 -0
- package/tests/__snapshots__/build.test.ts.snap +77 -0
- package/tests/__snapshots__/check-candid.test.ts.snap +73 -0
- package/tests/__snapshots__/check-fix.test.ts.snap +261 -0
- package/tests/__snapshots__/check.test.ts.snap +81 -0
- package/tests/__snapshots__/lint.test.ts.snap +78 -0
- package/tests/build/no-dfx/mops.toml +5 -0
- package/tests/build/no-dfx/src/Main.mo +5 -0
- package/tests/build-no-dfx.test.ts +10 -0
- package/tests/build.test.ts +24 -0
- package/tests/check/error/Error.mo +7 -0
- package/tests/check/error/mops.toml +2 -0
- package/tests/check/fix/M0223.mo +11 -0
- package/tests/check/fix/M0236.mo +11 -0
- package/tests/check/fix/M0237.mo +11 -0
- package/tests/check/fix/Ok.mo +7 -0
- package/tests/check/fix/edit-suggestions.mo +143 -0
- package/tests/check/fix/mops.toml +5 -0
- package/tests/check/fix/overlapping.mo +10 -0
- package/tests/check/fix/transitive-lib.mo +9 -0
- package/tests/check/fix/transitive-main.mo +9 -0
- package/tests/check/moc-args/Warning.mo +5 -0
- package/tests/check/moc-args/mops.toml +2 -0
- package/tests/check/success/Ok.mo +5 -0
- package/tests/check/success/Warning.mo +5 -0
- package/tests/check/success/mops.toml +2 -0
- package/tests/check-candid.test.ts +22 -0
- package/tests/check-fix.test.ts +134 -0
- package/tests/check.test.ts +51 -0
- package/tests/cli.test.ts +4 -74
- package/tests/helpers.ts +58 -0
- package/tests/lint/lints/no-bool-switch.toml +9 -0
- package/tests/lint/mops.toml +4 -0
- package/tests/lint/src/NoBoolSwitch.mo +8 -0
- package/tests/lint/src/Ok.mo +5 -0
- package/tests/lint.test.ts +17 -0
- package/tests/moc-args.test.ts +19 -0
- package/tests/toolchain/mock +2 -0
- package/tests/toolchain/mops.toml +2 -0
- package/tests/toolchain.test.ts +12 -0
- package/types.ts +8 -1
- package/wasm/Cargo.lock +101 -54
- package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/.DS_Store +0 -0
- package/bundle/bench/bench-canister.mo +0 -121
- package/bundle/bench/user-bench.mo +0 -10
- package/bundle/bin/moc-wrapper.sh +0 -40
- package/bundle/bin/mops.js +0 -3
- package/bundle/cli.js +0 -2144
- package/bundle/declarations/bench/bench.did +0 -30
- package/bundle/declarations/bench/bench.did.d.ts +0 -33
- package/bundle/declarations/bench/bench.did.js +0 -30
- package/bundle/declarations/bench/index.d.ts +0 -50
- package/bundle/declarations/bench/index.js +0 -40
- package/bundle/declarations/main/index.d.ts +0 -50
- package/bundle/declarations/main/index.js +0 -40
- package/bundle/declarations/main/main.did +0 -428
- package/bundle/declarations/main/main.did.d.ts +0 -348
- package/bundle/declarations/main/main.did.js +0 -406
- package/bundle/declarations/storage/index.d.ts +0 -50
- package/bundle/declarations/storage/index.js +0 -30
- package/bundle/declarations/storage/storage.did +0 -46
- package/bundle/declarations/storage/storage.did.d.ts +0 -40
- package/bundle/declarations/storage/storage.did.js +0 -38
- package/bundle/package.json +0 -36
- package/bundle/templates/README.md +0 -13
- package/bundle/templates/licenses/Apache-2.0 +0 -202
- package/bundle/templates/licenses/Apache-2.0-NOTICE +0 -13
- package/bundle/templates/licenses/MIT +0 -21
- package/bundle/templates/mops-publish.yml +0 -17
- package/bundle/templates/mops-test.yml +0 -24
- package/bundle/templates/src/lib.mo +0 -15
- package/bundle/templates/test/lib.test.mo +0 -4
- package/bundle/wasm_bg.wasm +0 -0
- package/bundle/xhr-sync-worker.js +0 -59
- package/dist/wasm/pkg/bundler/package.json +0 -20
- package/dist/wasm/pkg/bundler/wasm.d.ts +0 -3
- package/dist/wasm/pkg/bundler/wasm.js +0 -5
- package/dist/wasm/pkg/bundler/wasm_bg.js +0 -93
- package/dist/wasm/pkg/bundler/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/bundler/wasm_bg.wasm.d.ts +0 -8
- package/tests/__snapshots__/cli.test.ts.snap +0 -202
- package/tests/build/success/.dfx/local/canister_ids.json +0 -17
- package/tests/build/success/.dfx/local/canisters/bar/bar.did +0 -3
- package/tests/build/success/.dfx/local/canisters/bar/bar.most +0 -4
- package/tests/build/success/.dfx/local/canisters/bar/bar.wasm +0 -0
- package/tests/build/success/.dfx/local/canisters/bar/constructor.did +0 -3
- package/tests/build/success/.dfx/local/canisters/bar/index.js +0 -42
- package/tests/build/success/.dfx/local/canisters/bar/init_args.txt +0 -1
- package/tests/build/success/.dfx/local/canisters/bar/service.did +0 -3
- package/tests/build/success/.dfx/local/canisters/bar/service.did.d.ts +0 -7
- package/tests/build/success/.dfx/local/canisters/bar/service.did.js +0 -4
- package/tests/build/success/.dfx/local/canisters/foo/constructor.did +0 -3
- package/tests/build/success/.dfx/local/canisters/foo/foo.did +0 -3
- package/tests/build/success/.dfx/local/canisters/foo/foo.most +0 -4
- package/tests/build/success/.dfx/local/canisters/foo/foo.wasm +0 -0
- package/tests/build/success/.dfx/local/canisters/foo/index.js +0 -42
- package/tests/build/success/.dfx/local/canisters/foo/init_args.txt +0 -1
- package/tests/build/success/.dfx/local/canisters/foo/service.did +0 -3
- package/tests/build/success/.dfx/local/canisters/foo/service.did.d.ts +0 -7
- package/tests/build/success/.dfx/local/canisters/foo/service.did.js +0 -4
- package/tests/build/success/.dfx/local/lsp/ucwa4-rx777-77774-qaada-cai.did +0 -3
- package/tests/build/success/.dfx/local/lsp/ulvla-h7777-77774-qaacq-cai.did +0 -3
- package/tests/build/success/.dfx/local/network-id +0 -4
- package/wasm/pkg/bundler/package.json +0 -20
- package/wasm/pkg/bundler/wasm.d.ts +0 -3
- package/wasm/pkg/bundler/wasm.js +0 -5
- package/wasm/pkg/bundler/wasm_bg.js +0 -93
- package/wasm/pkg/bundler/wasm_bg.wasm +0 -0
- package/wasm/pkg/bundler/wasm_bg.wasm.d.ts +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
3
|
## Next
|
|
4
|
+
|
|
5
|
+
## 2.2.0
|
|
6
|
+
- Add `[moc]` config section for global `moc` compiler flags (applied to `check`, `build`, `test`, `bench`, `watch`)
|
|
7
|
+
- Add `mops moc-args` command to print global `moc` flags from `[moc]` config section
|
|
8
|
+
- Fix `mops check --fix` crash on overlapping diagnostic edits (e.g., nested function calls)
|
|
9
|
+
|
|
10
|
+
## 2.1.0
|
|
11
|
+
- Add `mops check --fix` subcommand (for Motoko files) with autofix logic
|
|
12
|
+
- Add `mops check` subcommand for type-checking Motoko files
|
|
13
|
+
- Warn for `dfx` projects instead of requiring `mops toolchain init`
|
|
14
|
+
- Allow specifying toolchain file paths in `mops.toml`
|
|
15
|
+
- Add `mops lint` subcommand and `lintoko` toolchain management
|
|
16
|
+
- Improve bench-canister Bench type to be less restrictive (by @timohanke)
|
|
17
|
+
|
|
18
|
+
## 2.0.1
|
|
19
|
+
- Patch vulnerability in `tar` dependency
|
|
20
|
+
|
|
21
|
+
# 2.0.0
|
|
4
22
|
- `mops publish` add support for subheadings in changelog (by @f0i)
|
|
5
23
|
- `mops toolchain` now downloads `moc.js` in addition to `moc` binary
|
|
6
24
|
- New `mops build` subcommand (alternative to `dfx build`)
|
package/RELEASE.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Mops CLI Release
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
### macOS: GNU tar
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
brew install gnu-tar
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Add to `~/.zshrc` or `~/.bashrc`:
|
|
12
|
+
```bash
|
|
13
|
+
export PATH="$HOMEBREW_PREFIX/opt/gnu-tar/libexec/gnubin:$PATH"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Docker
|
|
17
|
+
|
|
18
|
+
Docker (or OrbStack) must be installed and running. The CLI build happens inside a Docker container (`zenvoich/mops-builder:1.1.0`) for reproducibility.
|
|
19
|
+
|
|
20
|
+
### dfx
|
|
21
|
+
|
|
22
|
+
`dfx` must be installed with the `mops` identity configured (see [Adding the `mops` identity to dfx](#adding-the-mops-identity-to-dfx)).
|
|
23
|
+
|
|
24
|
+
## Release Steps
|
|
25
|
+
|
|
26
|
+
### 1. Install dependencies
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd cli && bun install
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Update changelog
|
|
33
|
+
|
|
34
|
+
Move items from the `## Next` section in `CHANGELOG.md` into a new version heading:
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
## Next
|
|
38
|
+
|
|
39
|
+
## X.Y.Z
|
|
40
|
+
- Change 1
|
|
41
|
+
- Change 2
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The heading must contain the exact version string — `release-cli.ts` parses it to extract release notes.
|
|
45
|
+
|
|
46
|
+
### 3. Create a release branch and PR
|
|
47
|
+
|
|
48
|
+
Direct pushes to `main` are not allowed. Create a branch and PR:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git checkout -b <username>/release-X.Y.Z
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 4. Bump version
|
|
55
|
+
|
|
56
|
+
Use `--no-git-tag-version` since the version bump will be committed as part of the PR (not directly on `main`):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd cli
|
|
60
|
+
npm version minor --no-git-tag-version # or: patch / major
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 5. Commit, push, and open PR
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git add cli/CHANGELOG.md cli/package.json cli/package-lock.json
|
|
67
|
+
git commit -m "release: CLI vX.Y.Z"
|
|
68
|
+
git push -u origin <username>/release-X.Y.Z
|
|
69
|
+
gh pr create --title "release: CLI vX.Y.Z" --body "..."
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Wait for CI to pass, then merge the PR.
|
|
73
|
+
|
|
74
|
+
### 6. Check reproducibility of the build
|
|
75
|
+
|
|
76
|
+
After the PR is merged to `main`, check the SHA256 hash from the latest [build-hash workflow](https://github.com/caffeinelabs/mops/actions/workflows/build-hash.yml) run.
|
|
77
|
+
|
|
78
|
+
**Important**: The CI hash is written to the GitHub Actions **Step Summary** — it is only visible on the **Summary tab** of the workflow run page. It does **not** appear in the downloadable logs (`gh run view --log` will not find it). You must open the run URL in a browser to see it.
|
|
79
|
+
|
|
80
|
+
Build the same version locally:
|
|
81
|
+
```bash
|
|
82
|
+
cd cli
|
|
83
|
+
MOPS_VERSION=0.0.0 ./build.sh
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`build.sh` does the following:
|
|
87
|
+
1. Reads `COMMIT_HASH` (defaults to `git rev-parse HEAD`) and `MOPS_VERSION`
|
|
88
|
+
2. Runs `docker build` using `cli/Dockerfile` with those as build args
|
|
89
|
+
3. The Dockerfile clones the repo at that commit, runs `bun install`, sets the version, and runs `npm run build`
|
|
90
|
+
4. Prints the SHA256 hash of `cli.tgz`
|
|
91
|
+
5. Copies `cli.tgz` out of the container into `cli/bundle/cli.tgz`
|
|
92
|
+
|
|
93
|
+
Compare the locally printed hash with the one from the CI Step Summary. If they don't match, do not proceed.
|
|
94
|
+
|
|
95
|
+
**Notes on the local build output:**
|
|
96
|
+
- The "Verification failed" message at the end is **expected** — it happens because no `SHASUM` env var is passed for comparison. The important output is the `Actual shasum: <hash>` line.
|
|
97
|
+
|
|
98
|
+
### 7. Publish to npm
|
|
99
|
+
|
|
100
|
+
After the PR is merged and the build hash is verified:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git checkout main && git pull
|
|
104
|
+
cd cli
|
|
105
|
+
npm publish
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 8. Prepare on-chain release
|
|
109
|
+
|
|
110
|
+
Run from the **repo root** (not `cli/`), with Docker running:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm run release-cli
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This runs `cli/release-cli.ts`, which:
|
|
117
|
+
1. Calls `./build.sh` — full Docker build with the real version from `cli/package.json`
|
|
118
|
+
2. Extracts release notes from `CHANGELOG.md` for that version
|
|
119
|
+
3. Computes SHA256 of `bundle/cli.tgz`
|
|
120
|
+
4. Copies the tarball to `cli-releases/versions/<version>.tgz`
|
|
121
|
+
5. Creates tag copies: `latest.tgz` and `<major>.tgz`
|
|
122
|
+
6. Updates `cli-releases/tags/latest` to the new version
|
|
123
|
+
7. Updates `cli-releases/releases.json` with metadata (timestamp, size, hash, commit hash, download URL, release notes)
|
|
124
|
+
|
|
125
|
+
### 9. Deploy the canister
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
dfx deploy --network ic --no-wallet cli --identity mops
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This deploys the `cli-releases` canister (serving `cli.mops.one`) to the Internet Computer mainnet.
|
|
132
|
+
|
|
133
|
+
### 10. Commit and push release artifacts
|
|
134
|
+
|
|
135
|
+
Step 8 generates files in `cli-releases/` that must be committed and pushed:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
git add cli-releases/
|
|
139
|
+
git commit -m "cli-releases: v<version> artifacts"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Since direct pushes to `main` are not allowed, create a branch and PR:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
git checkout -b <username>/release-X.Y.Z-artifacts
|
|
146
|
+
git push -u origin <username>/release-X.Y.Z-artifacts
|
|
147
|
+
gh pr create --title "cli-releases: vX.Y.Z artifacts" --body "Release artifacts generated by \`npm run release-cli\` for CLI vX.Y.Z."
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Merge this PR after approval.
|
|
151
|
+
|
|
152
|
+
## Verify build
|
|
153
|
+
|
|
154
|
+
Anyone can verify a released version by rebuilding from source:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
cd cli
|
|
158
|
+
docker build . --build-arg COMMIT_HASH=<commit_hash> --build-arg MOPS_VERSION=<mops_version> -t mops
|
|
159
|
+
docker run --rm --env SHASUM=<build_hash> mops
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Adding the `mops` identity to dfx
|
|
163
|
+
|
|
164
|
+
Check if the identity already exists:
|
|
165
|
+
```bash
|
|
166
|
+
dfx identity list
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If `mops` appears, verify it's the correct one:
|
|
170
|
+
```bash
|
|
171
|
+
dfx identity get-principal --identity mops
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If it doesn't exist, import it from the PEM file stored in Bitwarden (`Mops identity (canisters and packages)`):
|
|
175
|
+
|
|
176
|
+
1. Save the PEM key to a temporary file:
|
|
177
|
+
```bash
|
|
178
|
+
cat > /tmp/mops-identity.pem << 'EOF'
|
|
179
|
+
-----BEGIN EC PRIVATE KEY-----
|
|
180
|
+
<paste key from Bitwarden>
|
|
181
|
+
-----END EC PRIVATE KEY-----
|
|
182
|
+
EOF
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
2. Import into dfx:
|
|
186
|
+
```bash
|
|
187
|
+
dfx identity import mops /tmp/mops-identity.pem
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
3. Delete the temporary file:
|
|
191
|
+
```bash
|
|
192
|
+
rm /tmp/mops-identity.pem
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
4. Verify:
|
|
196
|
+
```bash
|
|
197
|
+
dfx identity get-principal --identity mops
|
|
198
|
+
```
|
package/bundle/cli.tgz
CHANGED
|
Binary file
|
package/check-requirements.ts
CHANGED
|
@@ -4,19 +4,14 @@ import chalk from "chalk";
|
|
|
4
4
|
|
|
5
5
|
import { getDependencyType, getRootDir, readConfig } from "./mops.js";
|
|
6
6
|
import { resolvePackages } from "./resolve-packages.js";
|
|
7
|
-
import {
|
|
7
|
+
import { getMocSemVer } from "./helpers/get-moc-version.js";
|
|
8
8
|
import { getPackageId } from "./helpers/get-package-id.js";
|
|
9
9
|
|
|
10
10
|
export async function checkRequirements({ verbose = false } = {}) {
|
|
11
|
-
let
|
|
12
|
-
|
|
13
|
-
if (!mocVersion) {
|
|
14
|
-
mocVersion = getMocVersion(false);
|
|
15
|
-
}
|
|
16
|
-
if (!mocVersion) {
|
|
11
|
+
let installedMoc = getMocSemVer();
|
|
12
|
+
if (!installedMoc) {
|
|
17
13
|
return;
|
|
18
14
|
}
|
|
19
|
-
let installedMoc = new SemVer(mocVersion);
|
|
20
15
|
let highestRequiredMoc = new SemVer("0.0.0");
|
|
21
16
|
let highestRequiredMocPkgId = "";
|
|
22
17
|
let rootDir = getRootDir();
|
package/cli.ts
CHANGED
|
@@ -10,11 +10,13 @@ import { add } from "./commands/add.js";
|
|
|
10
10
|
import { bench } from "./commands/bench.js";
|
|
11
11
|
import { build, DEFAULT_BUILD_OUTPUT_DIR } from "./commands/build.js";
|
|
12
12
|
import { bump } from "./commands/bump.js";
|
|
13
|
+
import { check } from "./commands/check.js";
|
|
13
14
|
import { checkCandid } from "./commands/check-candid.js";
|
|
14
15
|
import { docsCoverage } from "./commands/docs-coverage.js";
|
|
15
16
|
import { docs } from "./commands/docs.js";
|
|
16
17
|
import { format } from "./commands/format.js";
|
|
17
18
|
import { init } from "./commands/init.js";
|
|
19
|
+
import { lint } from "./commands/lint.js";
|
|
18
20
|
import { installAll } from "./commands/install/install-all.js";
|
|
19
21
|
import {
|
|
20
22
|
addMaintainer,
|
|
@@ -44,12 +46,15 @@ import {
|
|
|
44
46
|
apiVersion,
|
|
45
47
|
checkApiCompatibility,
|
|
46
48
|
checkConfigFile,
|
|
49
|
+
getGlobalMocArgs,
|
|
47
50
|
getNetworkFile,
|
|
51
|
+
readConfig,
|
|
48
52
|
setNetwork,
|
|
49
53
|
version,
|
|
50
54
|
} from "./mops.js";
|
|
51
55
|
import { resolvePackages } from "./resolve-packages.js";
|
|
52
56
|
import { Tool } from "./types.js";
|
|
57
|
+
import { TOOLCHAINS } from "./commands/toolchain/toolchain-utils.js";
|
|
53
58
|
|
|
54
59
|
declare global {
|
|
55
60
|
// eslint-disable-next-line no-var
|
|
@@ -73,6 +78,22 @@ if (fs.existsSync(networkFile)) {
|
|
|
73
78
|
|
|
74
79
|
let program = new Command();
|
|
75
80
|
|
|
81
|
+
function parseExtraArgs(variadicArgs?: string[]): {
|
|
82
|
+
extraArgs: string[];
|
|
83
|
+
args: string[];
|
|
84
|
+
} {
|
|
85
|
+
const rawArgs = process.argv.slice(2);
|
|
86
|
+
const dashDashIndex = rawArgs.indexOf("--");
|
|
87
|
+
const extraArgs =
|
|
88
|
+
dashDashIndex !== -1 ? rawArgs.slice(dashDashIndex + 1) : [];
|
|
89
|
+
const args = variadicArgs
|
|
90
|
+
? extraArgs.length > 0
|
|
91
|
+
? variadicArgs.slice(0, variadicArgs.length - extraArgs.length)
|
|
92
|
+
: variadicArgs
|
|
93
|
+
: [];
|
|
94
|
+
return { extraArgs, args };
|
|
95
|
+
}
|
|
96
|
+
|
|
76
97
|
program.name("mops");
|
|
77
98
|
|
|
78
99
|
// --version
|
|
@@ -152,7 +173,7 @@ program
|
|
|
152
173
|
}
|
|
153
174
|
|
|
154
175
|
if (options.toolchain) {
|
|
155
|
-
await toolchain.
|
|
176
|
+
await toolchain.checkToolchainInited({ strict: false });
|
|
156
177
|
}
|
|
157
178
|
|
|
158
179
|
let ok = await installAll(options);
|
|
@@ -231,11 +252,24 @@ program
|
|
|
231
252
|
installFromLockFile: true,
|
|
232
253
|
});
|
|
233
254
|
}
|
|
234
|
-
await toolchain.
|
|
255
|
+
await toolchain.checkToolchainInited({ strict: false });
|
|
235
256
|
let sourcesArr = await sources(options);
|
|
236
257
|
console.log(sourcesArr.join("\n"));
|
|
237
258
|
});
|
|
238
259
|
|
|
260
|
+
// moc-args
|
|
261
|
+
program
|
|
262
|
+
.command("moc-args")
|
|
263
|
+
.description("Print global moc compiler flags from [moc] config section")
|
|
264
|
+
.action(async () => {
|
|
265
|
+
checkConfigFile(true);
|
|
266
|
+
let config = readConfig();
|
|
267
|
+
let args = getGlobalMocArgs(config);
|
|
268
|
+
if (args.length) {
|
|
269
|
+
console.log(args.join("\n"));
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
239
273
|
// search
|
|
240
274
|
program
|
|
241
275
|
.command("search <text>")
|
|
@@ -272,18 +306,45 @@ program
|
|
|
272
306
|
),
|
|
273
307
|
)
|
|
274
308
|
.allowUnknownOption(true) // TODO: restrict unknown before "--"
|
|
275
|
-
.action(async (canisters, options
|
|
309
|
+
.action(async (canisters, options) => {
|
|
310
|
+
checkConfigFile(true);
|
|
311
|
+
const { extraArgs, args } = parseExtraArgs(canisters);
|
|
312
|
+
await installAll({
|
|
313
|
+
silent: true,
|
|
314
|
+
lock: "ignore",
|
|
315
|
+
installFromLockFile: true,
|
|
316
|
+
});
|
|
317
|
+
await build(args.length ? args : undefined, {
|
|
318
|
+
...options,
|
|
319
|
+
extraArgs,
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// check
|
|
324
|
+
program
|
|
325
|
+
.command("check <files...>")
|
|
326
|
+
.description(
|
|
327
|
+
"Check Motoko entrypoint files for syntax errors and type issues (including transitively imported files)",
|
|
328
|
+
)
|
|
329
|
+
.option("--verbose", "Verbose console output")
|
|
330
|
+
.addOption(
|
|
331
|
+
new Option(
|
|
332
|
+
"--fix",
|
|
333
|
+
"Apply autofixes to all files, including transitively imported ones",
|
|
334
|
+
),
|
|
335
|
+
)
|
|
336
|
+
.allowUnknownOption(true)
|
|
337
|
+
.action(async (files, options) => {
|
|
276
338
|
checkConfigFile(true);
|
|
277
|
-
const
|
|
339
|
+
const { extraArgs, args: fileList } = parseExtraArgs(files);
|
|
278
340
|
await installAll({
|
|
279
341
|
silent: true,
|
|
280
342
|
lock: "ignore",
|
|
281
343
|
installFromLockFile: true,
|
|
282
344
|
});
|
|
283
|
-
await
|
|
345
|
+
await check(fileList, {
|
|
284
346
|
...options,
|
|
285
|
-
extraArgs
|
|
286
|
-
extraArgsIndex !== -1 ? command.args.slice(extraArgsIndex + 1) : [],
|
|
347
|
+
extraArgs,
|
|
287
348
|
});
|
|
288
349
|
});
|
|
289
350
|
|
|
@@ -575,7 +636,7 @@ toolchainCommand
|
|
|
575
636
|
toolchainCommand
|
|
576
637
|
.command("use")
|
|
577
638
|
.description("Install specified tool version and update mops.toml")
|
|
578
|
-
.addArgument(new Argument("<tool>").choices(
|
|
639
|
+
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
579
640
|
.addArgument(new Argument("[version]"))
|
|
580
641
|
.action(async (tool, version) => {
|
|
581
642
|
if (!checkConfigFile()) {
|
|
@@ -589,7 +650,7 @@ toolchainCommand
|
|
|
589
650
|
.description(
|
|
590
651
|
"Update specified tool or all tools to the latest version and update mops.toml",
|
|
591
652
|
)
|
|
592
|
-
.addArgument(new Argument("[tool]").choices(
|
|
653
|
+
.addArgument(new Argument("[tool]").choices(TOOLCHAINS))
|
|
593
654
|
.action(async (tool?: Tool) => {
|
|
594
655
|
if (!checkConfigFile()) {
|
|
595
656
|
process.exit(1);
|
|
@@ -600,9 +661,9 @@ toolchainCommand
|
|
|
600
661
|
toolchainCommand
|
|
601
662
|
.command("bin")
|
|
602
663
|
.description(
|
|
603
|
-
|
|
664
|
+
`Get path to the tool binary\n<tool> can be one of ${TOOLCHAINS.map((s) => `"${s}"`).join(", ")}`,
|
|
604
665
|
)
|
|
605
|
-
.addArgument(new Argument("<tool>").choices(
|
|
666
|
+
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
606
667
|
.addOption(
|
|
607
668
|
new Option(
|
|
608
669
|
"--fallback",
|
|
@@ -671,6 +732,28 @@ program
|
|
|
671
732
|
}
|
|
672
733
|
});
|
|
673
734
|
|
|
735
|
+
// lint
|
|
736
|
+
program
|
|
737
|
+
.command("lint [filter]")
|
|
738
|
+
.description("Lint Motoko code")
|
|
739
|
+
.addOption(new Option("--verbose", "Verbose output"))
|
|
740
|
+
.addOption(new Option("--fix", "Apply fixes"))
|
|
741
|
+
.addOption(
|
|
742
|
+
new Option(
|
|
743
|
+
"-r, --rules <directory...>",
|
|
744
|
+
"Directories containing rules (can be used multiple times)",
|
|
745
|
+
),
|
|
746
|
+
)
|
|
747
|
+
.allowUnknownOption(true)
|
|
748
|
+
.action(async (filter, options) => {
|
|
749
|
+
checkConfigFile(true);
|
|
750
|
+
const { extraArgs } = parseExtraArgs();
|
|
751
|
+
await lint(filter, {
|
|
752
|
+
...options,
|
|
753
|
+
extraArgs,
|
|
754
|
+
});
|
|
755
|
+
});
|
|
756
|
+
|
|
674
757
|
// docs
|
|
675
758
|
const docsCommand = new Command("docs").description("Documentation management");
|
|
676
759
|
|
|
@@ -2,14 +2,25 @@ import Nat64 "mo:core/Nat64";
|
|
|
2
2
|
import Nat "mo:core/Nat";
|
|
3
3
|
import Runtime "mo:core/Runtime";
|
|
4
4
|
import InternetComputer "mo:core/InternetComputer";
|
|
5
|
-
import Int64 "mo:core/Int64";
|
|
6
5
|
import Region "mo:core/Region";
|
|
7
6
|
import Prim "mo:prim";
|
|
8
|
-
import Bench "mo:bench";
|
|
9
7
|
|
|
10
8
|
import UserBench "./user-bench"; // file path will be replaced with the *.bench.mo file path
|
|
11
9
|
|
|
12
10
|
persistent actor class () {
|
|
11
|
+
type BenchSchema = {
|
|
12
|
+
name : Text;
|
|
13
|
+
description : Text;
|
|
14
|
+
rows : [Text];
|
|
15
|
+
cols : [Text];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type Bench = {
|
|
19
|
+
getVersion : () -> Nat;
|
|
20
|
+
getSchema : () -> BenchSchema;
|
|
21
|
+
runCell : (Nat, Nat) -> ();
|
|
22
|
+
};
|
|
23
|
+
|
|
13
24
|
type BenchResult = {
|
|
14
25
|
instructions : Int;
|
|
15
26
|
rts_mutator_instructions : Int;
|
|
@@ -23,16 +34,16 @@ persistent actor class () {
|
|
|
23
34
|
rts_reclaimed : Int;
|
|
24
35
|
};
|
|
25
36
|
|
|
26
|
-
transient var benchOpt : ?Bench
|
|
37
|
+
transient var benchOpt : ?Bench = null;
|
|
27
38
|
|
|
28
|
-
public func init() : async
|
|
39
|
+
public func init() : async BenchSchema {
|
|
29
40
|
let bench = UserBench.init();
|
|
30
41
|
benchOpt := ?bench;
|
|
31
42
|
ignore Region.grow(Region.new(), 1);
|
|
32
43
|
bench.getSchema();
|
|
33
44
|
};
|
|
34
45
|
|
|
35
|
-
public query func getSchema() : async
|
|
46
|
+
public query func getSchema() : async BenchSchema {
|
|
36
47
|
let ?bench = benchOpt else Runtime.trap("bench not initialized");
|
|
37
48
|
bench.getSchema();
|
|
38
49
|
};
|
|
@@ -41,7 +52,7 @@ persistent actor class () {
|
|
|
41
52
|
{
|
|
42
53
|
instructions = 0;
|
|
43
54
|
rts_heap_size = Prim.rts_heap_size();
|
|
44
|
-
stable_memory_size =
|
|
55
|
+
stable_memory_size = Prim.rts_stable_memory_size() * 65536;
|
|
45
56
|
rts_stable_memory_size = Prim.rts_stable_memory_size();
|
|
46
57
|
rts_logical_stable_memory_size = Prim.rts_logical_stable_memory_size();
|
|
47
58
|
rts_memory_size = Prim.rts_memory_size();
|
package/commands/bench.ts
CHANGED
|
@@ -12,13 +12,19 @@ import { filesize } from "filesize";
|
|
|
12
12
|
import terminalSize from "terminal-size";
|
|
13
13
|
import { SemVer } from "semver";
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
getGlobalMocArgs,
|
|
17
|
+
getRootDir,
|
|
18
|
+
readConfig,
|
|
19
|
+
readDfxJson,
|
|
20
|
+
} from "../mops.js";
|
|
16
21
|
import { parallel } from "../parallel.js";
|
|
17
22
|
import { absToRel } from "./test/utils.js";
|
|
18
23
|
import { getMocVersion } from "../helpers/get-moc-version.js";
|
|
19
24
|
import { getDfxVersion } from "../helpers/get-dfx-version.js";
|
|
20
25
|
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
21
26
|
import { sources } from "./sources.js";
|
|
27
|
+
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
22
28
|
|
|
23
29
|
import { Benchmark, Benchmarks } from "../declarations/main/main.did.js";
|
|
24
30
|
import { BenchResult, _SERVICE } from "../declarations/bench/bench.did.js";
|
|
@@ -26,18 +32,6 @@ import { BenchReplica } from "./bench-replica.js";
|
|
|
26
32
|
|
|
27
33
|
type ReplicaName = "dfx" | "pocket-ic" | "dfx-pocket-ic";
|
|
28
34
|
|
|
29
|
-
let ignore = [
|
|
30
|
-
"**/node_modules/**",
|
|
31
|
-
"**/.mops/**",
|
|
32
|
-
"**/.vessel/**",
|
|
33
|
-
"**/.git/**",
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
let globConfig = {
|
|
37
|
-
nocase: true,
|
|
38
|
-
ignore: ignore,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
35
|
type BenchOptions = {
|
|
42
36
|
replica: ReplicaName;
|
|
43
37
|
replicaVersion: string;
|
|
@@ -113,7 +107,7 @@ export async function bench(
|
|
|
113
107
|
if (filter) {
|
|
114
108
|
globStr = `**/bench?(mark)/**/*${filter}*.mo`;
|
|
115
109
|
}
|
|
116
|
-
let files = globSync(path.join(rootDir, globStr),
|
|
110
|
+
let files = globSync(path.join(rootDir, globStr), MOTOKO_GLOB_CONFIG);
|
|
117
111
|
if (!files.length) {
|
|
118
112
|
if (filter) {
|
|
119
113
|
options.silent ||
|
|
@@ -149,13 +143,15 @@ export async function bench(
|
|
|
149
143
|
|
|
150
144
|
await replica.start({ silent: options.silent });
|
|
151
145
|
|
|
146
|
+
let globalMocArgs = getGlobalMocArgs(config);
|
|
147
|
+
|
|
152
148
|
if (!process.env.CI && !options.silent) {
|
|
153
149
|
console.log("Deploying canisters...");
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
await parallel(os.cpus().length, files, async (file: string) => {
|
|
157
153
|
try {
|
|
158
|
-
await deployBenchFile(file, options, replica);
|
|
154
|
+
await deployBenchFile(file, options, replica, globalMocArgs);
|
|
159
155
|
} catch (err) {
|
|
160
156
|
console.error("Unexpected error. Stopping replica...");
|
|
161
157
|
await replica.stop();
|
|
@@ -278,6 +274,7 @@ async function deployBenchFile(
|
|
|
278
274
|
file: string,
|
|
279
275
|
options: BenchOptions,
|
|
280
276
|
replica: BenchReplica,
|
|
277
|
+
globalMocArgs: string[],
|
|
281
278
|
): Promise<void> {
|
|
282
279
|
let rootDir = getRootDir();
|
|
283
280
|
let tempDir = path.join(rootDir, ".mops/.bench/", path.parse(file).name);
|
|
@@ -305,7 +302,7 @@ async function deployBenchFile(
|
|
|
305
302
|
let mocArgs = getMocArgs(options);
|
|
306
303
|
options.verbose && console.time(`build ${canisterName}`);
|
|
307
304
|
await execaCommand(
|
|
308
|
-
`${mocPath} -c --idl canister.mo ${mocArgs} ${(await sources({ cwd: tempDir })).join(" ")}`,
|
|
305
|
+
`${mocPath} -c --idl canister.mo ${globalMocArgs.join(" ")} ${mocArgs} ${(await sources({ cwd: tempDir })).join(" ")}`,
|
|
309
306
|
{
|
|
310
307
|
cwd: tempDir,
|
|
311
308
|
stdio: options.verbose ? "pipe" : ["pipe", "ignore", "pipe"],
|
package/commands/build.ts
CHANGED
|
@@ -4,12 +4,12 @@ import { exists } from "fs-extra";
|
|
|
4
4
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { cliError } from "../error.js";
|
|
7
|
-
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
8
7
|
import { isCandidCompatible } from "../helpers/is-candid-compatible.js";
|
|
9
8
|
import { CustomSection, getWasmBindings } from "../wasm.js";
|
|
10
|
-
import { readConfig } from "../mops.js";
|
|
9
|
+
import { getGlobalMocArgs, readConfig } from "../mops.js";
|
|
11
10
|
import { CanisterConfig } from "../types.js";
|
|
12
11
|
import { sourcesArgs } from "./sources.js";
|
|
12
|
+
import { toolchain } from "./toolchain/index.js";
|
|
13
13
|
|
|
14
14
|
export interface BuildOptions {
|
|
15
15
|
outputDir: string;
|
|
@@ -28,7 +28,7 @@ export async function build(
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
let outputDir = options.outputDir ?? DEFAULT_BUILD_OUTPUT_DIR;
|
|
31
|
-
let mocPath =
|
|
31
|
+
let mocPath = await toolchain.bin("moc", { fallback: true });
|
|
32
32
|
let canisters: Record<string, CanisterConfig> = {};
|
|
33
33
|
let config = readConfig();
|
|
34
34
|
if (config.canisters) {
|
|
@@ -70,7 +70,6 @@ export async function build(
|
|
|
70
70
|
: canisters;
|
|
71
71
|
|
|
72
72
|
for (let [canisterName, canister] of Object.entries(filteredCanisters)) {
|
|
73
|
-
options.verbose && console.time(`build canister ${canisterName}`);
|
|
74
73
|
console.log(chalk.blue("build canister"), chalk.bold(canisterName));
|
|
75
74
|
let motokoPath = canister.main;
|
|
76
75
|
if (!motokoPath) {
|
|
@@ -83,8 +82,8 @@ export async function build(
|
|
|
83
82
|
"-o",
|
|
84
83
|
wasmPath,
|
|
85
84
|
motokoPath,
|
|
86
|
-
...(options.extraArgs ?? []),
|
|
87
85
|
...(await sourcesArgs()).flat(),
|
|
86
|
+
...getGlobalMocArgs(config),
|
|
88
87
|
];
|
|
89
88
|
if (config.build?.args) {
|
|
90
89
|
if (typeof config.build.args === "string") {
|
|
@@ -102,6 +101,7 @@ export async function build(
|
|
|
102
101
|
}
|
|
103
102
|
args.push(...canister.args);
|
|
104
103
|
}
|
|
104
|
+
args.push(...(options.extraArgs ?? []));
|
|
105
105
|
const isPublicCandid = true; // always true for now to reduce corner cases
|
|
106
106
|
const candidVisibility = isPublicCandid ? "icp:public" : "icp:private";
|
|
107
107
|
if (isPublicCandid) {
|
|
@@ -193,7 +193,6 @@ export async function build(
|
|
|
193
193
|
`Error while compiling canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`,
|
|
194
194
|
);
|
|
195
195
|
}
|
|
196
|
-
options.verbose && console.timeEnd(`build canister ${canisterName}`);
|
|
197
196
|
}
|
|
198
197
|
|
|
199
198
|
console.log(
|