ic-mops 2.5.0 → 2.6.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 +24 -0
- package/api/network.ts +1 -1
- package/bun.lock +1082 -78
- package/bundle/cli.tgz +0 -0
- package/cli.ts +1 -1
- package/commands/add.ts +4 -1
- package/commands/build.ts +7 -12
- package/commands/check.ts +20 -2
- package/commands/docs-coverage.ts +26 -21
- package/commands/install/install-dep.ts +5 -3
- package/commands/lint.ts +107 -10
- package/commands/publish.ts +24 -11
- package/commands/remove.ts +5 -2
- package/commands/self.ts +1 -1
- package/commands/sources.ts +3 -2
- package/commands/sync.ts +13 -16
- package/commands/test/test.ts +3 -3
- package/commands/update.ts +13 -7
- package/commands/watch/error-checker.ts +3 -8
- package/commands/watch/warning-checker.ts +3 -8
- package/dist/api/network.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/commands/add.js +4 -1
- package/dist/commands/build.js +5 -10
- package/dist/commands/check.js +14 -2
- package/dist/commands/docs-coverage.js +22 -22
- package/dist/commands/install/install-dep.js +3 -3
- package/dist/commands/lint.d.ts +3 -0
- package/dist/commands/lint.js +75 -10
- package/dist/commands/publish.js +19 -11
- package/dist/commands/remove.js +5 -2
- package/dist/commands/self.js +1 -1
- package/dist/commands/sources.js +3 -2
- package/dist/commands/sync.js +9 -14
- package/dist/commands/test/test.js +3 -3
- package/dist/commands/update.js +9 -4
- package/dist/commands/watch/error-checker.js +3 -8
- package/dist/commands/watch/warning-checker.js +3 -8
- package/dist/helpers/find-changelog-entry.js +1 -1
- package/dist/integrity.js +9 -3
- package/dist/mops.js +3 -0
- package/dist/package.json +3 -5
- package/dist/release-cli.js +2 -2
- package/dist/resolve-packages.js +4 -4
- package/dist/tests/build.test.js +1 -1
- package/dist/tests/check.test.js +24 -0
- package/dist/tests/helpers.js +8 -1
- package/dist/tests/lint.test.js +28 -2
- package/dist/types.d.ts +2 -0
- package/dist/vessel.d.ts +1 -1
- package/dist/vessel.js +3 -2
- package/helpers/find-changelog-entry.ts +3 -1
- package/integrity.ts +12 -3
- package/mops.ts +7 -0
- package/package.json +3 -5
- package/release-cli.ts +2 -2
- package/resolve-packages.ts +6 -4
- package/tests/build.test.ts +1 -1
- package/tests/check/with-lint-fail/NoBoolSwitch.mo +8 -0
- package/tests/check/with-lint-fail/lints/no-bool-switch.toml +9 -0
- package/tests/check/with-lint-fail/mops.toml +9 -0
- package/tests/check/with-lint-pass/Ok.mo +5 -0
- package/tests/check/with-lint-pass/lints/no-bool-switch.toml +9 -0
- package/tests/check/with-lint-pass/mops.toml +9 -0
- package/tests/check.test.ts +28 -0
- package/tests/helpers.ts +9 -1
- package/tests/lint-config-rules/extra-rules/no-bool-switch.toml +9 -0
- package/tests/lint-config-rules/mops.toml +5 -0
- package/tests/lint-config-rules/src/NoBoolSwitch.mo +8 -0
- package/tests/lint-extends/mops.toml +8 -0
- package/tests/lint-extends/my-pkg/mops.toml +3 -0
- package/tests/lint-extends/my-pkg/rules/no-bool-switch.toml +9 -0
- package/tests/lint-extends/src/NoBoolSwitch.mo +8 -0
- package/tests/lint-extends-all/mops.toml +8 -0
- package/tests/lint-extends-all/src/NoBoolSwitch.mo +8 -0
- package/tests/lint-extends-ignored/mops.toml +8 -0
- package/tests/lint-extends-ignored/src/NoBoolSwitch.mo +8 -0
- package/tests/lint.test.ts +32 -2
- package/types.ts +2 -0
- package/vessel.ts +5 -3
|
@@ -5,7 +5,7 @@ import chalk from "chalk";
|
|
|
5
5
|
|
|
6
6
|
import { getMocPath } from "../../helpers/get-moc-path.js";
|
|
7
7
|
import { getGlobalMocArgs, getRootDir, readConfig } from "../../mops.js";
|
|
8
|
-
import {
|
|
8
|
+
import { sourcesArgs } from "../sources.js";
|
|
9
9
|
import { ErrorChecker } from "./error-checker.js";
|
|
10
10
|
import { parallel } from "../../parallel.js";
|
|
11
11
|
import { globMoFiles } from "./globMoFiles.js";
|
|
@@ -69,7 +69,7 @@ export class WarningChecker {
|
|
|
69
69
|
|
|
70
70
|
let rootDir = getRootDir();
|
|
71
71
|
let mocPath = getMocPath();
|
|
72
|
-
let deps = await
|
|
72
|
+
let deps = (await sourcesArgs({ cwd: rootDir })).flat();
|
|
73
73
|
let globalMocArgs = getGlobalMocArgs(readConfig());
|
|
74
74
|
let paths = globMoFiles(rootDir);
|
|
75
75
|
|
|
@@ -83,12 +83,7 @@ export class WarningChecker {
|
|
|
83
83
|
|
|
84
84
|
let { stderr } = await promisify(execFile)(
|
|
85
85
|
mocPath,
|
|
86
|
-
[
|
|
87
|
-
"--check",
|
|
88
|
-
...deps.flatMap((x) => x.split(" ")),
|
|
89
|
-
...globalMocArgs,
|
|
90
|
-
file,
|
|
91
|
-
],
|
|
86
|
+
["--check", ...deps, ...globalMocArgs, file],
|
|
92
87
|
{ cwd: rootDir, signal },
|
|
93
88
|
).catch((error) => {
|
|
94
89
|
if (error.code === "ABORT_ERR") {
|
package/dist/api/network.js
CHANGED
package/dist/cli.js
CHANGED
|
@@ -255,7 +255,7 @@ program
|
|
|
255
255
|
// check
|
|
256
256
|
program
|
|
257
257
|
.command("check [files...]")
|
|
258
|
-
.description("Check Motoko files for syntax errors and type issues. If no files are specified, checks all canister entrypoints from mops.toml. Also runs stable compatibility checks for canisters with [check-stable] configured")
|
|
258
|
+
.description("Check Motoko files for syntax errors and type issues. If no files are specified, checks all canister entrypoints from mops.toml. Also runs stable compatibility checks for canisters with [check-stable] configured, and runs linting if lintoko is configured in [toolchain] and rule directories are present")
|
|
259
259
|
.option("--verbose", "Verbose console output")
|
|
260
260
|
.addOption(new Option("--fix", "Apply autofixes to all files, including transitively imported ones"))
|
|
261
261
|
.allowUnknownOption(true)
|
package/dist/commands/add.js
CHANGED
|
@@ -77,9 +77,12 @@ export async function add(name, { verbose = false, dev = false, lock } = {}, asN
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
if (pkgDetails.repo) {
|
|
80
|
-
await installFromGithub(pkgDetails.name, pkgDetails.repo, {
|
|
80
|
+
let res = await installFromGithub(pkgDetails.name, pkgDetails.repo, {
|
|
81
81
|
verbose: verbose,
|
|
82
82
|
});
|
|
83
|
+
if (!res) {
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
83
86
|
}
|
|
84
87
|
else if (!pkgDetails.path) {
|
|
85
88
|
let res = await installMopsDep(pkgDetails.name, pkgDetails.version, {
|
package/dist/commands/build.js
CHANGED
|
@@ -12,7 +12,7 @@ import { sourcesArgs } from "./sources.js";
|
|
|
12
12
|
import { toolchain } from "./toolchain/index.js";
|
|
13
13
|
export const DEFAULT_BUILD_OUTPUT_DIR = ".mops/.build";
|
|
14
14
|
export async function build(canisterNames, options) {
|
|
15
|
-
if (canisterNames?.length
|
|
15
|
+
if (canisterNames?.length === 0) {
|
|
16
16
|
cliError("No canisters specified to build");
|
|
17
17
|
}
|
|
18
18
|
let config = readConfig();
|
|
@@ -26,14 +26,9 @@ export async function build(canisterNames, options) {
|
|
|
26
26
|
cliError(`No Motoko canisters found in mops.toml configuration`);
|
|
27
27
|
}
|
|
28
28
|
if (canisterNames) {
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
for (let name of canisterNames) {
|
|
34
|
-
if (!(name in canisters)) {
|
|
35
|
-
cliError(`Motoko canister '${name}' not found in mops.toml configuration`);
|
|
36
|
-
}
|
|
29
|
+
let invalidNames = canisterNames.filter((name) => !(name in canisters));
|
|
30
|
+
if (invalidNames.length) {
|
|
31
|
+
cliError(`Motoko canister(s) not found in mops.toml configuration: ${invalidNames.join(", ")}`);
|
|
37
32
|
}
|
|
38
33
|
}
|
|
39
34
|
if (!(await exists(outputDir))) {
|
|
@@ -131,7 +126,7 @@ export async function build(canisterNames, options) {
|
|
|
131
126
|
cliError(`Error while compiling canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`);
|
|
132
127
|
}
|
|
133
128
|
}
|
|
134
|
-
console.log(chalk.green(`\n✓ Built ${Object.keys(filteredCanisters).length} canister${Object.keys(filteredCanisters).length
|
|
129
|
+
console.log(chalk.green(`\n✓ Built ${Object.keys(filteredCanisters).length} canister${Object.keys(filteredCanisters).length === 1 ? "" : "s"} successfully`));
|
|
135
130
|
}
|
|
136
131
|
const managedFlags = {
|
|
137
132
|
"-o": "use [build].outputDir in mops.toml or --output flag instead",
|
package/dist/commands/check.js
CHANGED
|
@@ -3,20 +3,22 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { execa } from "execa";
|
|
5
5
|
import { cliError } from "../error.js";
|
|
6
|
-
import { getGlobalMocArgs, readConfig, resolveConfigPath } from "../mops.js";
|
|
6
|
+
import { getGlobalMocArgs, getRootDir, readConfig, resolveConfigPath, } from "../mops.js";
|
|
7
7
|
import { autofixMotoko } from "../helpers/autofix-motoko.js";
|
|
8
8
|
import { getMocSemVer } from "../helpers/get-moc-version.js";
|
|
9
9
|
import { resolveCanisterConfigs, resolveCanisterEntrypoints, } from "../helpers/resolve-canisters.js";
|
|
10
10
|
import { runStableCheck } from "./check-stable.js";
|
|
11
11
|
import { sourcesArgs } from "./sources.js";
|
|
12
12
|
import { toolchain } from "./toolchain/index.js";
|
|
13
|
+
import { collectLintRules, lint } from "./lint.js";
|
|
13
14
|
const MOC_ALL_LIBS_MIN_VERSION = "1.3.0";
|
|
14
15
|
function supportsAllLibsFlag() {
|
|
15
16
|
const version = getMocSemVer();
|
|
16
17
|
return version ? version.compare(MOC_ALL_LIBS_MIN_VERSION) >= 0 : false;
|
|
17
18
|
}
|
|
18
19
|
export async function check(files, options = {}) {
|
|
19
|
-
|
|
20
|
+
const explicitFiles = Array.isArray(files) ? files : files ? [files] : [];
|
|
21
|
+
let fileList = [...explicitFiles];
|
|
20
22
|
const config = readConfig();
|
|
21
23
|
if (fileList.length === 0) {
|
|
22
24
|
fileList = resolveCanisterEntrypoints(config).map(resolveConfigPath);
|
|
@@ -115,4 +117,14 @@ export async function check(files, options = {}) {
|
|
|
115
117
|
options: { verbose: options.verbose, extraArgs: options.extraArgs },
|
|
116
118
|
});
|
|
117
119
|
}
|
|
120
|
+
if (config.toolchain?.lintoko) {
|
|
121
|
+
const rootDir = getRootDir();
|
|
122
|
+
const lintRules = await collectLintRules(config, rootDir);
|
|
123
|
+
await lint(undefined, {
|
|
124
|
+
verbose: options.verbose,
|
|
125
|
+
fix: options.fix,
|
|
126
|
+
rules: lintRules,
|
|
127
|
+
files: explicitFiles.length > 0 ? explicitFiles : undefined,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
118
130
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { globSync } from "glob";
|
|
4
|
-
import { JSDOM } from "jsdom";
|
|
5
4
|
import { docs } from "./docs.js";
|
|
6
5
|
export async function docsCoverage(options = {}) {
|
|
7
6
|
let docsDir = ".mops/.docs";
|
|
@@ -14,11 +13,11 @@ export async function docsCoverage(options = {}) {
|
|
|
14
13
|
await docs({
|
|
15
14
|
source,
|
|
16
15
|
output: docsDir,
|
|
17
|
-
format: "
|
|
16
|
+
format: "adoc",
|
|
18
17
|
silent: true,
|
|
19
18
|
});
|
|
20
|
-
let files = globSync(`${docsDir}/**/*.
|
|
21
|
-
ignore: [`${docsDir}
|
|
19
|
+
let files = globSync(`${docsDir}/**/*.adoc`, {
|
|
20
|
+
ignore: [`${docsDir}/**/*.test.adoc`, `${docsDir}/test/**/*`],
|
|
22
21
|
});
|
|
23
22
|
let coverages = [];
|
|
24
23
|
for (let file of files) {
|
|
@@ -58,33 +57,34 @@ export async function docsCoverage(options = {}) {
|
|
|
58
57
|
return totalCoverage;
|
|
59
58
|
}
|
|
60
59
|
function docFileCoverage(file) {
|
|
61
|
-
let
|
|
62
|
-
|
|
60
|
+
let content = readFileSync(file, "utf-8");
|
|
61
|
+
// Module name is on the line after the [[module.*]] anchor
|
|
62
|
+
let module = content.match(/^\[\[module\.[^\]]+\]\]\n= (.+)$/m)?.[1]?.trim() || "";
|
|
63
63
|
let moduleFile = `${module}.mo`;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
let
|
|
64
|
+
// Split into per-declaration sections at every [[id]] that is NOT [[module.*]]
|
|
65
|
+
let sections = content.split(/^(?=\[\[(?!module\.))/m).slice(1);
|
|
66
|
+
let items = sections.map((section) => {
|
|
67
|
+
let rawId = section.match(/^\[\[([^\]]+)\]\]/)?.[1] ?? "";
|
|
68
|
+
let id = rawId.replace(/^type\./, "");
|
|
69
|
+
// mo-doc anchors types as [[type.X]]; classes/values have no prefix → "func"
|
|
70
|
+
let type = rawId.startsWith("type.") ? "type" : "func";
|
|
71
|
+
let definition = section.match(/^== (.+)$/m)?.[1]?.trim() ?? "";
|
|
72
|
+
// Text after the closing ---- is the doc comment (empty when undocumented).
|
|
73
|
+
// slice(2).join preserves any ---- that appears inside the comment itself.
|
|
74
|
+
let parts = section.split(/^----$/m);
|
|
75
|
+
let comment = parts.slice(2).join("----").trim();
|
|
71
76
|
return {
|
|
72
77
|
file: moduleFile,
|
|
73
78
|
id,
|
|
74
79
|
type,
|
|
75
80
|
definition,
|
|
76
81
|
comment,
|
|
77
|
-
covered:
|
|
82
|
+
covered: comment.length >= 5,
|
|
78
83
|
};
|
|
79
84
|
});
|
|
80
|
-
let coverage =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
coverage =
|
|
86
|
-
(items.filter((item) => item.covered).length / items.length) * 100;
|
|
87
|
-
}
|
|
85
|
+
let coverage = !items.length
|
|
86
|
+
? 100
|
|
87
|
+
: (items.filter((item) => item.covered).length / items.length) * 100;
|
|
88
88
|
return { file: moduleFile, coverage, items };
|
|
89
89
|
}
|
|
90
90
|
function colorizeCoverage(coverage) {
|
|
@@ -7,12 +7,11 @@ import { getRootDir } from "../../mops.js";
|
|
|
7
7
|
// returns false if failed
|
|
8
8
|
export async function installDep(dep, { verbose, silent, threads, ignoreTransitive } = {}, parentPkgPath) {
|
|
9
9
|
if (dep.repo) {
|
|
10
|
-
|
|
10
|
+
return installFromGithub(dep.name, dep.repo, {
|
|
11
11
|
silent,
|
|
12
12
|
verbose,
|
|
13
13
|
ignoreTransitive,
|
|
14
14
|
});
|
|
15
|
-
return true;
|
|
16
15
|
}
|
|
17
16
|
else if (dep.path) {
|
|
18
17
|
let depPath = dep.path;
|
|
@@ -34,5 +33,6 @@ export async function installDep(dep, { verbose, silent, threads, ignoreTransiti
|
|
|
34
33
|
ignoreTransitive,
|
|
35
34
|
});
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
console.warn(`Warning: dependency "${dep.name}" has no version, repo, or path`);
|
|
37
|
+
return false;
|
|
38
38
|
}
|
package/dist/commands/lint.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { Config } from "../types.js";
|
|
2
|
+
export declare function collectLintRules(config: Config, rootDir: string): Promise<string[]>;
|
|
1
3
|
export interface LintOptions {
|
|
2
4
|
verbose: boolean;
|
|
3
5
|
fix: boolean;
|
|
4
6
|
rules?: string[];
|
|
7
|
+
files?: string[];
|
|
5
8
|
extraArgs: string[];
|
|
6
9
|
}
|
|
7
10
|
export declare function lint(filter: string | undefined, options: Partial<LintOptions>): Promise<void>;
|
package/dist/commands/lint.js
CHANGED
|
@@ -3,23 +3,88 @@ import { execa } from "execa";
|
|
|
3
3
|
import { globSync } from "glob";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { cliError } from "../error.js";
|
|
6
|
-
import { getRootDir, readConfig } from "../mops.js";
|
|
6
|
+
import { formatDir, formatGithubDir, getDependencyType, getRootDir, readConfig, } from "../mops.js";
|
|
7
|
+
import { resolvePackages } from "../resolve-packages.js";
|
|
7
8
|
import { toolchain } from "./toolchain/index.js";
|
|
8
9
|
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
9
10
|
import { existsSync } from "node:fs";
|
|
11
|
+
async function resolveDepRules(config, rootDir) {
|
|
12
|
+
const ext = config.lint?.extends;
|
|
13
|
+
if (!ext) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const resolvedPackages = await resolvePackages();
|
|
17
|
+
const rules = [];
|
|
18
|
+
const matched = new Set();
|
|
19
|
+
const hasRules = new Set();
|
|
20
|
+
for (const [name, version] of Object.entries(resolvedPackages)) {
|
|
21
|
+
if (ext !== true && !ext.includes(name)) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
matched.add(name);
|
|
25
|
+
const depType = getDependencyType(version);
|
|
26
|
+
let pkgDir;
|
|
27
|
+
if (depType === "local") {
|
|
28
|
+
pkgDir = version;
|
|
29
|
+
}
|
|
30
|
+
else if (depType === "github") {
|
|
31
|
+
pkgDir = formatGithubDir(name, version);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
pkgDir = formatDir(name, version);
|
|
35
|
+
}
|
|
36
|
+
const rulesDir = path.join(pkgDir, "rules");
|
|
37
|
+
if (existsSync(rulesDir)) {
|
|
38
|
+
rules.push(path.relative(rootDir, rulesDir));
|
|
39
|
+
hasRules.add(name);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(ext)) {
|
|
43
|
+
const unresolved = ext.filter((n) => !matched.has(n));
|
|
44
|
+
if (unresolved.length > 0) {
|
|
45
|
+
console.warn(chalk.yellow(`[lint] extends: package(s) not found in dependencies: ${unresolved.join(", ")}`));
|
|
46
|
+
}
|
|
47
|
+
const noRulesDir = ext.filter((n) => matched.has(n) && !hasRules.has(n));
|
|
48
|
+
if (noRulesDir.length > 0) {
|
|
49
|
+
console.warn(chalk.yellow(`[lint] extends: package(s) have no rules/ directory: ${noRulesDir.join(", ")}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return rules;
|
|
53
|
+
}
|
|
54
|
+
export async function collectLintRules(config, rootDir) {
|
|
55
|
+
const configRules = config.lint?.rules ?? [];
|
|
56
|
+
for (const d of configRules) {
|
|
57
|
+
if (!existsSync(path.join(rootDir, d))) {
|
|
58
|
+
cliError(`[lint] rules: directory '${d}' not found. Check your mops.toml [lint] config.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const localRules = configRules.length > 0
|
|
62
|
+
? configRules
|
|
63
|
+
: ["lint", "lints"].filter((d) => existsSync(path.join(rootDir, d)));
|
|
64
|
+
const depRules = await resolveDepRules(config, rootDir);
|
|
65
|
+
return [...localRules, ...depRules];
|
|
66
|
+
}
|
|
10
67
|
export async function lint(filter, options) {
|
|
11
68
|
let config = readConfig();
|
|
12
69
|
let rootDir = getRootDir();
|
|
13
70
|
let lintokoBinPath = config.toolchain?.lintoko
|
|
14
71
|
? await toolchain.bin("lintoko")
|
|
15
72
|
: "lintoko";
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
73
|
+
let filesToLint;
|
|
74
|
+
if (options.files && options.files.length > 0) {
|
|
75
|
+
filesToLint = options.files;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
let globStr = filter ? `**/*${filter}*.mo` : "**/*.mo";
|
|
79
|
+
filesToLint = globSync(path.join(rootDir, globStr), {
|
|
80
|
+
...MOTOKO_GLOB_CONFIG,
|
|
81
|
+
cwd: rootDir,
|
|
82
|
+
});
|
|
83
|
+
if (filesToLint.length === 0) {
|
|
84
|
+
cliError(filter
|
|
85
|
+
? `No files found for filter '${filter}'`
|
|
86
|
+
: "No .mo files found in the project");
|
|
87
|
+
}
|
|
23
88
|
}
|
|
24
89
|
let args = [];
|
|
25
90
|
if (options.verbose) {
|
|
@@ -28,9 +93,9 @@ export async function lint(filter, options) {
|
|
|
28
93
|
if (options.fix) {
|
|
29
94
|
args.push("--fix");
|
|
30
95
|
}
|
|
31
|
-
const rules = options.rules
|
|
96
|
+
const rules = options.rules !== undefined
|
|
32
97
|
? options.rules
|
|
33
|
-
:
|
|
98
|
+
: await collectLintRules(config, rootDir);
|
|
34
99
|
rules.forEach((rule) => args.push("--rules", rule));
|
|
35
100
|
if (config.lint?.args) {
|
|
36
101
|
if (typeof config.lint.args === "string") {
|
package/dist/commands/publish.js
CHANGED
|
@@ -210,6 +210,7 @@ export async function publish(options = {}) {
|
|
|
210
210
|
"README.md",
|
|
211
211
|
"LICENSE",
|
|
212
212
|
"NOTICE",
|
|
213
|
+
"rules/*.toml",
|
|
213
214
|
"!.mops/**",
|
|
214
215
|
"!test/**",
|
|
215
216
|
"!tests/**",
|
|
@@ -261,6 +262,13 @@ export async function publish(options = {}) {
|
|
|
261
262
|
process.exit(1);
|
|
262
263
|
}
|
|
263
264
|
}
|
|
265
|
+
// pre-flight file count check (must match MAX_PACKAGE_FILES in PackagePublisher.mo)
|
|
266
|
+
const FILE_LIMIT = 1000;
|
|
267
|
+
if (files.length > FILE_LIMIT) {
|
|
268
|
+
console.log(chalk.red("Error: ") +
|
|
269
|
+
`Too many files (${files.length}). Maximum is ${FILE_LIMIT}.`);
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
264
272
|
// parse changelog
|
|
265
273
|
console.log("Parsing CHANGELOG.md...");
|
|
266
274
|
let changelog = parseChangelog(config.package.version);
|
|
@@ -316,25 +324,25 @@ export async function publish(options = {}) {
|
|
|
316
324
|
console.log(chalk.red("Error: ") + publishing.err);
|
|
317
325
|
process.exit(1);
|
|
318
326
|
}
|
|
319
|
-
let
|
|
327
|
+
let publishingId = publishing.ok;
|
|
320
328
|
// upload test stats
|
|
321
329
|
if (options.test) {
|
|
322
|
-
await actor.uploadTestStats(
|
|
330
|
+
await actor.uploadTestStats(publishingId, {
|
|
323
331
|
passed: BigInt(reporter.passed),
|
|
324
332
|
passedNames: reporter.passedNamesFlat,
|
|
325
333
|
});
|
|
326
334
|
}
|
|
327
335
|
// upload benchmarks
|
|
328
336
|
if (options.bench) {
|
|
329
|
-
await actor.uploadBenchmarks(
|
|
337
|
+
await actor.uploadBenchmarks(publishingId, benchmarks);
|
|
330
338
|
}
|
|
331
339
|
// upload changelog
|
|
332
340
|
if (changelog) {
|
|
333
|
-
await actor.uploadNotes(
|
|
341
|
+
await actor.uploadNotes(publishingId, changelog);
|
|
334
342
|
}
|
|
335
343
|
// upload docs coverage
|
|
336
344
|
if (options.docs) {
|
|
337
|
-
await actor.uploadDocsCoverage(
|
|
345
|
+
await actor.uploadDocsCoverage(publishingId, docsCov);
|
|
338
346
|
}
|
|
339
347
|
// upload files
|
|
340
348
|
await parallel(8, files, async (file) => {
|
|
@@ -347,7 +355,7 @@ export async function publish(options = {}) {
|
|
|
347
355
|
if (file === docsFile) {
|
|
348
356
|
file = path.basename(file);
|
|
349
357
|
}
|
|
350
|
-
let res = await actor.startFileUpload(
|
|
358
|
+
let res = await actor.startFileUpload(publishingId, file, BigInt(chunkCount), firstChunk);
|
|
351
359
|
if ("err" in res) {
|
|
352
360
|
console.log(chalk.red("Error: ") + res.err);
|
|
353
361
|
process.exit(1);
|
|
@@ -356,7 +364,7 @@ export async function publish(options = {}) {
|
|
|
356
364
|
for (let i = 1; i < chunkCount; i++) {
|
|
357
365
|
let start = i * chunkSize;
|
|
358
366
|
let chunk = Array.from(content.slice(start, start + chunkSize));
|
|
359
|
-
let res = await actor.uploadFileChunk(
|
|
367
|
+
let res = await actor.uploadFileChunk(publishingId, fileId, BigInt(i), chunk);
|
|
360
368
|
if ("err" in res) {
|
|
361
369
|
console.log(chalk.red("Error: ") + res.err);
|
|
362
370
|
process.exit(1);
|
|
@@ -370,7 +378,7 @@ export async function publish(options = {}) {
|
|
|
370
378
|
// finish
|
|
371
379
|
progress();
|
|
372
380
|
logUpdate.done();
|
|
373
|
-
let res = await actor.finishPublish(
|
|
381
|
+
let res = await actor.finishPublish(publishingId);
|
|
374
382
|
if ("err" in res) {
|
|
375
383
|
console.log(chalk.red("Error: ") + res.err);
|
|
376
384
|
process.exit(1);
|
|
@@ -402,14 +410,14 @@ function parseChangelog(version) {
|
|
|
402
410
|
async function fetchGitHubReleaseNotes(repo, version) {
|
|
403
411
|
let repoPath = new URL(repo).pathname;
|
|
404
412
|
let res = await fetch(`https://api.github.com/repos${repoPath}/releases/tags/${version}`);
|
|
405
|
-
let release = await res.json();
|
|
413
|
+
let release = (await res.json());
|
|
406
414
|
if (release.message === "Not Found") {
|
|
407
415
|
res = await fetch(`https://api.github.com/repos${repoPath}/releases/tags/v${version}`);
|
|
408
|
-
release = await res.json();
|
|
416
|
+
release = (await res.json());
|
|
409
417
|
if (release.message === "Not Found") {
|
|
410
418
|
console.log(chalk.yellow(`No GitHub release found with name ${version} or v${version}`));
|
|
411
419
|
return "";
|
|
412
420
|
}
|
|
413
421
|
}
|
|
414
|
-
return release.body;
|
|
422
|
+
return release.body ?? "";
|
|
415
423
|
}
|
package/dist/commands/remove.js
CHANGED
|
@@ -42,7 +42,10 @@ export async function remove(name, { dev = false, verbose = false, dryRun = fals
|
|
|
42
42
|
let config = readConfig(configFile);
|
|
43
43
|
let deps = Object.values(config.dependencies || {})
|
|
44
44
|
.map((dep) => {
|
|
45
|
-
return [
|
|
45
|
+
return [
|
|
46
|
+
dep,
|
|
47
|
+
...getTransitiveDependenciesOf(dep.name, dep.version, dep.repo),
|
|
48
|
+
];
|
|
46
49
|
})
|
|
47
50
|
.flat();
|
|
48
51
|
return deps;
|
|
@@ -65,7 +68,7 @@ export async function remove(name, { dev = false, verbose = false, dryRun = fals
|
|
|
65
68
|
// transitive deps of this package (including itself)
|
|
66
69
|
let transitiveDepsOfPackage = [
|
|
67
70
|
pkgDetails,
|
|
68
|
-
...getTransitiveDependenciesOf(name, version),
|
|
71
|
+
...getTransitiveDependenciesOf(name, version, pkgDetails.repo),
|
|
69
72
|
];
|
|
70
73
|
// remove local cache
|
|
71
74
|
for (let dep of transitiveDepsOfPackage) {
|
package/dist/commands/self.js
CHANGED
|
@@ -27,7 +27,7 @@ function detectPackageManager() {
|
|
|
27
27
|
}
|
|
28
28
|
export async function getLatestVersion() {
|
|
29
29
|
let res = await fetch(url + "/tags/latest");
|
|
30
|
-
return res.text();
|
|
30
|
+
return (await res.text()).trim();
|
|
31
31
|
}
|
|
32
32
|
export async function update() {
|
|
33
33
|
let latest = await getLatestVersion();
|
package/dist/commands/sources.js
CHANGED
|
@@ -27,8 +27,9 @@ export async function sourcesArgs({ conflicts = "ignore", cwd = process.cwd(), }
|
|
|
27
27
|
}
|
|
28
28
|
// append baseDir
|
|
29
29
|
let pkgBaseDir;
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
let resolvedMopsToml = path.resolve(cwd, pkgDir, "mops.toml");
|
|
31
|
+
if (fs.existsSync(resolvedMopsToml)) {
|
|
32
|
+
let config = readConfig(resolvedMopsToml);
|
|
32
33
|
pkgBaseDir = path.join(pkgDir, config.package?.baseDir || "src");
|
|
33
34
|
}
|
|
34
35
|
else {
|
package/dist/commands/sync.js
CHANGED
|
@@ -8,6 +8,7 @@ import { remove } from "./remove.js";
|
|
|
8
8
|
import { checkIntegrity } from "../integrity.js";
|
|
9
9
|
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
10
10
|
import { MOTOKO_IGNORE_PATTERNS } from "../constants.js";
|
|
11
|
+
import { getDepName } from "../helpers/get-dep-name.js";
|
|
11
12
|
export async function sync({ lock } = {}) {
|
|
12
13
|
if (!checkConfigFile()) {
|
|
13
14
|
return;
|
|
@@ -58,25 +59,19 @@ async function getUsedPackages() {
|
|
|
58
59
|
}
|
|
59
60
|
async function getMissingPackages() {
|
|
60
61
|
let config = readConfig();
|
|
61
|
-
let
|
|
62
|
+
let allDepNames = new Set([
|
|
62
63
|
...Object.keys(config.dependencies || {}),
|
|
63
64
|
...Object.keys(config["dev-dependencies"] || {}),
|
|
64
|
-
];
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
missing.delete(pkg);
|
|
68
|
-
}
|
|
69
|
-
return [...missing];
|
|
65
|
+
].map((key) => getDepName(key)));
|
|
66
|
+
let used = await getUsedPackages();
|
|
67
|
+
return used.filter((pkg) => !allDepNames.has(pkg));
|
|
70
68
|
}
|
|
71
69
|
async function getUnusedPackages() {
|
|
72
70
|
let config = readConfig();
|
|
73
|
-
let allDeps =
|
|
71
|
+
let allDeps = [
|
|
74
72
|
...Object.keys(config.dependencies || {}),
|
|
75
73
|
...Object.keys(config["dev-dependencies"] || {}),
|
|
76
|
-
]
|
|
77
|
-
let used = await getUsedPackages();
|
|
78
|
-
|
|
79
|
-
allDeps.delete(pkg);
|
|
80
|
-
}
|
|
81
|
-
return [...allDeps];
|
|
74
|
+
];
|
|
75
|
+
let used = new Set(await getUsedPackages());
|
|
76
|
+
return allDeps.filter((key) => !used.has(getDepName(key)));
|
|
82
77
|
}
|
|
@@ -9,7 +9,7 @@ import { globSync } from "glob";
|
|
|
9
9
|
import chokidar from "chokidar";
|
|
10
10
|
import debounce from "debounce";
|
|
11
11
|
import { SemVer } from "semver";
|
|
12
|
-
import {
|
|
12
|
+
import { sourcesArgs } from "../sources.js";
|
|
13
13
|
import { getGlobalMocArgs, getRootDir, readConfig } from "../../mops.js";
|
|
14
14
|
import { parallel } from "../../parallel.js";
|
|
15
15
|
import { MMF1 } from "./mmf1.js";
|
|
@@ -151,7 +151,7 @@ export async function testWithReporter(reporterName, filter = "", defaultMode =
|
|
|
151
151
|
}
|
|
152
152
|
reporter.addFiles(files);
|
|
153
153
|
let config = readConfig();
|
|
154
|
-
let sourcesArr = await
|
|
154
|
+
let sourcesArr = (await sourcesArgs()).flat();
|
|
155
155
|
let globalMocArgs = getGlobalMocArgs(config);
|
|
156
156
|
if (!mocPath) {
|
|
157
157
|
mocPath = await toolchain.bin("moc", { fallback: true });
|
|
@@ -197,7 +197,7 @@ export async function testWithReporter(reporterName, filter = "", defaultMode =
|
|
|
197
197
|
let mocArgs = [
|
|
198
198
|
"--hide-warnings",
|
|
199
199
|
"--error-detail=2",
|
|
200
|
-
...sourcesArr
|
|
200
|
+
...sourcesArr,
|
|
201
201
|
...globalMocArgs,
|
|
202
202
|
file,
|
|
203
203
|
].filter((x) => x);
|
package/dist/commands/update.js
CHANGED
|
@@ -25,9 +25,14 @@ export async function update(pkg, { lock } = {}) {
|
|
|
25
25
|
for (let dep of githubDeps) {
|
|
26
26
|
let { org, gitName, branch, commitHash } = parseGithubURL(dep.repo || "");
|
|
27
27
|
let dev = !!config["dev-dependencies"]?.[dep.name];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
try {
|
|
29
|
+
let commit = await getGithubCommit(`${org}/${gitName}`, branch);
|
|
30
|
+
if (commit.sha !== commitHash) {
|
|
31
|
+
await add(`https://github.com/${org}/${gitName}#${branch}@${commit.sha}`, { dev, lock }, dep.name);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.log(chalk.red("Error: ") + `Failed to update ${dep.name}: ${err.message}`);
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
// update mops packages
|
|
@@ -58,7 +63,7 @@ export async function update(pkg, { lock } = {}) {
|
|
|
58
63
|
return (getDepName(d) === dep[0] &&
|
|
59
64
|
(!pinnedVersion || dep[1].startsWith(pinnedVersion)));
|
|
60
65
|
}) || dep[0];
|
|
61
|
-
await add(`${dep[0]}@${dep[2]}`, { dev }, asName);
|
|
66
|
+
await add(`${dep[0]}@${dep[2]}`, { dev, lock }, asName);
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
await checkIntegrity(lock);
|
|
@@ -4,7 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { getMocPath } from "../../helpers/get-moc-path.js";
|
|
6
6
|
import { getGlobalMocArgs, getRootDir, readConfig } from "../../mops.js";
|
|
7
|
-
import {
|
|
7
|
+
import { sourcesArgs } from "../sources.js";
|
|
8
8
|
import { parallel } from "../../parallel.js";
|
|
9
9
|
import { globMoFiles } from "./globMoFiles.js";
|
|
10
10
|
export class ErrorChecker {
|
|
@@ -30,19 +30,14 @@ export class ErrorChecker {
|
|
|
30
30
|
onProgress();
|
|
31
31
|
let rootDir = getRootDir();
|
|
32
32
|
let mocPath = getMocPath();
|
|
33
|
-
let deps = await
|
|
33
|
+
let deps = (await sourcesArgs({ cwd: rootDir })).flat();
|
|
34
34
|
let globalMocArgs = getGlobalMocArgs(readConfig());
|
|
35
35
|
let paths = globMoFiles(rootDir);
|
|
36
36
|
this.totalFiles = paths.length;
|
|
37
37
|
this.processedFiles = 0;
|
|
38
38
|
await parallel(os.cpus().length, paths, async (file) => {
|
|
39
39
|
try {
|
|
40
|
-
await promisify(execFile)(mocPath, [
|
|
41
|
-
"--check",
|
|
42
|
-
...deps.flatMap((x) => x.split(" ")),
|
|
43
|
-
...globalMocArgs,
|
|
44
|
-
file,
|
|
45
|
-
], { cwd: rootDir });
|
|
40
|
+
await promisify(execFile)(mocPath, ["--check", ...deps, ...globalMocArgs, file], { cwd: rootDir });
|
|
46
41
|
}
|
|
47
42
|
catch (error) {
|
|
48
43
|
error.message.split("\n").forEach((line) => {
|