ic-mops 2.9.0 → 2.11.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/bundle/cli.tgz +0 -0
- package/cli.ts +34 -10
- package/commands/build.ts +16 -22
- package/commands/check-stable.ts +141 -17
- package/commands/check.ts +195 -101
- package/commands/migrate.ts +165 -0
- package/declarations/main/main.did +38 -0
- package/declarations/main/main.did.d.ts +36 -0
- package/declarations/main/main.did.js +36 -0
- package/dist/cli.js +28 -10
- package/dist/commands/build.js +7 -13
- package/dist/commands/check-stable.d.ts +8 -1
- package/dist/commands/check-stable.js +101 -19
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/check.js +136 -78
- package/dist/commands/migrate.d.ts +2 -0
- package/dist/commands/migrate.js +104 -0
- package/dist/declarations/main/main.did +38 -0
- package/dist/declarations/main/main.did.d.ts +36 -0
- package/dist/declarations/main/main.did.js +36 -0
- package/dist/helpers/migrations.d.ts +10 -0
- package/dist/helpers/migrations.js +109 -0
- package/dist/helpers/resolve-canisters.d.ts +3 -1
- package/dist/helpers/resolve-canisters.js +34 -5
- package/dist/package.json +1 -1
- package/dist/tests/check-stable.test.js +18 -0
- package/dist/tests/check.test.js +23 -5
- package/dist/tests/migrate.test.d.ts +1 -0
- package/dist/tests/migrate.test.js +160 -0
- package/dist/types.d.ts +7 -0
- package/helpers/migrations.ts +166 -0
- package/helpers/resolve-canisters.ts +53 -5
- package/package.json +1 -1
- package/tests/__snapshots__/check.test.ts.snap +2 -2
- package/tests/__snapshots__/migrate.test.ts.snap +119 -0
- package/tests/check/canisters-canister-args/Warning.mo +5 -0
- package/tests/check/canisters-canister-args/mops.toml +9 -0
- package/tests/check-stable/canister-args/migrations/20250101_000000_Init.mo +8 -0
- package/tests/check-stable/canister-args/migrations/20250201_000000_AddField.mo +9 -0
- package/tests/check-stable/canister-args/mops.toml +9 -0
- package/tests/check-stable/canister-args/old.most +8 -0
- package/tests/check-stable/canister-args/src/main.mo +11 -0
- package/tests/check-stable.test.ts +21 -0
- package/tests/check.test.ts +26 -5
- package/tests/migrate/basic/deployed.most +12 -0
- package/tests/migrate/basic/migrations/20250101_000000_Init.mo +5 -0
- package/tests/migrate/basic/migrations/20250201_000000_AddName.mo +5 -0
- package/tests/migrate/basic/migrations/20250301_000000_AddEmail.mo +9 -0
- package/tests/migrate/basic/mops.toml +15 -0
- package/tests/migrate/basic/next-migration/.gitkeep +0 -0
- package/tests/migrate/basic/src/main.mo +11 -0
- package/tests/migrate/with-next/deployed.most +12 -0
- package/tests/migrate/with-next/migrations/20250101_000000_Init.mo +5 -0
- package/tests/migrate/with-next/migrations/20250201_000000_AddName.mo +5 -0
- package/tests/migrate/with-next/migrations/20250301_000000_AddEmail.mo +9 -0
- package/tests/migrate/with-next/mops.toml +15 -0
- package/tests/migrate/with-next/next-migration/20250401_000000_RenameId.mo +9 -0
- package/tests/migrate/with-next/src/main.mo +11 -0
- package/tests/migrate.test.ts +228 -0
- package/types.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## Next
|
|
4
4
|
|
|
5
|
+
## 2.11.0
|
|
6
|
+
- Add `mops migrate new <Name>` and `mops migrate freeze` commands for managing enhanced migration chains
|
|
7
|
+
- Add `[canisters.<name>.migrations]` config section with `chain`, `next`, `check-limit`, and `build-limit` fields
|
|
8
|
+
- `mops check`, `mops build`, and `mops check-stable` now auto-inject `--enhanced-migration` when `[migrations]` is configured
|
|
9
|
+
- `mops check` and `mops check-stable` emit a hint to create a migration when a stable compatibility check fails and `[migrations]` is configured
|
|
10
|
+
- Migration chain trimming: only the last N migrations are passed to `moc` based on `check-limit`/`build-limit` settings
|
|
11
|
+
|
|
12
|
+
## 2.10.0
|
|
13
|
+
- `mops check` and `mops check-stable` now apply per-canister `[canisters.<name>].args` (previously only `mops build` applied them)
|
|
14
|
+
- `mops check` now accepts canister names as arguments (e.g. `mops check backend`) to check a specific canister
|
|
15
|
+
- `mops check-stable` now works without arguments, checking all canisters with `[check-stable]` configured
|
|
16
|
+
- `mops check-stable` now accepts canister names as arguments (e.g. `mops check-stable backend`)
|
|
17
|
+
|
|
5
18
|
## 2.9.0
|
|
6
19
|
- Add `mops info <pkg>` command to show detailed package metadata from the registry
|
|
7
20
|
- Add `[lint.extra]` config for applying additional lint rules to specific files via glob patterns
|
package/bundle/cli.tgz
CHANGED
|
Binary file
|
package/cli.ts
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
importPem,
|
|
44
44
|
setUserProp,
|
|
45
45
|
} from "./commands/user.js";
|
|
46
|
+
import { migrateNew, migrateFreeze } from "./commands/migrate.js";
|
|
46
47
|
import { watch } from "./commands/watch/watch.js";
|
|
47
48
|
import {
|
|
48
49
|
apiVersion,
|
|
@@ -330,9 +331,9 @@ program
|
|
|
330
331
|
|
|
331
332
|
// check
|
|
332
333
|
program
|
|
333
|
-
.command("check [
|
|
334
|
+
.command("check [args...]")
|
|
334
335
|
.description(
|
|
335
|
-
"Check Motoko files for syntax errors and type issues. If no
|
|
336
|
+
"Check Motoko canisters or files for syntax errors and type issues. Arguments can be canister names or file paths. If no arguments are given, checks all canisters from mops.toml. Also runs stable compatibility checks for canisters with [check-stable] configured, and runs linting if lintoko is configured in [toolchain]",
|
|
336
337
|
)
|
|
337
338
|
.option("--verbose", "Verbose console output")
|
|
338
339
|
.addOption(
|
|
@@ -342,15 +343,15 @@ program
|
|
|
342
343
|
),
|
|
343
344
|
)
|
|
344
345
|
.allowUnknownOption(true)
|
|
345
|
-
.action(async (
|
|
346
|
+
.action(async (args, options) => {
|
|
346
347
|
checkConfigFile(true);
|
|
347
|
-
const { extraArgs, args:
|
|
348
|
+
const { extraArgs, args: argList } = parseExtraArgs(args);
|
|
348
349
|
await installAll({
|
|
349
350
|
silent: true,
|
|
350
351
|
lock: "ignore",
|
|
351
352
|
installFromLockFile: true,
|
|
352
353
|
});
|
|
353
|
-
await check(
|
|
354
|
+
await check(argList, {
|
|
354
355
|
...options,
|
|
355
356
|
extraArgs,
|
|
356
357
|
});
|
|
@@ -372,21 +373,21 @@ program
|
|
|
372
373
|
|
|
373
374
|
// check-stable
|
|
374
375
|
program
|
|
375
|
-
.command("check-stable
|
|
376
|
+
.command("check-stable [args...]")
|
|
376
377
|
.description(
|
|
377
|
-
"Check stable variable compatibility
|
|
378
|
+
"Check stable variable compatibility. With no arguments, checks all canisters with [check-stable] configured. Arguments can be canister names or an old file path followed by an optional canister name",
|
|
378
379
|
)
|
|
379
380
|
.option("--verbose", "Verbose console output")
|
|
380
381
|
.allowUnknownOption(true)
|
|
381
|
-
.action(async (
|
|
382
|
+
.action(async (args, options) => {
|
|
382
383
|
checkConfigFile(true);
|
|
383
|
-
const { extraArgs } = parseExtraArgs();
|
|
384
|
+
const { extraArgs, args: argList } = parseExtraArgs(args);
|
|
384
385
|
await installAll({
|
|
385
386
|
silent: true,
|
|
386
387
|
lock: "ignore",
|
|
387
388
|
installFromLockFile: true,
|
|
388
389
|
});
|
|
389
|
-
await checkStable(
|
|
390
|
+
await checkStable(argList, {
|
|
390
391
|
...options,
|
|
391
392
|
extraArgs,
|
|
392
393
|
});
|
|
@@ -707,6 +708,29 @@ toolchainCommand
|
|
|
707
708
|
|
|
708
709
|
program.addCommand(toolchainCommand);
|
|
709
710
|
|
|
711
|
+
// migrate
|
|
712
|
+
const migrateCommand = new Command("migrate").description(
|
|
713
|
+
"Manage enhanced migration chains",
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
migrateCommand
|
|
717
|
+
.command("new <name> [canister]")
|
|
718
|
+
.description("Create a new migration file in the next-migration directory")
|
|
719
|
+
.action(async (name, canister) => {
|
|
720
|
+
checkConfigFile(true);
|
|
721
|
+
await migrateNew(name, canister);
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
migrateCommand
|
|
725
|
+
.command("freeze [canister]")
|
|
726
|
+
.description("Move the next migration into the frozen chain")
|
|
727
|
+
.action(async (canister) => {
|
|
728
|
+
checkConfigFile(true);
|
|
729
|
+
await migrateFreeze(canister);
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
program.addCommand(migrateCommand);
|
|
733
|
+
|
|
710
734
|
// self
|
|
711
735
|
const selfCommand = new Command("self").description("Mops CLI management");
|
|
712
736
|
|
package/commands/build.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { join } from "node:path";
|
|
|
6
6
|
import { lock, unlockSync } from "proper-lockfile";
|
|
7
7
|
import { cliError } from "../error.js";
|
|
8
8
|
import { isCandidCompatible } from "../helpers/is-candid-compatible.js";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
filterCanisters,
|
|
11
|
+
resolveCanisterConfigs,
|
|
12
|
+
validateCanisterArgs,
|
|
13
|
+
} from "../helpers/resolve-canisters.js";
|
|
14
|
+
import { prepareMigrationArgs } from "../helpers/migrations.js";
|
|
10
15
|
import { CanisterConfig, Config } from "../types.js";
|
|
11
16
|
import { CustomSection, getWasmBindings } from "../wasm.js";
|
|
12
17
|
import { getGlobalMocArgs, readConfig, resolveConfigPath } from "../mops.js";
|
|
@@ -41,26 +46,11 @@ export async function build(
|
|
|
41
46
|
cliError(`No Motoko canisters found in mops.toml configuration`);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
if (canisterNames) {
|
|
45
|
-
let invalidNames = canisterNames.filter((name) => !(name in canisters));
|
|
46
|
-
if (invalidNames.length) {
|
|
47
|
-
cliError(
|
|
48
|
-
`Motoko canister(s) not found in mops.toml configuration: ${invalidNames.join(", ")}`,
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
49
|
if (!(await exists(outputDir))) {
|
|
54
50
|
await mkdir(outputDir, { recursive: true });
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
const filteredCanisters = canisterNames
|
|
58
|
-
? Object.fromEntries(
|
|
59
|
-
Object.entries(canisters).filter(([name]) =>
|
|
60
|
-
canisterNames.includes(name),
|
|
61
|
-
),
|
|
62
|
-
)
|
|
63
|
-
: canisters;
|
|
53
|
+
const filteredCanisters = filterCanisters(canisters, canisterNames);
|
|
64
54
|
|
|
65
55
|
for (let [canisterName, canister] of Object.entries(filteredCanisters)) {
|
|
66
56
|
console.log(chalk.blue("build canister"), chalk.bold(canisterName));
|
|
@@ -98,6 +88,12 @@ export async function build(
|
|
|
98
88
|
};
|
|
99
89
|
process.on("exit", exitCleanup);
|
|
100
90
|
|
|
91
|
+
const migration = await prepareMigrationArgs(
|
|
92
|
+
canister.migrations,
|
|
93
|
+
canisterName,
|
|
94
|
+
"build",
|
|
95
|
+
options.verbose,
|
|
96
|
+
);
|
|
101
97
|
try {
|
|
102
98
|
let args = [
|
|
103
99
|
"-c",
|
|
@@ -108,6 +104,7 @@ export async function build(
|
|
|
108
104
|
motokoPath,
|
|
109
105
|
...(await sourcesArgs()).flat(),
|
|
110
106
|
...getGlobalMocArgs(config),
|
|
107
|
+
...migration.migrationArgs,
|
|
111
108
|
];
|
|
112
109
|
args.push(
|
|
113
110
|
...collectExtraArgs(config, canister, canisterName, options.extraArgs),
|
|
@@ -210,6 +207,7 @@ export async function build(
|
|
|
210
207
|
);
|
|
211
208
|
}
|
|
212
209
|
} finally {
|
|
210
|
+
await migration.cleanup();
|
|
213
211
|
process.removeListener("exit", exitCleanup);
|
|
214
212
|
try {
|
|
215
213
|
await release?.();
|
|
@@ -249,11 +247,7 @@ function collectExtraArgs(
|
|
|
249
247
|
args.push(...config.build.args);
|
|
250
248
|
}
|
|
251
249
|
if (canister.args) {
|
|
252
|
-
|
|
253
|
-
cliError(
|
|
254
|
-
`Canister config 'args' should be an array of strings for canister ${canisterName}`,
|
|
255
|
-
);
|
|
256
|
-
}
|
|
250
|
+
validateCanisterArgs(canister, canisterName, config);
|
|
257
251
|
args.push(...canister.args);
|
|
258
252
|
}
|
|
259
253
|
if (extraArgs) {
|
package/commands/check-stable.ts
CHANGED
|
@@ -4,8 +4,16 @@ import { rm } from "node:fs/promises";
|
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { execa } from "execa";
|
|
6
6
|
import { cliError } from "../error.js";
|
|
7
|
+
import { prepareMigrationArgs } from "../helpers/migrations.js";
|
|
7
8
|
import { getGlobalMocArgs, readConfig, resolveConfigPath } from "../mops.js";
|
|
8
|
-
import {
|
|
9
|
+
import { CanisterConfig } from "../types.js";
|
|
10
|
+
import {
|
|
11
|
+
filterCanisters,
|
|
12
|
+
looksLikeFile,
|
|
13
|
+
resolveCanisterConfigs,
|
|
14
|
+
resolveSingleCanister,
|
|
15
|
+
validateCanisterArgs,
|
|
16
|
+
} from "../helpers/resolve-canisters.js";
|
|
9
17
|
import { sourcesArgs } from "./sources.js";
|
|
10
18
|
import { toolchain } from "./toolchain/index.js";
|
|
11
19
|
|
|
@@ -16,29 +24,130 @@ export interface CheckStableOptions {
|
|
|
16
24
|
extraArgs: string[];
|
|
17
25
|
}
|
|
18
26
|
|
|
27
|
+
export function resolveStablePath(
|
|
28
|
+
canister: CanisterConfig,
|
|
29
|
+
canisterName: string,
|
|
30
|
+
options?: { required?: boolean },
|
|
31
|
+
): string | null {
|
|
32
|
+
const stableConfig = canister["check-stable"];
|
|
33
|
+
if (!stableConfig) {
|
|
34
|
+
if (options?.required) {
|
|
35
|
+
cliError(
|
|
36
|
+
`Canister '${canisterName}' has no [canisters.${canisterName}.check-stable] configuration in mops.toml`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const stablePath = resolveConfigPath(stableConfig.path);
|
|
42
|
+
if (!existsSync(stablePath)) {
|
|
43
|
+
if (stableConfig.skipIfMissing) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
cliError(
|
|
47
|
+
`Deployed file not found: ${stablePath} (canister '${canisterName}')\n` +
|
|
48
|
+
"Set skipIfMissing = true in [canisters." +
|
|
49
|
+
canisterName +
|
|
50
|
+
".check-stable] to skip this check when the file is missing.",
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return stablePath;
|
|
54
|
+
}
|
|
55
|
+
|
|
19
56
|
export async function checkStable(
|
|
20
|
-
|
|
21
|
-
canisterName: string | undefined,
|
|
57
|
+
args: string[],
|
|
22
58
|
options: Partial<CheckStableOptions> = {},
|
|
23
59
|
): Promise<void> {
|
|
24
60
|
const config = readConfig();
|
|
25
|
-
const
|
|
61
|
+
const mocPath = await toolchain.bin("moc", { fallback: true });
|
|
62
|
+
const globalMocArgs = getGlobalMocArgs(config);
|
|
63
|
+
|
|
64
|
+
const firstArg = args[0];
|
|
65
|
+
if (firstArg && looksLikeFile(firstArg)) {
|
|
66
|
+
const oldFile = firstArg;
|
|
67
|
+
const canisterName = args[1];
|
|
68
|
+
const { name, canister } = resolveSingleCanister(config, canisterName);
|
|
69
|
+
|
|
70
|
+
if (!canister.main) {
|
|
71
|
+
cliError(`No main file specified for canister '${name}' in mops.toml`);
|
|
72
|
+
}
|
|
26
73
|
|
|
27
|
-
|
|
28
|
-
|
|
74
|
+
validateCanisterArgs(canister, name, config);
|
|
75
|
+
|
|
76
|
+
const migration = await prepareMigrationArgs(
|
|
77
|
+
canister.migrations,
|
|
78
|
+
name,
|
|
79
|
+
"check",
|
|
80
|
+
options.verbose,
|
|
81
|
+
);
|
|
82
|
+
try {
|
|
83
|
+
await runStableCheck({
|
|
84
|
+
oldFile,
|
|
85
|
+
canisterMain: resolveConfigPath(canister.main),
|
|
86
|
+
canisterName: name,
|
|
87
|
+
mocPath,
|
|
88
|
+
globalMocArgs,
|
|
89
|
+
canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
|
|
90
|
+
options,
|
|
91
|
+
hasMigrations: !!canister.migrations,
|
|
92
|
+
});
|
|
93
|
+
} finally {
|
|
94
|
+
await migration.cleanup();
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
29
97
|
}
|
|
30
98
|
|
|
31
|
-
const
|
|
32
|
-
const
|
|
99
|
+
const canisters = resolveCanisterConfigs(config);
|
|
100
|
+
const canisterNames = args.length > 0 ? args : undefined;
|
|
101
|
+
const filteredCanisters = filterCanisters(canisters, canisterNames);
|
|
102
|
+
const sources = (await sourcesArgs()).flat();
|
|
33
103
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
104
|
+
let checked = 0;
|
|
105
|
+
for (const [name, canister] of Object.entries(filteredCanisters)) {
|
|
106
|
+
if (!canister.main) {
|
|
107
|
+
cliError(`No main file specified for canister '${name}' in mops.toml`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
validateCanisterArgs(canister, name, config);
|
|
111
|
+
const stablePath = resolveStablePath(canister, name, {
|
|
112
|
+
required: !!canisterNames,
|
|
113
|
+
});
|
|
114
|
+
if (!stablePath) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const migration = await prepareMigrationArgs(
|
|
119
|
+
canister.migrations,
|
|
120
|
+
name,
|
|
121
|
+
"check",
|
|
122
|
+
options.verbose,
|
|
123
|
+
);
|
|
124
|
+
try {
|
|
125
|
+
await runStableCheck({
|
|
126
|
+
oldFile: stablePath,
|
|
127
|
+
canisterMain: resolveConfigPath(canister.main),
|
|
128
|
+
canisterName: name,
|
|
129
|
+
mocPath,
|
|
130
|
+
globalMocArgs,
|
|
131
|
+
canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
|
|
132
|
+
sources,
|
|
133
|
+
options,
|
|
134
|
+
hasMigrations: !!canister.migrations,
|
|
135
|
+
});
|
|
136
|
+
} finally {
|
|
137
|
+
await migration.cleanup();
|
|
138
|
+
}
|
|
139
|
+
checked++;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (checked === 0 && !canisterNames) {
|
|
143
|
+
cliError(
|
|
144
|
+
"No canisters with [check-stable] configuration found in mops.toml.\n" +
|
|
145
|
+
"Either pass an old file: mops check-stable <old-file> [canister]\n" +
|
|
146
|
+
"Or configure check-stable for a canister:\n\n" +
|
|
147
|
+
" [canisters.backend.check-stable]\n" +
|
|
148
|
+
' path = "deployed.mo"',
|
|
149
|
+
);
|
|
150
|
+
}
|
|
42
151
|
}
|
|
43
152
|
|
|
44
153
|
export interface RunStableCheckParams {
|
|
@@ -47,7 +156,10 @@ export interface RunStableCheckParams {
|
|
|
47
156
|
canisterName: string;
|
|
48
157
|
mocPath: string;
|
|
49
158
|
globalMocArgs: string[];
|
|
159
|
+
canisterArgs: string[];
|
|
160
|
+
sources?: string[];
|
|
50
161
|
options?: Partial<CheckStableOptions>;
|
|
162
|
+
hasMigrations?: boolean;
|
|
51
163
|
}
|
|
52
164
|
|
|
53
165
|
export async function runStableCheck(
|
|
@@ -59,10 +171,11 @@ export async function runStableCheck(
|
|
|
59
171
|
canisterName,
|
|
60
172
|
mocPath,
|
|
61
173
|
globalMocArgs,
|
|
174
|
+
canisterArgs,
|
|
62
175
|
options = {},
|
|
63
176
|
} = params;
|
|
64
177
|
|
|
65
|
-
const sources = (await sourcesArgs()).flat();
|
|
178
|
+
const sources = params.sources ?? (await sourcesArgs()).flat();
|
|
66
179
|
const isOldMostFile = oldFile.endsWith(".most");
|
|
67
180
|
|
|
68
181
|
if (!existsSync(oldFile)) {
|
|
@@ -80,6 +193,7 @@ export async function runStableCheck(
|
|
|
80
193
|
join(CHECK_STABLE_DIR, "old.most"),
|
|
81
194
|
sources,
|
|
82
195
|
globalMocArgs,
|
|
196
|
+
canisterArgs,
|
|
83
197
|
options,
|
|
84
198
|
);
|
|
85
199
|
|
|
@@ -89,6 +203,7 @@ export async function runStableCheck(
|
|
|
89
203
|
join(CHECK_STABLE_DIR, "new.most"),
|
|
90
204
|
sources,
|
|
91
205
|
globalMocArgs,
|
|
206
|
+
canisterArgs,
|
|
92
207
|
options,
|
|
93
208
|
);
|
|
94
209
|
|
|
@@ -113,6 +228,13 @@ export async function runStableCheck(
|
|
|
113
228
|
if (result.stderr) {
|
|
114
229
|
console.error(result.stderr);
|
|
115
230
|
}
|
|
231
|
+
if (params.hasMigrations) {
|
|
232
|
+
console.error(
|
|
233
|
+
chalk.yellow(
|
|
234
|
+
"Hint: You may need a migration. Run `mops migrate new <Name>` to create one.",
|
|
235
|
+
),
|
|
236
|
+
);
|
|
237
|
+
}
|
|
116
238
|
cliError(
|
|
117
239
|
`✗ Stable compatibility check failed for canister '${canisterName}'`,
|
|
118
240
|
);
|
|
@@ -134,6 +256,7 @@ async function generateStableTypes(
|
|
|
134
256
|
outputPath: string,
|
|
135
257
|
sources: string[],
|
|
136
258
|
globalMocArgs: string[],
|
|
259
|
+
canisterArgs: string[],
|
|
137
260
|
options: Partial<CheckStableOptions>,
|
|
138
261
|
): Promise<string> {
|
|
139
262
|
const base = basename(outputPath, ".most");
|
|
@@ -145,6 +268,7 @@ async function generateStableTypes(
|
|
|
145
268
|
moFile,
|
|
146
269
|
...sources,
|
|
147
270
|
...globalMocArgs,
|
|
271
|
+
...canisterArgs,
|
|
148
272
|
...(options.extraArgs ?? []),
|
|
149
273
|
];
|
|
150
274
|
|