as-test 1.0.3 → 1.0.4
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 +7 -1
- package/bin/commands/build-core.js +7 -0
- package/bin/commands/build.js +16 -1
- package/bin/index.js +66 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## 2026-03-27 -
|
|
3
|
+
## 2026-03-27 - v1.0.4
|
|
4
|
+
|
|
5
|
+
### Build Command
|
|
6
|
+
|
|
7
|
+
- fix: make `ast build` exit cleanly instead of hanging after work completes.
|
|
8
|
+
- feat: make `ast build` print per-mode build results and a final summary.
|
|
9
|
+
- feat: make `ast build` support `--parallel`, `--jobs`, and `--build-jobs`.
|
|
4
10
|
|
|
5
11
|
### Parallel Execution
|
|
6
12
|
|
|
@@ -102,6 +102,13 @@ function getSerialBuildWorkerPool() {
|
|
|
102
102
|
}
|
|
103
103
|
return serialBuildWorkerPool;
|
|
104
104
|
}
|
|
105
|
+
export async function closeSerialBuildWorkerPool() {
|
|
106
|
+
if (!serialBuildWorkerPool)
|
|
107
|
+
return;
|
|
108
|
+
const pool = serialBuildWorkerPool;
|
|
109
|
+
serialBuildWorkerPool = null;
|
|
110
|
+
await pool.close();
|
|
111
|
+
}
|
|
105
112
|
export async function getBuildInvocationPreview(configPath = DEFAULT_CONFIG_PATH, file, modeName, featureToggles = {}, overrides = {}) {
|
|
106
113
|
const loadedConfig = loadConfig(configPath, false);
|
|
107
114
|
const mode = applyMode(loadedConfig, modeName);
|
package/bin/commands/build.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { closeSerialBuildWorkerPool, } from "./build-core.js";
|
|
1
2
|
export { build } from "./build-core.js";
|
|
2
3
|
export { formatInvocation, getBuildInvocationPreview } from "./build-core.js";
|
|
3
4
|
export async function executeBuildCommand(rawArgs, configPath, selectedModes, deps) {
|
|
4
5
|
const commandArgs = deps.resolveCommandArgs(rawArgs, "build");
|
|
5
6
|
const listFlags = deps.resolveListFlags(rawArgs, "build");
|
|
6
7
|
const featureToggles = deps.resolveFeatureToggles(rawArgs, "build");
|
|
8
|
+
const parallel = deps.resolveBuildParallelJobs(rawArgs);
|
|
7
9
|
const buildFeatureToggles = {
|
|
8
10
|
tryAs: featureToggles.tryAs,
|
|
9
11
|
coverage: featureToggles.coverage,
|
|
@@ -13,5 +15,18 @@ export async function executeBuildCommand(rawArgs, configPath, selectedModes, de
|
|
|
13
15
|
await deps.listExecutionPlan("build", configPath, commandArgs, modeTargets, listFlags);
|
|
14
16
|
return;
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
const previousBuildApi = process.env.AS_TEST_BUILD_API;
|
|
19
|
+
process.env.AS_TEST_BUILD_API = "1";
|
|
20
|
+
try {
|
|
21
|
+
await deps.runBuildModes(configPath, commandArgs, modeTargets, buildFeatureToggles, parallel);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
if (previousBuildApi == undefined) {
|
|
25
|
+
delete process.env.AS_TEST_BUILD_API;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
process.env.AS_TEST_BUILD_API = previousBuildApi;
|
|
29
|
+
}
|
|
30
|
+
await closeSerialBuildWorkerPool();
|
|
31
|
+
}
|
|
17
32
|
}
|
package/bin/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { executeFuzzCommand } from "./commands/fuzz.js";
|
|
|
9
9
|
import { executeInitCommand } from "./commands/init.js";
|
|
10
10
|
import { executeDoctorCommand } from "./commands/doctor.js";
|
|
11
11
|
import { fuzz } from "./commands/fuzz-core.js";
|
|
12
|
-
import { applyMode, getCliVersion, loadConfig, resolveModeNames, } from "./util.js";
|
|
12
|
+
import { applyMode, formatTime, getCliVersion, loadConfig, resolveModeNames, } from "./util.js";
|
|
13
13
|
import * as path from "path";
|
|
14
14
|
import { spawnSync } from "child_process";
|
|
15
15
|
import { glob } from "glob";
|
|
@@ -50,6 +50,7 @@ else if (COMMANDS.includes(args[0])) {
|
|
|
50
50
|
resolveCommandArgs,
|
|
51
51
|
resolveListFlags,
|
|
52
52
|
resolveFeatureToggles,
|
|
53
|
+
resolveBuildParallelJobs,
|
|
53
54
|
resolveExecutionModes,
|
|
54
55
|
listExecutionPlan,
|
|
55
56
|
runBuildModes,
|
|
@@ -226,6 +227,9 @@ function printCommandHelp(command) {
|
|
|
226
227
|
process.stdout.write(" --mode <name[,name...]> Run one or multiple named config modes\n");
|
|
227
228
|
process.stdout.write(" --enable <feature> Enable build feature (coverage|try-as)\n");
|
|
228
229
|
process.stdout.write(" --disable <feature> Disable build feature (coverage|try-as)\n");
|
|
230
|
+
process.stdout.write(" --parallel Run files through an ordered worker pool using an automatic worker count\n");
|
|
231
|
+
process.stdout.write(" --jobs <n> Run files through an ordered worker pool\n");
|
|
232
|
+
process.stdout.write(" --build-jobs <n> Limit concurrent build tasks (defaults to --jobs)\n");
|
|
229
233
|
process.stdout.write(" --list Preview resolved files/artifacts without building\n");
|
|
230
234
|
process.stdout.write(" --list-modes Preview configured and selected mode names\n");
|
|
231
235
|
process.stdout.write(" --help, -h Show this help\n");
|
|
@@ -597,6 +601,29 @@ function resolveJobs(rawArgs, command) {
|
|
|
597
601
|
}
|
|
598
602
|
return parallel ? 0 : 1;
|
|
599
603
|
}
|
|
604
|
+
function resolveBuildParallelJobs(rawArgs) {
|
|
605
|
+
const baseJobs = resolveJobs(rawArgs, "build");
|
|
606
|
+
let buildJobs = baseJobs;
|
|
607
|
+
let seenCommand = false;
|
|
608
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
609
|
+
const arg = rawArgs[i];
|
|
610
|
+
if (!seenCommand) {
|
|
611
|
+
if (arg == "build")
|
|
612
|
+
seenCommand = true;
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
const buildParsed = parseNumberFlag(rawArgs, i, "--build-jobs");
|
|
616
|
+
if (buildParsed) {
|
|
617
|
+
if (buildParsed.number < 1) {
|
|
618
|
+
throw new Error("--build-jobs requires a positive integer");
|
|
619
|
+
}
|
|
620
|
+
buildJobs = buildParsed.number;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
const jobs = Math.max(baseJobs, buildJobs);
|
|
625
|
+
return { jobs, buildJobs };
|
|
626
|
+
}
|
|
600
627
|
function resolveParallelJobs(rawArgs, command) {
|
|
601
628
|
const baseJobs = resolveJobs(rawArgs, command);
|
|
602
629
|
let buildJobs = baseJobs;
|
|
@@ -922,10 +949,46 @@ async function runTestSequential(runFlags, configPath, selectors, buildFeatureTo
|
|
|
922
949
|
},
|
|
923
950
|
};
|
|
924
951
|
}
|
|
925
|
-
async function runBuildModes(configPath, selectors, modes, buildFeatureToggles) {
|
|
952
|
+
async function runBuildModes(configPath, selectors, modes, buildFeatureToggles, parallel) {
|
|
953
|
+
const files = await resolveSelectedFiles(configPath, selectors);
|
|
954
|
+
if (!files.length) {
|
|
955
|
+
throw await buildNoTestFilesMatchedError(configPath, selectors);
|
|
956
|
+
}
|
|
957
|
+
const effective = resolveEffectiveParallelJobs({
|
|
958
|
+
jobs: parallel.jobs,
|
|
959
|
+
buildJobs: parallel.buildJobs,
|
|
960
|
+
runJobs: parallel.buildJobs,
|
|
961
|
+
}, files.length);
|
|
962
|
+
const resolvedConfigPath = configPath ?? path.join(process.cwd(), "./as-test.config.json");
|
|
963
|
+
const loadedConfig = loadConfig(resolvedConfigPath, true);
|
|
964
|
+
const allStartedAt = Date.now();
|
|
965
|
+
let builtCount = 0;
|
|
926
966
|
for (const modeName of modes) {
|
|
927
|
-
|
|
967
|
+
const startedAt = Date.now();
|
|
968
|
+
if (effective.buildJobs > 1) {
|
|
969
|
+
const pool = new BuildWorkerPool(effective.buildJobs);
|
|
970
|
+
try {
|
|
971
|
+
await runOrderedPool(files, effective.buildJobs, async (file) => {
|
|
972
|
+
await pool.buildFileMode({
|
|
973
|
+
configPath,
|
|
974
|
+
file,
|
|
975
|
+
modeName,
|
|
976
|
+
featureToggles: buildFeatureToggles,
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
finally {
|
|
981
|
+
await pool.close();
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
await build(configPath, selectors, modeName, buildFeatureToggles);
|
|
986
|
+
}
|
|
987
|
+
builtCount += files.length;
|
|
988
|
+
const active = applyMode(loadedConfig, modeName).config;
|
|
989
|
+
process.stdout.write(`${chalk.bgGreenBright.black(" BUILT ")} ${modeName ?? "default"} ${chalk.dim(`(${active.buildOptions.target})`)} ${files.length} file(s) -> ${active.outDir} ${chalk.dim(formatTime(Date.now() - startedAt))}\n`);
|
|
928
990
|
}
|
|
991
|
+
process.stdout.write(`${chalk.bold("Summary:")} built ${builtCount} file(s) across ${modes.length || 1} mode(s) in ${formatTime(Date.now() - allStartedAt)}\n`);
|
|
929
992
|
}
|
|
930
993
|
async function runRuntimeModes(runFlags, configPath, selectors, modes) {
|
|
931
994
|
await ensureWebBrowsersReady(configPath, modes, runFlags.browser);
|