ic-mops 2.0.1 → 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 +2 -4
- 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 +2 -4
- 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 +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 +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 +5 -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/helpers/autofix-motoko.ts +170 -0
- package/helpers/get-moc-version.ts +12 -1
- package/mops.ts +2 -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 +242 -0
- package/tests/__snapshots__/check.test.ts.snap +72 -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/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 +5 -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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { relative } from "node:path";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { execa } from "execa";
|
|
4
|
+
import { cliError } from "../error.js";
|
|
5
|
+
import { autofixMotoko } from "../helpers/autofix-motoko.js";
|
|
6
|
+
import { getMocSemVer } from "../helpers/get-moc-version.js";
|
|
7
|
+
import { sourcesArgs } from "./sources.js";
|
|
8
|
+
import { toolchain } from "./toolchain/index.js";
|
|
9
|
+
const MOC_ALL_LIBS_MIN_VERSION = "1.3.0";
|
|
10
|
+
function supportsAllLibsFlag() {
|
|
11
|
+
const version = getMocSemVer();
|
|
12
|
+
return version ? version.compare(MOC_ALL_LIBS_MIN_VERSION) >= 0 : false;
|
|
13
|
+
}
|
|
14
|
+
export async function check(files, options = {}) {
|
|
15
|
+
const fileList = Array.isArray(files) ? files : [files];
|
|
16
|
+
if (fileList.length === 0) {
|
|
17
|
+
cliError("No Motoko files specified for checking");
|
|
18
|
+
}
|
|
19
|
+
const mocPath = await toolchain.bin("moc", { fallback: true });
|
|
20
|
+
const sources = await sourcesArgs();
|
|
21
|
+
// --all-libs enables richer diagnostics with edit suggestions from moc (requires moc >= 1.3.0)
|
|
22
|
+
const allLibs = supportsAllLibsFlag();
|
|
23
|
+
if (!allLibs) {
|
|
24
|
+
console.log(chalk.yellow(`moc < ${MOC_ALL_LIBS_MIN_VERSION}: some diagnostic hints may be missing`));
|
|
25
|
+
}
|
|
26
|
+
else if (options.verbose) {
|
|
27
|
+
console.log(chalk.blue("check"), chalk.gray("Using --all-libs for richer diagnostics"));
|
|
28
|
+
}
|
|
29
|
+
const mocArgs = [
|
|
30
|
+
"--check",
|
|
31
|
+
...(allLibs ? ["--all-libs"] : []),
|
|
32
|
+
...sources.flat(),
|
|
33
|
+
...(options.extraArgs ?? []),
|
|
34
|
+
];
|
|
35
|
+
if (options.fix) {
|
|
36
|
+
if (options.verbose) {
|
|
37
|
+
console.log(chalk.blue("check"), chalk.gray("Attempting to fix files"));
|
|
38
|
+
}
|
|
39
|
+
const fixResult = await autofixMotoko(mocPath, fileList, mocArgs);
|
|
40
|
+
if (fixResult) {
|
|
41
|
+
for (const [file, codes] of fixResult.fixedFiles) {
|
|
42
|
+
const unique = [...new Set(codes)].sort();
|
|
43
|
+
const n = codes.length;
|
|
44
|
+
const rel = relative(process.cwd(), file);
|
|
45
|
+
console.log(chalk.green(`Fixed ${rel} (${n} ${n === 1 ? "fix" : "fixes"}: ${unique.join(", ")})`));
|
|
46
|
+
}
|
|
47
|
+
const fileCount = fixResult.fixedFiles.size;
|
|
48
|
+
console.log(chalk.green(`\n✓ ${fixResult.totalFixCount} ${fixResult.totalFixCount === 1 ? "fix" : "fixes"} applied to ${fileCount} ${fileCount === 1 ? "file" : "files"}`));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (options.verbose) {
|
|
52
|
+
console.log(chalk.yellow("No fixes were needed"));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const file of fileList) {
|
|
57
|
+
try {
|
|
58
|
+
const args = [file, ...mocArgs];
|
|
59
|
+
if (options.verbose) {
|
|
60
|
+
console.log(chalk.blue("check"), chalk.gray("Running moc:"));
|
|
61
|
+
console.log(chalk.gray(mocPath, JSON.stringify(args)));
|
|
62
|
+
}
|
|
63
|
+
const result = await execa(mocPath, args, {
|
|
64
|
+
stdio: "inherit",
|
|
65
|
+
reject: false,
|
|
66
|
+
});
|
|
67
|
+
if (result.exitCode !== 0) {
|
|
68
|
+
cliError(`✗ Check failed for file ${file} (exit code: ${result.exitCode})`);
|
|
69
|
+
}
|
|
70
|
+
if (!options.fix) {
|
|
71
|
+
console.log(chalk.green(`✓ ${file}`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
cliError(`Error while checking ${file}${err?.message ? `\n${err.message}` : ""}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
package/dist/commands/format.js
CHANGED
|
@@ -7,26 +7,13 @@ import motokoPlugin from "prettier-plugin-motoko";
|
|
|
7
7
|
import { getRootDir } from "../mops.js";
|
|
8
8
|
import { absToRel } from "./test/utils.js";
|
|
9
9
|
import { parallel } from "../parallel.js";
|
|
10
|
-
|
|
11
|
-
"**/node_modules/**",
|
|
12
|
-
"**/.mops/**",
|
|
13
|
-
"**/.vessel/**",
|
|
14
|
-
"**/.git/**",
|
|
15
|
-
"**/dist/**",
|
|
16
|
-
];
|
|
17
|
-
let globConfig = {
|
|
18
|
-
nocase: true,
|
|
19
|
-
ignore: ignore,
|
|
20
|
-
};
|
|
10
|
+
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
21
11
|
export async function format(filter, options = {}, signal, onProgress) {
|
|
22
12
|
let startTime = Date.now();
|
|
23
13
|
let rootDir = getRootDir();
|
|
24
|
-
let globStr = "**/*.mo";
|
|
25
|
-
if (filter) {
|
|
26
|
-
globStr = `**/*${filter}*.mo`;
|
|
27
|
-
}
|
|
14
|
+
let globStr = filter ? `**/*${filter}*.mo` : "**/*.mo";
|
|
28
15
|
let files = globSync(path.join(rootDir, globStr), {
|
|
29
|
-
...
|
|
16
|
+
...MOTOKO_GLOB_CONFIG,
|
|
30
17
|
cwd: rootDir,
|
|
31
18
|
});
|
|
32
19
|
let invalidFiles = 0;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import { globSync } from "glob";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { cliError } from "../error.js";
|
|
6
|
+
import { getRootDir, readConfig } from "../mops.js";
|
|
7
|
+
import { toolchain } from "./toolchain/index.js";
|
|
8
|
+
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
export async function lint(filter, options) {
|
|
11
|
+
let config = readConfig();
|
|
12
|
+
let rootDir = getRootDir();
|
|
13
|
+
let lintokoBinPath = config.toolchain?.lintoko
|
|
14
|
+
? await toolchain.bin("lintoko")
|
|
15
|
+
: "lintoko";
|
|
16
|
+
let globStr = filter ? `**/*${filter}*.mo` : "**/*.mo";
|
|
17
|
+
let filesToLint = globSync(path.join(rootDir, globStr), {
|
|
18
|
+
...MOTOKO_GLOB_CONFIG,
|
|
19
|
+
cwd: rootDir,
|
|
20
|
+
});
|
|
21
|
+
if (filesToLint.length === 0) {
|
|
22
|
+
cliError(`No files found for filter '${filter}'`);
|
|
23
|
+
}
|
|
24
|
+
let args = [];
|
|
25
|
+
if (options.verbose) {
|
|
26
|
+
args.push("--verbose");
|
|
27
|
+
}
|
|
28
|
+
if (options.fix) {
|
|
29
|
+
args.push("--fix");
|
|
30
|
+
}
|
|
31
|
+
const rules = options.rules && options.rules.length > 0
|
|
32
|
+
? options.rules
|
|
33
|
+
: ["lint", "lints"].filter((d) => existsSync(path.join(rootDir, d)));
|
|
34
|
+
rules.forEach((rule) => args.push("--rules", rule));
|
|
35
|
+
if (config.lint?.args) {
|
|
36
|
+
if (typeof config.lint.args === "string") {
|
|
37
|
+
cliError(`[lint] config 'args' should be an array of strings in mops.toml config file`);
|
|
38
|
+
}
|
|
39
|
+
args.push(...config.lint.args);
|
|
40
|
+
}
|
|
41
|
+
if (options.extraArgs && options.extraArgs.length > 0) {
|
|
42
|
+
args.push(...options.extraArgs);
|
|
43
|
+
}
|
|
44
|
+
args.push(...filesToLint);
|
|
45
|
+
try {
|
|
46
|
+
if (options.verbose) {
|
|
47
|
+
console.log(chalk.blue("lint"), chalk.gray("Running lintoko:"));
|
|
48
|
+
console.log(chalk.gray(lintokoBinPath));
|
|
49
|
+
console.log(chalk.gray(JSON.stringify(args)));
|
|
50
|
+
}
|
|
51
|
+
const result = await execa(lintokoBinPath, args, {
|
|
52
|
+
cwd: rootDir,
|
|
53
|
+
stdio: "inherit",
|
|
54
|
+
reject: false,
|
|
55
|
+
});
|
|
56
|
+
if (result.exitCode !== 0) {
|
|
57
|
+
cliError(`Lint failed with exit code ${result.exitCode}`);
|
|
58
|
+
}
|
|
59
|
+
if (options.fix) {
|
|
60
|
+
console.log(chalk.green("✓ Lint fixes applied"));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.log(chalk.green("✓ Lint succeeded"));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
cliError(`Error while running lintoko${err?.message ? `\n${err.message}` : ""}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
package/dist/commands/sync.js
CHANGED
|
@@ -7,6 +7,7 @@ import { add } from "./add.js";
|
|
|
7
7
|
import { remove } from "./remove.js";
|
|
8
8
|
import { checkIntegrity } from "../integrity.js";
|
|
9
9
|
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
10
|
+
import { MOTOKO_IGNORE_PATTERNS } from "../constants.js";
|
|
10
11
|
export async function sync({ lock } = {}) {
|
|
11
12
|
if (!checkConfigFile()) {
|
|
12
13
|
return;
|
|
@@ -31,19 +32,13 @@ export async function sync({ lock } = {}) {
|
|
|
31
32
|
}
|
|
32
33
|
await checkIntegrity(lock);
|
|
33
34
|
}
|
|
34
|
-
let ignore = [
|
|
35
|
-
"**/node_modules/**",
|
|
36
|
-
"**/.vessel/**",
|
|
37
|
-
"**/.git/**",
|
|
38
|
-
"**/.mops/**",
|
|
39
|
-
];
|
|
40
35
|
async function getUsedPackages() {
|
|
41
36
|
let rootDir = getRootDir();
|
|
42
37
|
let mocPath = getMocPath();
|
|
43
38
|
let files = globSync("**/*.mo", {
|
|
44
39
|
cwd: rootDir,
|
|
45
40
|
nocase: true,
|
|
46
|
-
ignore:
|
|
41
|
+
ignore: MOTOKO_IGNORE_PATTERNS,
|
|
47
42
|
});
|
|
48
43
|
let packages = new Set();
|
|
49
44
|
for (let file of files) {
|
|
@@ -21,16 +21,7 @@ import { SilentReporter } from "./reporters/silent-reporter.js";
|
|
|
21
21
|
import { toolchain } from "../toolchain/index.js";
|
|
22
22
|
import { Replica } from "../replica.js";
|
|
23
23
|
import { getDfxVersion } from "../../helpers/get-dfx-version.js";
|
|
24
|
-
|
|
25
|
-
"**/node_modules/**",
|
|
26
|
-
"**/.mops/**",
|
|
27
|
-
"**/.vessel/**",
|
|
28
|
-
"**/.git/**",
|
|
29
|
-
];
|
|
30
|
-
let globConfig = {
|
|
31
|
-
nocase: true,
|
|
32
|
-
ignore: ignore,
|
|
33
|
-
};
|
|
24
|
+
import { MOTOKO_GLOB_CONFIG, MOTOKO_IGNORE_PATTERNS } from "../../constants.js";
|
|
34
25
|
let replica = new Replica();
|
|
35
26
|
let replicaStartPromise;
|
|
36
27
|
async function startReplicaOnce(replica, type) {
|
|
@@ -94,7 +85,7 @@ export async function test(filter = "", options = {}) {
|
|
|
94
85
|
console.log(chalk.gray(`Press ${chalk.gray("Ctrl+C")} to exit.`));
|
|
95
86
|
}, 200);
|
|
96
87
|
let watcher = chokidar.watch([path.join(rootDir, "**/*.mo"), path.join(rootDir, "mops.toml")], {
|
|
97
|
-
ignored:
|
|
88
|
+
ignored: MOTOKO_IGNORE_PATTERNS,
|
|
98
89
|
ignoreInitial: true,
|
|
99
90
|
});
|
|
100
91
|
watcher.on("all", () => {
|
|
@@ -118,16 +109,15 @@ async function runAll(reporterName, filter = "", mode = "interpreter", replicaTy
|
|
|
118
109
|
export async function testWithReporter(reporterName, filter = "", defaultMode = "interpreter", replicaType, watch = false, signal) {
|
|
119
110
|
let rootDir = getRootDir();
|
|
120
111
|
let files = [];
|
|
121
|
-
let libFiles = globSync("**/test?(s)/lib.mo",
|
|
112
|
+
let libFiles = globSync("**/test?(s)/lib.mo", MOTOKO_GLOB_CONFIG);
|
|
122
113
|
if (libFiles[0]) {
|
|
123
114
|
files = [libFiles[0]];
|
|
124
115
|
}
|
|
125
116
|
else {
|
|
126
|
-
let globStr =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
files = globSync(path.join(rootDir, globStr), globConfig);
|
|
117
|
+
let globStr = filter
|
|
118
|
+
? `**/test?(s)/**/*${filter}*.mo`
|
|
119
|
+
: "**/test?(s)/**/*.test.mo";
|
|
120
|
+
files = globSync(path.join(rootDir, globStr), MOTOKO_GLOB_CONFIG);
|
|
131
121
|
}
|
|
132
122
|
if (!files.length) {
|
|
133
123
|
if (filter) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tool } from "../../types.js";
|
|
2
|
-
declare function
|
|
2
|
+
declare function checkToolchainInited({ strict }?: {
|
|
3
3
|
strict?: boolean | undefined;
|
|
4
4
|
}): Promise<boolean>;
|
|
5
5
|
declare function init({ reset, silent }?: {
|
|
@@ -21,6 +21,6 @@ export declare let toolchain: {
|
|
|
21
21
|
update: typeof update;
|
|
22
22
|
bin: typeof bin;
|
|
23
23
|
installAll: typeof installAll;
|
|
24
|
-
|
|
24
|
+
checkToolchainInited: typeof checkToolchainInited;
|
|
25
25
|
};
|
|
26
26
|
export {};
|
|
@@ -11,6 +11,8 @@ import { checkRequirements } from "../../check-requirements.js";
|
|
|
11
11
|
import * as moc from "./moc.js";
|
|
12
12
|
import * as pocketIc from "./pocket-ic.js";
|
|
13
13
|
import * as wasmtime from "./wasmtime.js";
|
|
14
|
+
import * as lintoko from "./lintoko.js";
|
|
15
|
+
import { FILE_PATH_REGEX } from "../../constants.js";
|
|
14
16
|
function getToolUtils(tool) {
|
|
15
17
|
if (tool === "moc") {
|
|
16
18
|
return moc;
|
|
@@ -21,12 +23,15 @@ function getToolUtils(tool) {
|
|
|
21
23
|
else if (tool === "wasmtime") {
|
|
22
24
|
return wasmtime;
|
|
23
25
|
}
|
|
26
|
+
else if (tool === "lintoko") {
|
|
27
|
+
return lintoko;
|
|
28
|
+
}
|
|
24
29
|
else {
|
|
25
30
|
console.error(`Unknown tool '${tool}'`);
|
|
26
31
|
process.exit(1);
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
async function
|
|
34
|
+
async function checkToolchainInited({ strict = false } = {}) {
|
|
30
35
|
// auto init in CI
|
|
31
36
|
if (process.env.CI) {
|
|
32
37
|
await init({ silent: true });
|
|
@@ -47,8 +52,8 @@ async function ensureToolchainInited({ strict = true } = {}) {
|
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
catch { }
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
process.stderr.write(`${chalk.yellow('Toolchain management is not initialized. Run "mops toolchain init" to use with dfx.')}\n`);
|
|
56
|
+
return false;
|
|
52
57
|
}
|
|
53
58
|
// update shell config files to set DFX_MOC_PATH to moc-wrapper
|
|
54
59
|
async function init({ reset = false, silent = false } = {}) {
|
|
@@ -172,6 +177,9 @@ async function installAll({ silent = false, verbose = false } = {}) {
|
|
|
172
177
|
verbose,
|
|
173
178
|
});
|
|
174
179
|
}
|
|
180
|
+
if (config.toolchain?.lintoko) {
|
|
181
|
+
await download("lintoko", config.toolchain.lintoko, { silent, verbose });
|
|
182
|
+
}
|
|
175
183
|
if (!silent) {
|
|
176
184
|
logUpdate.clear();
|
|
177
185
|
console.log(chalk.green("Toolchain installed"));
|
|
@@ -204,7 +212,7 @@ async function promptVersion(tool) {
|
|
|
204
212
|
// download binary and set version in mops.toml
|
|
205
213
|
async function use(tool, version) {
|
|
206
214
|
if (tool === "moc") {
|
|
207
|
-
await
|
|
215
|
+
await checkToolchainInited();
|
|
208
216
|
}
|
|
209
217
|
if (!version) {
|
|
210
218
|
version = await promptVersion(tool);
|
|
@@ -232,7 +240,7 @@ async function use(tool, version) {
|
|
|
232
240
|
// download latest binary and set version in mops.toml
|
|
233
241
|
async function update(tool) {
|
|
234
242
|
if (tool === "moc") {
|
|
235
|
-
await
|
|
243
|
+
await checkToolchainInited();
|
|
236
244
|
}
|
|
237
245
|
let config = readConfig();
|
|
238
246
|
config.toolchain = config.toolchain || {};
|
|
@@ -273,8 +281,11 @@ async function bin(tool, { fallback = false } = {}) {
|
|
|
273
281
|
let config = readConfig();
|
|
274
282
|
let version = config.toolchain?.[tool];
|
|
275
283
|
if (version) {
|
|
284
|
+
if (version.match(FILE_PATH_REGEX)) {
|
|
285
|
+
return version;
|
|
286
|
+
}
|
|
276
287
|
if (tool === "moc") {
|
|
277
|
-
await
|
|
288
|
+
await checkToolchainInited();
|
|
278
289
|
}
|
|
279
290
|
await download(tool, version, { silent: true });
|
|
280
291
|
if (tool === "moc") {
|
|
@@ -300,5 +311,5 @@ export let toolchain = {
|
|
|
300
311
|
update,
|
|
301
312
|
bin,
|
|
302
313
|
installAll,
|
|
303
|
-
|
|
314
|
+
checkToolchainInited,
|
|
304
315
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare let repo: string;
|
|
2
|
+
export declare let getLatestReleaseTag: () => Promise<string>;
|
|
3
|
+
export declare let getReleases: () => Promise<any>;
|
|
4
|
+
export declare let isCached: (version: string) => boolean;
|
|
5
|
+
export declare let download: (version: string, { silent, verbose }?: {
|
|
6
|
+
silent?: boolean | undefined;
|
|
7
|
+
verbose?: boolean | undefined;
|
|
8
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { globalCacheDir } from "../../mops.js";
|
|
5
|
+
import * as toolchainUtils from "./toolchain-utils.js";
|
|
6
|
+
let cacheDir = path.join(globalCacheDir, "lintoko");
|
|
7
|
+
export let repo = "caffeinelabs/lintoko";
|
|
8
|
+
export let getLatestReleaseTag = async () => {
|
|
9
|
+
return toolchainUtils.getLatestReleaseTag(repo);
|
|
10
|
+
};
|
|
11
|
+
export let getReleases = async () => {
|
|
12
|
+
return toolchainUtils.getReleases(repo);
|
|
13
|
+
};
|
|
14
|
+
export let isCached = (version) => {
|
|
15
|
+
let dir = path.join(cacheDir, version);
|
|
16
|
+
return fs.existsSync(dir) && fs.existsSync(path.join(dir, "lintoko"));
|
|
17
|
+
};
|
|
18
|
+
export let download = async (version, { silent = false, verbose = false } = {}) => {
|
|
19
|
+
if (!version) {
|
|
20
|
+
console.error("version is not defined");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (isCached(version)) {
|
|
24
|
+
if (verbose) {
|
|
25
|
+
console.log(`lintoko ${version} is already installed`);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let platform = process.platform == "darwin" ? "apple-darwin" : "unknown-linux-gnu";
|
|
30
|
+
let arch = process.arch.startsWith("arm") ? "aarch64" : "x86_64";
|
|
31
|
+
let url = `https://github.com/caffeinelabs/lintoko/releases/download/v${version}/lintoko-${arch}-${platform}.tar.xz`;
|
|
32
|
+
if (verbose && !silent) {
|
|
33
|
+
console.log(`Downloading ${url}`);
|
|
34
|
+
}
|
|
35
|
+
await toolchainUtils.downloadAndExtract(url, path.join(cacheDir, version), "lintoko");
|
|
36
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
|
+
export declare const TOOLCHAINS: string[];
|
|
2
3
|
export declare let tryDownloadFile: (url: string) => Promise<Buffer | null>;
|
|
3
4
|
export declare let downloadAndExtract: (url: string, destDir: string, destFileName?: string) => Promise<void>;
|
|
4
5
|
export declare let getLatestReleaseTag: (repo: string) => Promise<string>;
|
|
@@ -10,6 +10,7 @@ import { deleteSync } from "del";
|
|
|
10
10
|
import { Octokit } from "octokit";
|
|
11
11
|
import { extract as extractTar } from "tar";
|
|
12
12
|
import { getRootDir } from "../../mops.js";
|
|
13
|
+
export const TOOLCHAINS = ["moc", "wasmtime", "pocket-ic", "lintoko"];
|
|
13
14
|
export let tryDownloadFile = async (url) => {
|
|
14
15
|
let res = await fetch(url);
|
|
15
16
|
if (!res.ok) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common ignore patterns for glob operations across Motoko files.
|
|
3
|
+
*/
|
|
4
|
+
export declare const MOTOKO_IGNORE_PATTERNS: string[];
|
|
5
|
+
/**
|
|
6
|
+
* Common glob configuration for Motoko file operations
|
|
7
|
+
*/
|
|
8
|
+
export declare const MOTOKO_GLOB_CONFIG: {
|
|
9
|
+
nocase: boolean;
|
|
10
|
+
ignore: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Regex to match a file path for dependency and toolchain versions
|
|
14
|
+
*/
|
|
15
|
+
export declare const FILE_PATH_REGEX: RegExp;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common ignore patterns for glob operations across Motoko files.
|
|
3
|
+
*/
|
|
4
|
+
export const MOTOKO_IGNORE_PATTERNS = [
|
|
5
|
+
"**/node_modules/**",
|
|
6
|
+
"**/.mops/**",
|
|
7
|
+
"**/.vessel/**",
|
|
8
|
+
"**/.git/**",
|
|
9
|
+
"**/dist/**",
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Common glob configuration for Motoko file operations
|
|
13
|
+
*/
|
|
14
|
+
export const MOTOKO_GLOB_CONFIG = {
|
|
15
|
+
nocase: true,
|
|
16
|
+
ignore: MOTOKO_IGNORE_PATTERNS,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Regex to match a file path for dependency and toolchain versions
|
|
20
|
+
*/
|
|
21
|
+
export const FILE_PATH_REGEX = /^(\.?\.)?\//;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
2
4
|
import { setWasmBindings } from "../../wasm.js";
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const wasm = require(path.join(__dirname, "../../wasm/pkg/nodejs/wasm.js"));
|
|
3
8
|
setWasmBindings(wasm);
|
|
4
9
|
export * from "../../cli.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface MocSpan {
|
|
2
|
+
file: string;
|
|
3
|
+
line_start: number;
|
|
4
|
+
column_start: number;
|
|
5
|
+
line_end: number;
|
|
6
|
+
column_end: number;
|
|
7
|
+
is_primary: boolean;
|
|
8
|
+
label: string | null;
|
|
9
|
+
suggested_replacement: string | null;
|
|
10
|
+
suggestion_applicability: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface MocDiagnostic {
|
|
13
|
+
message: string;
|
|
14
|
+
code: string;
|
|
15
|
+
level: string;
|
|
16
|
+
spans: MocSpan[];
|
|
17
|
+
notes: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare function parseDiagnostics(stdout: string): MocDiagnostic[];
|
|
20
|
+
export interface AutofixResult {
|
|
21
|
+
/** Map of file path → diagnostic codes fixed in that file */
|
|
22
|
+
fixedFiles: Map<string, string[]>;
|
|
23
|
+
totalFixCount: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function autofixMotoko(mocPath: string, files: string[], mocArgs: string[]): Promise<AutofixResult | null>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { execa } from "execa";
|
|
4
|
+
import { TextDocument, } from "vscode-languageserver-textdocument";
|
|
5
|
+
export function parseDiagnostics(stdout) {
|
|
6
|
+
return stdout
|
|
7
|
+
.split("\n")
|
|
8
|
+
.filter((l) => l.trim())
|
|
9
|
+
.map((l) => {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(l);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
.filter((d) => d !== null);
|
|
18
|
+
}
|
|
19
|
+
function extractFixes(diagnostics) {
|
|
20
|
+
const fixes = [];
|
|
21
|
+
for (const diag of diagnostics) {
|
|
22
|
+
for (const span of diag.spans) {
|
|
23
|
+
if (span.suggestion_applicability === "MachineApplicable" &&
|
|
24
|
+
span.suggested_replacement !== null) {
|
|
25
|
+
fixes.push({
|
|
26
|
+
file: span.file,
|
|
27
|
+
code: diag.code,
|
|
28
|
+
edit: {
|
|
29
|
+
range: {
|
|
30
|
+
start: {
|
|
31
|
+
line: span.line_start - 1,
|
|
32
|
+
character: span.column_start - 1,
|
|
33
|
+
},
|
|
34
|
+
end: {
|
|
35
|
+
line: span.line_end - 1,
|
|
36
|
+
character: span.column_end - 1,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
newText: span.suggested_replacement,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return fixes;
|
|
46
|
+
}
|
|
47
|
+
const MAX_FIX_ITERATIONS = 10;
|
|
48
|
+
export async function autofixMotoko(mocPath, files, mocArgs) {
|
|
49
|
+
const fixedFilesCodes = new Map();
|
|
50
|
+
for (let iteration = 0; iteration < MAX_FIX_ITERATIONS; iteration++) {
|
|
51
|
+
const allFixes = [];
|
|
52
|
+
for (const file of files) {
|
|
53
|
+
const result = await execa(mocPath, [file, "--error-format=json", ...mocArgs], { stdio: "pipe", reject: false });
|
|
54
|
+
const diagnostics = parseDiagnostics(result.stdout);
|
|
55
|
+
allFixes.push(...extractFixes(diagnostics));
|
|
56
|
+
}
|
|
57
|
+
if (allFixes.length === 0) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
const fixesByFile = new Map();
|
|
61
|
+
for (const fix of allFixes) {
|
|
62
|
+
const normalizedPath = resolve(fix.file);
|
|
63
|
+
const existing = fixesByFile.get(normalizedPath) ?? [];
|
|
64
|
+
existing.push(fix);
|
|
65
|
+
fixesByFile.set(normalizedPath, existing);
|
|
66
|
+
}
|
|
67
|
+
let progress = false;
|
|
68
|
+
for (const [file, fixes] of fixesByFile) {
|
|
69
|
+
const original = await readFile(file, "utf-8");
|
|
70
|
+
const doc = TextDocument.create(`file://${file}`, "motoko", 0, original);
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = TextDocument.applyEdits(doc, fixes.map((f) => f.edit));
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.warn(`Warning: could not apply fixes to ${file}: ${err}`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (result === original) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
await writeFile(file, result, "utf-8");
|
|
83
|
+
progress = true;
|
|
84
|
+
const existing = fixedFilesCodes.get(file) ?? [];
|
|
85
|
+
for (const fix of fixes) {
|
|
86
|
+
existing.push(fix.code);
|
|
87
|
+
}
|
|
88
|
+
fixedFilesCodes.set(file, existing);
|
|
89
|
+
}
|
|
90
|
+
if (!progress) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (fixedFilesCodes.size === 0) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
let totalFixCount = 0;
|
|
98
|
+
for (const codes of fixedFilesCodes.values()) {
|
|
99
|
+
totalFixCount += codes.length;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
fixedFiles: fixedFilesCodes,
|
|
103
|
+
totalFixCount,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { parse } from "semver";
|
|
3
|
+
import { readConfig } from "../mops.js";
|
|
2
4
|
import { getMocPath } from "./get-moc-path.js";
|
|
5
|
+
export function getMocSemVer() {
|
|
6
|
+
return parse(getMocVersion(false));
|
|
7
|
+
}
|
|
3
8
|
export function getMocVersion(throwOnError = false) {
|
|
4
|
-
let
|
|
9
|
+
let configVersion = readConfig().toolchain?.moc;
|
|
10
|
+
if (configVersion) {
|
|
11
|
+
return configVersion;
|
|
12
|
+
}
|
|
13
|
+
const mocPath = getMocPath(false);
|
|
5
14
|
if (!mocPath) {
|
|
6
15
|
return "";
|
|
7
16
|
}
|
package/dist/mops.js
CHANGED
|
@@ -10,6 +10,7 @@ import { mainActor, storageActor } from "./api/actors.js";
|
|
|
10
10
|
import { getNetwork } from "./api/network.js";
|
|
11
11
|
import { getHighestVersion } from "./api/getHighestVersion.js";
|
|
12
12
|
import { getPackageId } from "./helpers/get-package-id.js";
|
|
13
|
+
import { FILE_PATH_REGEX } from "./constants.js";
|
|
13
14
|
if (!globalThis.fetch) {
|
|
14
15
|
globalThis.fetch = fetch;
|
|
15
16
|
}
|
|
@@ -135,7 +136,7 @@ export function getDependencyType(version) {
|
|
|
135
136
|
if (version.startsWith("https://github.com/")) {
|
|
136
137
|
return "github";
|
|
137
138
|
}
|
|
138
|
-
else if (version.match(
|
|
139
|
+
else if (version.match(FILE_PATH_REGEX)) {
|
|
139
140
|
return "local";
|
|
140
141
|
}
|
|
141
142
|
else {
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ic-mops",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mops": "bin/mops.js",
|
|
@@ -71,7 +71,8 @@
|
|
|
71
71
|
"stream-to-promise": "3.0.0",
|
|
72
72
|
"string-width": "7.2.0",
|
|
73
73
|
"tar": "7.5.6",
|
|
74
|
-
"terminal-size": "4.0.0"
|
|
74
|
+
"terminal-size": "4.0.0",
|
|
75
|
+
"vscode-languageserver-textdocument": "1.0.12"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
77
78
|
"@tsconfig/strictest": "2.0.5",
|