ic-mops 2.0.0 → 2.1.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 +13 -0
- package/RELEASE.md +179 -0
- package/bundle/cli.tgz +0 -0
- package/check-requirements.ts +3 -8
- package/cli.ts +79 -11
- package/commands/bench/bench-canister.mo +17 -6
- package/commands/bench.ts +2 -13
- package/commands/build.ts +42 -17
- package/commands/check.ts +117 -0
- package/commands/format.ts +3 -18
- package/commands/lint.ts +92 -0
- package/commands/sync.ts +2 -8
- package/commands/test/test.ts +7 -19
- package/commands/toolchain/index.ts +21 -8
- package/commands/toolchain/lintoko.ts +54 -0
- package/commands/toolchain/toolchain-utils.ts +2 -0
- package/constants.ts +23 -0
- package/dist/check-requirements.js +3 -8
- package/dist/cli.js +60 -10
- package/dist/commands/bench/bench-canister.mo +17 -6
- package/dist/commands/bench.js +2 -11
- package/dist/commands/build.js +38 -16
- package/dist/commands/check.d.ts +6 -0
- package/dist/commands/check.js +78 -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 +7 -17
- 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/constants.d.ts +15 -0
- package/dist/constants.js +21 -0
- package/dist/environments/nodejs/cli.js +6 -1
- package/dist/helpers/autofix-motoko.d.ts +26 -0
- package/dist/helpers/autofix-motoko.js +105 -0
- package/dist/helpers/get-moc-version.d.ts +2 -0
- package/dist/helpers/get-moc-version.js +10 -1
- package/dist/mops.js +2 -1
- package/dist/package.json +4 -3
- 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 +73 -0
- package/dist/tests/check.test.d.ts +1 -0
- package/dist/tests/check.test.js +33 -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/toolchain.test.d.ts +1 -0
- package/dist/tests/toolchain.test.js +11 -0
- package/dist/types.d.ts +6 -1
- package/dist/wasm/pkg/nodejs/wasm.d.ts +3 -0
- package/dist/wasm/pkg/nodejs/wasm.js +323 -17
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +6 -1
- package/dist/wasm/pkg/web/wasm.d.ts +10 -1
- package/dist/wasm/pkg/web/wasm.js +300 -21
- package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/web/wasm_bg.wasm.d.ts +6 -1
- package/dist/wasm.d.ts +6 -1
- package/environments/nodejs/cli.ts +7 -1
- package/helpers/autofix-motoko.ts +170 -0
- package/helpers/get-moc-version.ts +12 -1
- package/mops.ts +2 -1
- package/package.json +4 -3
- 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 +242 -0
- package/tests/__snapshots__/check.test.ts.snap +72 -0
- package/tests/__snapshots__/lint.test.ts.snap +78 -0
- package/tests/build/error/src/Bar.mo +2 -2
- package/tests/build/no-dfx/mops.toml +5 -0
- package/tests/build/no-dfx/src/Main.mo +5 -0
- package/tests/build/success/candid/bar.did +1 -0
- package/tests/build/success/mops.toml +8 -3
- 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/transitive-lib.mo +9 -0
- package/tests/check/fix/transitive-main.mo +9 -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 +111 -0
- package/tests/check.test.ts +46 -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/toolchain/mock +2 -0
- package/tests/toolchain/mops.toml +2 -0
- package/tests/toolchain.test.ts +12 -0
- package/types.ts +6 -1
- package/wasm/Cargo.lock +101 -54
- package/wasm/Cargo.toml +2 -5
- package/wasm/pkg/nodejs/wasm.d.ts +3 -0
- package/wasm/pkg/nodejs/wasm.js +323 -17
- package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +6 -1
- package/wasm/pkg/web/wasm.d.ts +10 -1
- package/wasm/pkg/web/wasm.js +300 -21
- package/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/wasm/pkg/web/wasm_bg.wasm.d.ts +6 -1
- package/wasm/src/lib.rs +10 -5
- package/wasm/src/utils.rs +15 -0
- package/wasm/src/wasm_utils.rs +79 -0
- package/wasm.ts +10 -1
- 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,19 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
3
|
## Next
|
|
4
|
+
|
|
5
|
+
## 2.1.0
|
|
6
|
+
- Add `mops check --fix` subcommand (for Motoko files) with autofix logic
|
|
7
|
+
- Add `mops check` subcommand for type-checking Motoko files
|
|
8
|
+
- Warn for `dfx` projects instead of requiring `mops toolchain init`
|
|
9
|
+
- Allow specifying toolchain file paths in `mops.toml`
|
|
10
|
+
- Add `mops lint` subcommand and `lintoko` toolchain management
|
|
11
|
+
- Improve bench-canister Bench type to be less restrictive (by @timohanke)
|
|
12
|
+
|
|
13
|
+
## 2.0.1
|
|
14
|
+
- Patch vulnerability in `tar` dependency
|
|
15
|
+
|
|
16
|
+
# 2.0.0
|
|
4
17
|
- `mops publish` add support for subheadings in changelog (by @f0i)
|
|
5
18
|
- `mops toolchain` now downloads `moc.js` in addition to `moc` binary
|
|
6
19
|
- New `mops build` subcommand (alternative to `dfx build`)
|
package/RELEASE.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
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
|
+
## Verify build
|
|
134
|
+
|
|
135
|
+
Anyone can verify a released version by rebuilding from source:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
cd cli
|
|
139
|
+
docker build . --build-arg COMMIT_HASH=<commit_hash> --build-arg MOPS_VERSION=<mops_version> -t mops
|
|
140
|
+
docker run --rm --env SHASUM=<build_hash> mops
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Adding the `mops` identity to dfx
|
|
144
|
+
|
|
145
|
+
Check if the identity already exists:
|
|
146
|
+
```bash
|
|
147
|
+
dfx identity list
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If `mops` appears, verify it's the correct one:
|
|
151
|
+
```bash
|
|
152
|
+
dfx identity get-principal --identity mops
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
If it doesn't exist, import it from the PEM file stored in Bitwarden (`Mops identity (canisters and packages)`):
|
|
156
|
+
|
|
157
|
+
1. Save the PEM key to a temporary file:
|
|
158
|
+
```bash
|
|
159
|
+
cat > /tmp/mops-identity.pem << 'EOF'
|
|
160
|
+
-----BEGIN EC PRIVATE KEY-----
|
|
161
|
+
<paste key from Bitwarden>
|
|
162
|
+
-----END EC PRIVATE KEY-----
|
|
163
|
+
EOF
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
2. Import into dfx:
|
|
167
|
+
```bash
|
|
168
|
+
dfx identity import mops /tmp/mops-identity.pem
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
3. Delete the temporary file:
|
|
172
|
+
```bash
|
|
173
|
+
rm /tmp/mops-identity.pem
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
4. Verify:
|
|
177
|
+
```bash
|
|
178
|
+
dfx identity get-principal --identity mops
|
|
179
|
+
```
|
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,
|
|
@@ -50,6 +52,7 @@ import {
|
|
|
50
52
|
} from "./mops.js";
|
|
51
53
|
import { resolvePackages } from "./resolve-packages.js";
|
|
52
54
|
import { Tool } from "./types.js";
|
|
55
|
+
import { TOOLCHAINS } from "./commands/toolchain/toolchain-utils.js";
|
|
53
56
|
|
|
54
57
|
declare global {
|
|
55
58
|
// eslint-disable-next-line no-var
|
|
@@ -73,6 +76,22 @@ if (fs.existsSync(networkFile)) {
|
|
|
73
76
|
|
|
74
77
|
let program = new Command();
|
|
75
78
|
|
|
79
|
+
function parseExtraArgs(variadicArgs?: string[]): {
|
|
80
|
+
extraArgs: string[];
|
|
81
|
+
args: string[];
|
|
82
|
+
} {
|
|
83
|
+
const rawArgs = process.argv.slice(2);
|
|
84
|
+
const dashDashIndex = rawArgs.indexOf("--");
|
|
85
|
+
const extraArgs =
|
|
86
|
+
dashDashIndex !== -1 ? rawArgs.slice(dashDashIndex + 1) : [];
|
|
87
|
+
const args = variadicArgs
|
|
88
|
+
? extraArgs.length > 0
|
|
89
|
+
? variadicArgs.slice(0, variadicArgs.length - extraArgs.length)
|
|
90
|
+
: variadicArgs
|
|
91
|
+
: [];
|
|
92
|
+
return { extraArgs, args };
|
|
93
|
+
}
|
|
94
|
+
|
|
76
95
|
program.name("mops");
|
|
77
96
|
|
|
78
97
|
// --version
|
|
@@ -152,7 +171,7 @@ program
|
|
|
152
171
|
}
|
|
153
172
|
|
|
154
173
|
if (options.toolchain) {
|
|
155
|
-
await toolchain.
|
|
174
|
+
await toolchain.checkToolchainInited({ strict: false });
|
|
156
175
|
}
|
|
157
176
|
|
|
158
177
|
let ok = await installAll(options);
|
|
@@ -231,7 +250,7 @@ program
|
|
|
231
250
|
installFromLockFile: true,
|
|
232
251
|
});
|
|
233
252
|
}
|
|
234
|
-
await toolchain.
|
|
253
|
+
await toolchain.checkToolchainInited({ strict: false });
|
|
235
254
|
let sourcesArr = await sources(options);
|
|
236
255
|
console.log(sourcesArr.join("\n"));
|
|
237
256
|
});
|
|
@@ -272,18 +291,45 @@ program
|
|
|
272
291
|
),
|
|
273
292
|
)
|
|
274
293
|
.allowUnknownOption(true) // TODO: restrict unknown before "--"
|
|
275
|
-
.action(async (canisters, options
|
|
294
|
+
.action(async (canisters, options) => {
|
|
295
|
+
checkConfigFile(true);
|
|
296
|
+
const { extraArgs, args } = parseExtraArgs(canisters);
|
|
297
|
+
await installAll({
|
|
298
|
+
silent: true,
|
|
299
|
+
lock: "ignore",
|
|
300
|
+
installFromLockFile: true,
|
|
301
|
+
});
|
|
302
|
+
await build(args.length ? args : undefined, {
|
|
303
|
+
...options,
|
|
304
|
+
extraArgs,
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// check
|
|
309
|
+
program
|
|
310
|
+
.command("check <files...>")
|
|
311
|
+
.description(
|
|
312
|
+
"Check Motoko entrypoint files for syntax errors and type issues (including transitively imported files)",
|
|
313
|
+
)
|
|
314
|
+
.option("--verbose", "Verbose console output")
|
|
315
|
+
.addOption(
|
|
316
|
+
new Option(
|
|
317
|
+
"--fix",
|
|
318
|
+
"Apply autofixes to all files, including transitively imported ones",
|
|
319
|
+
),
|
|
320
|
+
)
|
|
321
|
+
.allowUnknownOption(true)
|
|
322
|
+
.action(async (files, options) => {
|
|
276
323
|
checkConfigFile(true);
|
|
277
|
-
const
|
|
324
|
+
const { extraArgs, args: fileList } = parseExtraArgs(files);
|
|
278
325
|
await installAll({
|
|
279
326
|
silent: true,
|
|
280
327
|
lock: "ignore",
|
|
281
328
|
installFromLockFile: true,
|
|
282
329
|
});
|
|
283
|
-
await
|
|
330
|
+
await check(fileList, {
|
|
284
331
|
...options,
|
|
285
|
-
extraArgs
|
|
286
|
-
extraArgsIndex !== -1 ? command.args.slice(extraArgsIndex + 1) : [],
|
|
332
|
+
extraArgs,
|
|
287
333
|
});
|
|
288
334
|
});
|
|
289
335
|
|
|
@@ -575,7 +621,7 @@ toolchainCommand
|
|
|
575
621
|
toolchainCommand
|
|
576
622
|
.command("use")
|
|
577
623
|
.description("Install specified tool version and update mops.toml")
|
|
578
|
-
.addArgument(new Argument("<tool>").choices(
|
|
624
|
+
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
579
625
|
.addArgument(new Argument("[version]"))
|
|
580
626
|
.action(async (tool, version) => {
|
|
581
627
|
if (!checkConfigFile()) {
|
|
@@ -589,7 +635,7 @@ toolchainCommand
|
|
|
589
635
|
.description(
|
|
590
636
|
"Update specified tool or all tools to the latest version and update mops.toml",
|
|
591
637
|
)
|
|
592
|
-
.addArgument(new Argument("[tool]").choices(
|
|
638
|
+
.addArgument(new Argument("[tool]").choices(TOOLCHAINS))
|
|
593
639
|
.action(async (tool?: Tool) => {
|
|
594
640
|
if (!checkConfigFile()) {
|
|
595
641
|
process.exit(1);
|
|
@@ -600,9 +646,9 @@ toolchainCommand
|
|
|
600
646
|
toolchainCommand
|
|
601
647
|
.command("bin")
|
|
602
648
|
.description(
|
|
603
|
-
|
|
649
|
+
`Get path to the tool binary\n<tool> can be one of ${TOOLCHAINS.map((s) => `"${s}"`).join(", ")}`,
|
|
604
650
|
)
|
|
605
|
-
.addArgument(new Argument("<tool>").choices(
|
|
651
|
+
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
606
652
|
.addOption(
|
|
607
653
|
new Option(
|
|
608
654
|
"--fallback",
|
|
@@ -671,6 +717,28 @@ program
|
|
|
671
717
|
}
|
|
672
718
|
});
|
|
673
719
|
|
|
720
|
+
// lint
|
|
721
|
+
program
|
|
722
|
+
.command("lint [filter]")
|
|
723
|
+
.description("Lint Motoko code")
|
|
724
|
+
.addOption(new Option("--verbose", "Verbose output"))
|
|
725
|
+
.addOption(new Option("--fix", "Apply fixes"))
|
|
726
|
+
.addOption(
|
|
727
|
+
new Option(
|
|
728
|
+
"-r, --rules <directory...>",
|
|
729
|
+
"Directories containing rules (can be used multiple times)",
|
|
730
|
+
),
|
|
731
|
+
)
|
|
732
|
+
.allowUnknownOption(true)
|
|
733
|
+
.action(async (filter, options) => {
|
|
734
|
+
checkConfigFile(true);
|
|
735
|
+
const { extraArgs } = parseExtraArgs();
|
|
736
|
+
await lint(filter, {
|
|
737
|
+
...options,
|
|
738
|
+
extraArgs,
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
|
|
674
742
|
// docs
|
|
675
743
|
const docsCommand = new Command("docs").description("Documentation management");
|
|
676
744
|
|
|
@@ -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
|
@@ -19,6 +19,7 @@ import { getMocVersion } from "../helpers/get-moc-version.js";
|
|
|
19
19
|
import { getDfxVersion } from "../helpers/get-dfx-version.js";
|
|
20
20
|
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
21
21
|
import { sources } from "./sources.js";
|
|
22
|
+
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
22
23
|
|
|
23
24
|
import { Benchmark, Benchmarks } from "../declarations/main/main.did.js";
|
|
24
25
|
import { BenchResult, _SERVICE } from "../declarations/bench/bench.did.js";
|
|
@@ -26,18 +27,6 @@ import { BenchReplica } from "./bench-replica.js";
|
|
|
26
27
|
|
|
27
28
|
type ReplicaName = "dfx" | "pocket-ic" | "dfx-pocket-ic";
|
|
28
29
|
|
|
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
30
|
type BenchOptions = {
|
|
42
31
|
replica: ReplicaName;
|
|
43
32
|
replicaVersion: string;
|
|
@@ -113,7 +102,7 @@ export async function bench(
|
|
|
113
102
|
if (filter) {
|
|
114
103
|
globStr = `**/bench?(mark)/**/*${filter}*.mo`;
|
|
115
104
|
}
|
|
116
|
-
let files = globSync(path.join(rootDir, globStr),
|
|
105
|
+
let files = globSync(path.join(rootDir, globStr), MOTOKO_GLOB_CONFIG);
|
|
117
106
|
if (!files.length) {
|
|
118
107
|
if (filter) {
|
|
119
108
|
options.silent ||
|
package/commands/build.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { execa } from "execa";
|
|
3
3
|
import { exists } from "fs-extra";
|
|
4
|
-
import { mkdir } from "node:fs/promises";
|
|
4
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { cliError } from "../error.js";
|
|
7
|
+
import { isCandidCompatible } from "../helpers/is-candid-compatible.js";
|
|
8
|
+
import { CustomSection, getWasmBindings } from "../wasm.js";
|
|
7
9
|
import { readConfig } from "../mops.js";
|
|
8
10
|
import { CanisterConfig } from "../types.js";
|
|
9
11
|
import { sourcesArgs } from "./sources.js";
|
|
10
|
-
import {
|
|
11
|
-
import { cliError } from "../error.js";
|
|
12
|
+
import { toolchain } from "./toolchain/index.js";
|
|
12
13
|
|
|
13
14
|
export interface BuildOptions {
|
|
14
15
|
outputDir: string;
|
|
@@ -27,7 +28,7 @@ export async function build(
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
let outputDir = options.outputDir ?? DEFAULT_BUILD_OUTPUT_DIR;
|
|
30
|
-
let mocPath =
|
|
31
|
+
let mocPath = await toolchain.bin("moc", { fallback: true });
|
|
31
32
|
let canisters: Record<string, CanisterConfig> = {};
|
|
32
33
|
let config = readConfig();
|
|
33
34
|
if (config.canisters) {
|
|
@@ -69,17 +70,17 @@ export async function build(
|
|
|
69
70
|
: canisters;
|
|
70
71
|
|
|
71
72
|
for (let [canisterName, canister] of Object.entries(filteredCanisters)) {
|
|
72
|
-
options.verbose && console.time(`build canister ${canisterName}`);
|
|
73
73
|
console.log(chalk.blue("build canister"), chalk.bold(canisterName));
|
|
74
74
|
let motokoPath = canister.main;
|
|
75
75
|
if (!motokoPath) {
|
|
76
76
|
cliError(`No main file is specified for canister ${canisterName}`);
|
|
77
77
|
}
|
|
78
|
+
const wasmPath = join(outputDir, `${canisterName}.wasm`);
|
|
78
79
|
let args = [
|
|
79
80
|
"-c",
|
|
80
81
|
"--idl",
|
|
81
82
|
"-o",
|
|
82
|
-
|
|
83
|
+
wasmPath,
|
|
83
84
|
motokoPath,
|
|
84
85
|
...(options.extraArgs ?? []),
|
|
85
86
|
...(await sourcesArgs()).flat(),
|
|
@@ -100,6 +101,12 @@ export async function build(
|
|
|
100
101
|
}
|
|
101
102
|
args.push(...canister.args);
|
|
102
103
|
}
|
|
104
|
+
const isPublicCandid = true; // always true for now to reduce corner cases
|
|
105
|
+
const candidVisibility = isPublicCandid ? "icp:public" : "icp:private";
|
|
106
|
+
if (isPublicCandid) {
|
|
107
|
+
args.push("--public-metadata", "candid:service");
|
|
108
|
+
args.push("--public-metadata", "candid:args");
|
|
109
|
+
}
|
|
103
110
|
try {
|
|
104
111
|
if (options.verbose) {
|
|
105
112
|
console.log(chalk.gray(mocPath, JSON.stringify(args)));
|
|
@@ -128,8 +135,8 @@ export async function build(
|
|
|
128
135
|
console.log(result.stdout);
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
const generatedDidPath = join(outputDir, `${canisterName}.did`);
|
|
131
139
|
if (canister.candid) {
|
|
132
|
-
const generatedDidPath = join(outputDir, `${canisterName}.did`);
|
|
133
140
|
const originalCandidPath = canister.candid;
|
|
134
141
|
|
|
135
142
|
try {
|
|
@@ -146,27 +153,45 @@ export async function build(
|
|
|
146
153
|
|
|
147
154
|
if (options.verbose) {
|
|
148
155
|
console.log(
|
|
149
|
-
chalk.
|
|
156
|
+
chalk.gray(
|
|
150
157
|
`Candid compatibility check passed for canister ${canisterName}`,
|
|
151
158
|
),
|
|
152
159
|
);
|
|
153
160
|
}
|
|
154
|
-
} catch (
|
|
161
|
+
} catch (err: any) {
|
|
155
162
|
cliError(
|
|
156
|
-
`Error during Candid compatibility check for canister ${canisterName}`,
|
|
157
|
-
candidError,
|
|
163
|
+
`Error during Candid compatibility check for canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`,
|
|
158
164
|
);
|
|
159
165
|
}
|
|
160
166
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
167
|
+
|
|
168
|
+
options.verbose &&
|
|
169
|
+
console.log(chalk.gray(`Adding metadata to ${wasmPath}`));
|
|
170
|
+
const candidPath = canister.candid ?? generatedDidPath;
|
|
171
|
+
const candidText = await readFile(candidPath, "utf-8");
|
|
172
|
+
const customSections: CustomSection[] = [
|
|
173
|
+
{ name: `${candidVisibility} candid:service`, data: candidText },
|
|
174
|
+
];
|
|
175
|
+
if (canister.initArg) {
|
|
176
|
+
customSections.push({
|
|
177
|
+
name: `${candidVisibility} candid:args`,
|
|
178
|
+
data: canister.initArg,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const wasmBytes = await readFile(wasmPath);
|
|
182
|
+
const newWasm = getWasmBindings().add_custom_sections(
|
|
183
|
+
wasmBytes,
|
|
184
|
+
customSections,
|
|
185
|
+
);
|
|
186
|
+
await writeFile(wasmPath, newWasm);
|
|
187
|
+
} catch (err: any) {
|
|
188
|
+
if (err.message?.includes("Build failed for canister")) {
|
|
189
|
+
throw err;
|
|
164
190
|
}
|
|
165
191
|
cliError(
|
|
166
|
-
`Error while compiling canister ${canisterName}${
|
|
192
|
+
`Error while compiling canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`,
|
|
167
193
|
);
|
|
168
194
|
}
|
|
169
|
-
options.verbose && console.timeEnd(`build canister ${canisterName}`);
|
|
170
195
|
}
|
|
171
196
|
|
|
172
197
|
console.log(
|