cobolx-2 1.2.3
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/.github/pull_request_template.md +9 -0
- package/.github/workflows/ci.yml +18 -0
- package/.vscode/launch.json +19 -0
- package/.vscode/tasks.json +14 -0
- package/CHANGELOG.md +16 -0
- package/CONTRIBUTING.md +23 -0
- package/CargoX.lock +2 -0
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/api-demo/CargoX.lock +1 -0
- package/api-demo/README.md +3 -0
- package/api-demo/benchmarks/arith.cbx +6 -0
- package/api-demo/cobolx.toml +6 -0
- package/api-demo/docs-output/index.html +1 -0
- package/api-demo/generated/LEGACYDEMO.cbx +5 -0
- package/api-demo/generated/client-types.ts +2 -0
- package/api-demo/generated/deploy.json +12 -0
- package/api-demo/generated/flowchart.mmd +4 -0
- package/api-demo/migrations/20260411215238_init.sql +1 -0
- package/api-demo/src/main.cbx +5 -0
- package/api-demo/tests/smoke.cbx +6 -0
- package/benchmarks/arithmetic.cbx +6 -0
- package/cargox/package.json +11 -0
- package/cargox/src/index.d.ts +4 -0
- package/cargox/src/index.js +5 -0
- package/cargox/src/index.js.map +1 -0
- package/cargox/src/index.ts +4 -0
- package/cargox/src/lockfile/index.d.ts +1 -0
- package/cargox/src/lockfile/index.js +9 -0
- package/cargox/src/lockfile/index.js.map +1 -0
- package/cargox/src/lockfile/index.ts +9 -0
- package/cargox/src/manifest.d.ts +10 -0
- package/cargox/src/manifest.js +49 -0
- package/cargox/src/manifest.js.map +1 -0
- package/cargox/src/manifest.ts +58 -0
- package/cargox/src/registry/index.d.ts +4 -0
- package/cargox/src/registry/index.js +13 -0
- package/cargox/src/registry/index.js.map +1 -0
- package/cargox/src/registry/index.ts +13 -0
- package/cargox/src/resolver/index.d.ts +5 -0
- package/cargox/src/resolver/index.js +4 -0
- package/cargox/src/resolver/index.js.map +1 -0
- package/cargox/src/resolver/index.ts +8 -0
- package/cargox/tsconfig.json +7 -0
- package/cli/cobolx-cli/package.json +23 -0
- package/cli/cobolx-cli/src/commands/add.ts +18 -0
- package/cli/cobolx-cli/src/commands/bench.ts +47 -0
- package/cli/cobolx-cli/src/commands/build.ts +74 -0
- package/cli/cobolx-cli/src/commands/check.ts +24 -0
- package/cli/cobolx-cli/src/commands/debug.ts +15 -0
- package/cli/cobolx-cli/src/commands/debug_rewind.ts +16 -0
- package/cli/cobolx-cli/src/commands/deploy.ts +18 -0
- package/cli/cobolx-cli/src/commands/dev.ts +24 -0
- package/cli/cobolx-cli/src/commands/doc.ts +19 -0
- package/cli/cobolx-cli/src/commands/fmt.ts +14 -0
- package/cli/cobolx-cli/src/commands/fuzz.ts +24 -0
- package/cli/cobolx-cli/src/commands/generate.ts +38 -0
- package/cli/cobolx-cli/src/commands/install.ts +25 -0
- package/cli/cobolx-cli/src/commands/legacy.ts +17 -0
- package/cli/cobolx-cli/src/commands/lint.ts +17 -0
- package/cli/cobolx-cli/src/commands/migrate.ts +27 -0
- package/cli/cobolx-cli/src/commands/new.ts +20 -0
- package/cli/cobolx-cli/src/commands/profile.ts +8 -0
- package/cli/cobolx-cli/src/commands/publish.ts +16 -0
- package/cli/cobolx-cli/src/commands/repl.ts +30 -0
- package/cli/cobolx-cli/src/commands/run.ts +22 -0
- package/cli/cobolx-cli/src/commands/task.ts +27 -0
- package/cli/cobolx-cli/src/commands/test.ts +44 -0
- package/cli/cobolx-cli/src/commands/update.ts +30 -0
- package/cli/cobolx-cli/src/commands/visualize.ts +25 -0
- package/cli/cobolx-cli/src/index.ts +101 -0
- package/cli/cobolx-cli/src/project.ts +74 -0
- package/cli/cobolx-cli/tsconfig.json +7 -0
- package/cobolx.toml +7 -0
- package/compiler/package.json +14 -0
- package/compiler/src/ast/types.d.ts +87 -0
- package/compiler/src/ast/types.js +2 -0
- package/compiler/src/ast/types.js.map +1 -0
- package/compiler/src/ast/types.ts +329 -0
- package/compiler/src/backend/custom.d.ts +8 -0
- package/compiler/src/backend/custom.js +12 -0
- package/compiler/src/backend/custom.js.map +1 -0
- package/compiler/src/backend/custom.ts +21 -0
- package/compiler/src/borrow_checker/checker.d.ts +3 -0
- package/compiler/src/borrow_checker/checker.js +82 -0
- package/compiler/src/borrow_checker/checker.js.map +1 -0
- package/compiler/src/borrow_checker/checker.ts +100 -0
- package/compiler/src/codegen/javascript.d.ts +2 -0
- package/compiler/src/codegen/javascript.js +89 -0
- package/compiler/src/codegen/javascript.js.map +1 -0
- package/compiler/src/codegen/javascript.ts +175 -0
- package/compiler/src/const_eval/evaluator.ts +58 -0
- package/compiler/src/diagnostics.d.ts +11 -0
- package/compiler/src/diagnostics.js +14 -0
- package/compiler/src/diagnostics.js.map +1 -0
- package/compiler/src/diagnostics.ts +20 -0
- package/compiler/src/hir/lower.d.ts +7 -0
- package/compiler/src/hir/lower.js +44 -0
- package/compiler/src/hir/lower.js.map +1 -0
- package/compiler/src/hir/lower.ts +60 -0
- package/compiler/src/hir/types.d.ts +21 -0
- package/compiler/src/hir/types.js +2 -0
- package/compiler/src/hir/types.js.map +1 -0
- package/compiler/src/hir/types.ts +26 -0
- package/compiler/src/index.d.ts +22 -0
- package/compiler/src/index.js +84 -0
- package/compiler/src/index.js.map +1 -0
- package/compiler/src/index.ts +122 -0
- package/compiler/src/lexer/lexer.d.ts +21 -0
- package/compiler/src/lexer/lexer.js +207 -0
- package/compiler/src/lexer/lexer.js.map +1 -0
- package/compiler/src/lexer/lexer.ts +274 -0
- package/compiler/src/lexer/tokens.d.ts +8 -0
- package/compiler/src/lexer/tokens.js +18 -0
- package/compiler/src/lexer/tokens.js.map +1 -0
- package/compiler/src/lexer/tokens.ts +126 -0
- package/compiler/src/macros/expand.ts +75 -0
- package/compiler/src/main.ts +4 -0
- package/compiler/src/mir/lower.d.ts +3 -0
- package/compiler/src/mir/lower.js +10 -0
- package/compiler/src/mir/lower.js.map +1 -0
- package/compiler/src/mir/lower.ts +12 -0
- package/compiler/src/mir/types.d.ts +13 -0
- package/compiler/src/mir/types.js +2 -0
- package/compiler/src/mir/types.js.map +1 -0
- package/compiler/src/mir/types.ts +16 -0
- package/compiler/src/optimizer/constantFold.d.ts +2 -0
- package/compiler/src/optimizer/constantFold.js +61 -0
- package/compiler/src/optimizer/constantFold.js.map +1 -0
- package/compiler/src/optimizer/constantFold.ts +109 -0
- package/compiler/src/parser/parser.d.ts +33 -0
- package/compiler/src/parser/parser.js +323 -0
- package/compiler/src/parser/parser.js.map +1 -0
- package/compiler/src/parser/parser.ts +710 -0
- package/compiler/src/plugins/api.ts +8 -0
- package/compiler/src/plugins/loader.ts +21 -0
- package/compiler/src/semantic/analyzer.d.ts +12 -0
- package/compiler/src/semantic/analyzer.js +144 -0
- package/compiler/src/semantic/analyzer.js.map +1 -0
- package/compiler/src/semantic/analyzer.ts +277 -0
- package/compiler/src/type_system/checker.d.ts +7 -0
- package/compiler/src/type_system/checker.js +84 -0
- package/compiler/src/type_system/checker.js.map +1 -0
- package/compiler/src/type_system/checker.ts +108 -0
- package/compiler/tsconfig.json +7 -0
- package/debugger/package.json +11 -0
- package/debugger/src/index.d.ts +1 -0
- package/debugger/src/index.js +9 -0
- package/debugger/src/index.js.map +1 -0
- package/debugger/src/index.ts +9 -0
- package/debugger/tsconfig.json +7 -0
- package/docs/CHANGELOG.md +11 -0
- package/docs/CONTRIBUTING.md +15 -0
- package/docs/LICENSE +21 -0
- package/docs/architecture.md +29 -0
- package/docs/cli.md +58 -0
- package/docs/language-spec.md +49 -0
- package/docs/packages.md +19 -0
- package/docs/platform-systems.md +31 -0
- package/docs/release-validation.md +22 -0
- package/docs/runtime.md +10 -0
- package/docs/tooling.md +17 -0
- package/docs/vscode-extension.md +40 -0
- package/enterprise-demo/CargoX.lock +2 -0
- package/enterprise-demo/README.md +3 -0
- package/enterprise-demo/benchmarks/arith.cbx +6 -0
- package/enterprise-demo/cobolx.toml +7 -0
- package/enterprise-demo/src/main.cbx +5 -0
- package/enterprise-demo/tests/smoke.cbx +6 -0
- package/examples/README.md +20 -0
- package/examples/actors-and-flags.md +8 -0
- package/examples/api-server/README.md +9 -0
- package/examples/api-server/cobolx.toml +6 -0
- package/examples/api-server/src/main.cbx +8 -0
- package/examples/debug-replay.md +7 -0
- package/examples/debugging-demo/README.md +3 -0
- package/examples/debugging-demo/cobolx.toml +6 -0
- package/examples/debugging-demo/src/main.cbx +7 -0
- package/examples/distributed-service.md +12 -0
- package/examples/distributed-system/README.md +3 -0
- package/examples/distributed-system/cobolx.toml +6 -0
- package/examples/distributed-system/generated/deploy.json +12 -0
- package/examples/distributed-system/src/main.cbx +6 -0
- package/examples/event-driven.md +5 -0
- package/examples/event-system/README.md +3 -0
- package/examples/event-system/cobolx.toml +6 -0
- package/examples/event-system/src/main.cbx +11 -0
- package/examples/functions.cbx +10 -0
- package/examples/functions.mjs +12 -0
- package/examples/hello.cbx +5 -0
- package/examples/hello.mjs +7 -0
- package/examples/legacy-sample.cob +5 -0
- package/examples/parallel-processing/README.md +3 -0
- package/examples/parallel-processing/cobolx.toml +6 -0
- package/examples/parallel-processing/src/main.cbx +6 -0
- package/examples/parallel-processing.md +8 -0
- package/examples/platform-features.cbx +32 -0
- package/examples/platform-features.mjs +35 -0
- package/examples/service.cbx +10 -0
- package/examples/workflow-engine/README.md +3 -0
- package/examples/workflow-engine/cobolx.toml +6 -0
- package/examples/workflow-engine/generated/flowchart.mmd +8 -0
- package/examples/workflow-engine/src/main.cbx +13 -0
- package/examples/workflow-engine.md +5 -0
- package/formatter/package.json +14 -0
- package/formatter/src/index.d.ts +1 -0
- package/formatter/src/index.js +59 -0
- package/formatter/src/index.js.map +1 -0
- package/formatter/src/index.ts +103 -0
- package/formatter/tsconfig.json +7 -0
- package/generated/LEGACYDEMO.cbx +5 -0
- package/install.ps1 +4 -0
- package/install.sh +5 -0
- package/linter/package.json +14 -0
- package/linter/src/index.d.ts +2 -0
- package/linter/src/index.js +18 -0
- package/linter/src/index.js.map +1 -0
- package/linter/src/index.ts +19 -0
- package/linter/tsconfig.json +7 -0
- package/lsp/server/package.json +16 -0
- package/lsp/server/src/index.ts +168 -0
- package/lsp/server/tsconfig.json +7 -0
- package/package.json +30 -0
- package/profiler/package.json +11 -0
- package/profiler/src/index.d.ts +5 -0
- package/profiler/src/index.js +11 -0
- package/profiler/src/index.js.map +1 -0
- package/profiler/src/index.ts +11 -0
- package/profiler/tsconfig.json +7 -0
- package/release.json +10 -0
- package/runtime/package.json +14 -0
- package/runtime/src/actors/index.ts +27 -0
- package/runtime/src/async/futures.ts +11 -0
- package/runtime/src/code_as_data/index.ts +5 -0
- package/runtime/src/config/index.ts +17 -0
- package/runtime/src/distributed/index.ts +13 -0
- package/runtime/src/events/index.ts +21 -0
- package/runtime/src/feature_flags/index.ts +9 -0
- package/runtime/src/gc_or_arc/index.ts +1 -0
- package/runtime/src/healing/index.ts +26 -0
- package/runtime/src/index.ts +20 -0
- package/runtime/src/intents/index.ts +9 -0
- package/runtime/src/iterators/index.ts +23 -0
- package/runtime/src/memory/arc.ts +22 -0
- package/runtime/src/observability/index.ts +23 -0
- package/runtime/src/repl/context.ts +7 -0
- package/runtime/src/scheduler/taskScheduler.ts +11 -0
- package/runtime/src/security/capabilities.ts +15 -0
- package/runtime/src/security/secrets.ts +13 -0
- package/runtime/src/state/versioned.ts +31 -0
- package/runtime/src/std_hooks/audit.ts +23 -0
- package/runtime/src/time_travel/index.ts +54 -0
- package/runtime/src/workflows/index.ts +35 -0
- package/runtime/tsconfig.json +7 -0
- package/sample-payroll/README.md +3 -0
- package/sample-payroll/cobolx.toml +3 -0
- package/sample-payroll/src/main.cbx +5 -0
- package/stdlib/business/index.js +15 -0
- package/stdlib/core/README.md +8 -0
- package/stdlib/core/runtime.js +191 -0
- package/stdlib/crypto/index.js +5 -0
- package/stdlib/datetime/index.js +3 -0
- package/stdlib/fs/index.js +9 -0
- package/stdlib/http/index.js +7 -0
- package/stdlib/io/index.js +1 -0
- package/stdlib/json/index.js +7 -0
- package/stdlib/net/index.js +4 -0
- package/tests/macros.cbx +10 -0
- package/tests/pattern_match.cbx +16 -0
- package/tests/smoke.cbx +7 -0
- package/tests/validate-release.mjs +54 -0
- package/tsconfig.base.json +24 -0
- package/vscode-extension/LICENSE +21 -0
- package/vscode-extension/README.md +47 -0
- package/vscode-extension/cobolx-1.2.0.vsix +0 -0
- package/vscode-extension/icon.png +0 -0
- package/vscode-extension/icon.svg +15 -0
- package/vscode-extension/language-configuration.json +17 -0
- package/vscode-extension/package.json +148 -0
- package/vscode-extension/snippets/cobolx.code-snippets +49 -0
- package/vscode-extension/src/extension.ts +283 -0
- package/vscode-extension/syntaxes/cobolx.tmLanguage.json +75 -0
- package/vscode-extension/tests/test.cbl +3 -0
- package/vscode-extension/tsconfig.json +7 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cobolx/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cobolx": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "powershell -NoProfile -Command \"if (Test-Path dist) { Remove-Item -Recurse -Force dist }; tsc -p tsconfig.json; if (Test-Path 'dist\\\\cli\\\\cobolx-cli\\\\src') { Copy-Item -Recurse -Force 'dist\\\\cli\\\\cobolx-cli\\\\src\\\\*' dist }\"",
|
|
11
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
12
|
+
"clean": "if (Test-Path dist) { Remove-Item -Recurse -Force dist }"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@cobolx/cargox": "0.2.0",
|
|
16
|
+
"@cobolx/compiler": "0.2.0",
|
|
17
|
+
"@cobolx/debugger": "0.2.0",
|
|
18
|
+
"@cobolx/formatter": "0.2.0",
|
|
19
|
+
"@cobolx/linter": "0.2.0",
|
|
20
|
+
"@cobolx/profiler": "0.2.0",
|
|
21
|
+
"@cobolx/runtime": "0.2.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readManifest, resolveDependencyGraph, writeLockfile, writeManifest } from "@cobolx/cargox";
|
|
2
|
+
import { lockfilePath, manifestPath } from "../project.js";
|
|
3
|
+
|
|
4
|
+
export function runAddCommand(projectDir: string, dependencyName?: string, version = "0.1.0"): number {
|
|
5
|
+
if (!dependencyName) {
|
|
6
|
+
console.error("Usage: cobolx add <dependency> [version]");
|
|
7
|
+
return 1;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const manifestFile = manifestPath(projectDir);
|
|
11
|
+
const manifest = readManifest(manifestFile);
|
|
12
|
+
manifest.dependencies[dependencyName] = version;
|
|
13
|
+
writeManifest(manifestFile, manifest);
|
|
14
|
+
const graph = resolveDependencyGraph(manifest.package.name, manifest.dependencies);
|
|
15
|
+
writeLockfile(lockfilePath(projectDir), graph.root, graph.dependencies);
|
|
16
|
+
console.log(`Added dependency ${dependencyName}@${version}`);
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { profile } from "@cobolx/profiler";
|
|
4
|
+
import { CobolxError, compileFile, compilerStdlibDir, printDiagnostics } from "@cobolx/compiler";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
|
|
7
|
+
export async function runBenchCommand(projectDir: string): Promise<number> {
|
|
8
|
+
const benchmarksDir = path.join(projectDir, "benchmarks");
|
|
9
|
+
if (!fs.existsSync(benchmarksDir)) {
|
|
10
|
+
console.log("No benchmarks directory found");
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const files = fs.readdirSync(benchmarksDir).filter((file) => file.endsWith(".cbx"));
|
|
15
|
+
const outDir = path.join(projectDir, "dist", "benchmarks");
|
|
16
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
17
|
+
let totalDuration = 0;
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
const inputPath = path.join(benchmarksDir, file);
|
|
20
|
+
const outputPath = path.join(outDir, file.replace(/\.cbx$/i, ".mjs"));
|
|
21
|
+
const diagnostics = compileFile(inputPath, outputPath, compilerStdlibDir());
|
|
22
|
+
const hasErrors = diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
23
|
+
if (diagnostics.length > 0) {
|
|
24
|
+
printDiagnostics(inputPath, diagnostics);
|
|
25
|
+
if (hasErrors) return 1;
|
|
26
|
+
}
|
|
27
|
+
const measurement = await profile(file, () => {
|
|
28
|
+
const result = spawnSync(process.execPath, [outputPath], {
|
|
29
|
+
cwd: projectDir,
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
stdio: "inherit"
|
|
32
|
+
});
|
|
33
|
+
return result.status ?? 1;
|
|
34
|
+
});
|
|
35
|
+
totalDuration += measurement.durationMs;
|
|
36
|
+
if (measurement.result !== 0) return measurement.result;
|
|
37
|
+
}
|
|
38
|
+
console.log(`Benchmarked ${files.length} file(s) in ${totalDuration.toFixed(2)}ms`);
|
|
39
|
+
return 0;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error instanceof CobolxError) {
|
|
42
|
+
console.error(error.message);
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { CobolxError, compileFile, printDiagnostics } from "@cobolx/compiler";
|
|
6
|
+
import { compilerStdlibDir } from "@cobolx/compiler";
|
|
7
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
8
|
+
|
|
9
|
+
export interface BuildOptions {
|
|
10
|
+
release?: boolean;
|
|
11
|
+
target?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const TOOLCHAIN_CACHE_VERSION = "1.0.0";
|
|
15
|
+
|
|
16
|
+
function buildCachePath(projectDir: string): string {
|
|
17
|
+
return path.join(projectDir, ".cobolx-cache", "build.json");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function sourceHash(value: string): string {
|
|
21
|
+
return crypto.createHash("sha256").update(value).digest("hex");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function toolchainFingerprint(): string {
|
|
25
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
26
|
+
const toolchainFiles = [
|
|
27
|
+
currentFile,
|
|
28
|
+
path.resolve(path.dirname(currentFile), "../../../compiler/dist/index.js"),
|
|
29
|
+
path.resolve(path.dirname(currentFile), "../../../stdlib/core/runtime.js")
|
|
30
|
+
];
|
|
31
|
+
return toolchainFiles
|
|
32
|
+
.filter((file) => fs.existsSync(file))
|
|
33
|
+
.map((file) => `${path.basename(file)}:${fs.statSync(file).mtimeMs}`)
|
|
34
|
+
.join("|");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function runBuildCommand(projectDir: string, options: BuildOptions = {}): number {
|
|
38
|
+
try {
|
|
39
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
40
|
+
const inputPath = path.join(projectDir, manifest.package.entry);
|
|
41
|
+
const target = options.target ?? "node";
|
|
42
|
+
const outputPath = path.join(projectDir, "dist", target === "wasm" ? "main.wasm.mjs" : "main.mjs");
|
|
43
|
+
const source = fs.readFileSync(inputPath, "utf8");
|
|
44
|
+
const cachePath = buildCachePath(projectDir);
|
|
45
|
+
const cacheKey = sourceHash(`${TOOLCHAIN_CACHE_VERSION}:${toolchainFingerprint()}:${source}:${options.release ? "release" : "debug"}:${target}`);
|
|
46
|
+
if (fs.existsSync(cachePath)) {
|
|
47
|
+
const previous = JSON.parse(fs.readFileSync(cachePath, "utf8")) as { key?: string; outputPath?: string };
|
|
48
|
+
if (previous.key === cacheKey && previous.outputPath === outputPath && fs.existsSync(outputPath)) {
|
|
49
|
+
console.log(`Reused incremental build cache for ${outputPath}`);
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const diagnostics = compileFile(inputPath, outputPath, compilerStdlibDir());
|
|
54
|
+
const hasErrors = diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
55
|
+
|
|
56
|
+
if (diagnostics.length > 0) {
|
|
57
|
+
printDiagnostics(inputPath, diagnostics);
|
|
58
|
+
}
|
|
59
|
+
if (hasErrors) {
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
64
|
+
fs.writeFileSync(cachePath, JSON.stringify({ key: cacheKey, outputPath, target, mode: options.release ? "release" : "debug" }, null, 2), "utf8");
|
|
65
|
+
console.log(`Built ${outputPath}${options.release ? " [release]" : " [debug]"}${target !== "node" ? ` target=${target}` : ""}`);
|
|
66
|
+
return 0;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error instanceof CobolxError) {
|
|
69
|
+
console.error(error.message);
|
|
70
|
+
return 1;
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { CobolxError, checkFile, printDiagnostics } from "@cobolx/compiler";
|
|
3
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
4
|
+
|
|
5
|
+
export function runCheckCommand(projectDir: string): number {
|
|
6
|
+
try {
|
|
7
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
8
|
+
const inputPath = path.join(projectDir, manifest.package.entry);
|
|
9
|
+
const diagnostics = checkFile(inputPath);
|
|
10
|
+
const hasErrors = diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
11
|
+
if (diagnostics.length > 0) {
|
|
12
|
+
printDiagnostics(inputPath, diagnostics);
|
|
13
|
+
if (hasErrors) return 1;
|
|
14
|
+
}
|
|
15
|
+
console.log("Check completed successfully");
|
|
16
|
+
return 0;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof CobolxError) {
|
|
19
|
+
console.error(error.message);
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { debugNodeProgram } from "@cobolx/debugger";
|
|
3
|
+
import { runBuildCommand } from "./build.js";
|
|
4
|
+
import { runDebugRewindCommand } from "./debug_rewind.js";
|
|
5
|
+
|
|
6
|
+
export function runDebugCommand(projectDir: string, rewind = false): number {
|
|
7
|
+
if (rewind) {
|
|
8
|
+
return runDebugRewindCommand(projectDir);
|
|
9
|
+
}
|
|
10
|
+
const buildExit = runBuildCommand(projectDir);
|
|
11
|
+
if (buildExit !== 0) {
|
|
12
|
+
return buildExit;
|
|
13
|
+
}
|
|
14
|
+
return debugNodeProgram(path.join(projectDir, "dist", "main.mjs"));
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadTimeline } from "@cobolx/runtime";
|
|
4
|
+
|
|
5
|
+
export function runDebugRewindCommand(projectDir: string): number {
|
|
6
|
+
const tracePath = path.join(projectDir, "dist", "debug-timeline.json");
|
|
7
|
+
if (!fs.existsSync(tracePath)) {
|
|
8
|
+
console.error(`No debug trace found at ${tracePath}. Run the program with tracing first.`);
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
const timeline = loadTimeline(tracePath);
|
|
12
|
+
for (const entry of timeline.slice().reverse()) {
|
|
13
|
+
console.log(`[rewind step ${entry.step}] ${entry.action} ${JSON.stringify(entry.state)}`);
|
|
14
|
+
}
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { discoverService, healthCheck, registerService } from "@cobolx/runtime";
|
|
4
|
+
import { runBuildCommand } from "./build.js";
|
|
5
|
+
|
|
6
|
+
export function runDeployCommand(projectDir: string): number {
|
|
7
|
+
const built = runBuildCommand(projectDir, { release: true });
|
|
8
|
+
if (built !== 0) return built;
|
|
9
|
+
const serviceName = path.basename(projectDir);
|
|
10
|
+
const address = `node://${serviceName}`;
|
|
11
|
+
registerService(serviceName, address);
|
|
12
|
+
const status = healthCheck(serviceName, true, { address });
|
|
13
|
+
const out = path.join(projectDir, "generated", "deploy.json");
|
|
14
|
+
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
15
|
+
fs.writeFileSync(out, JSON.stringify({ service: serviceName, address, status, discovered: discoverService(serviceName) }, null, 2), "utf8");
|
|
16
|
+
console.log(`Deployed ${serviceName} to ${address}`);
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
5
|
+
import { runBuildCommand } from "./build.js";
|
|
6
|
+
|
|
7
|
+
export function runDevCommand(projectDir: string): number {
|
|
8
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
9
|
+
const sourcePath = path.join(projectDir, manifest.package.entry);
|
|
10
|
+
let child: ReturnType<typeof spawn> | undefined;
|
|
11
|
+
|
|
12
|
+
const restart = (): void => {
|
|
13
|
+
child?.kill();
|
|
14
|
+
const built = runBuildCommand(projectDir);
|
|
15
|
+
if (built !== 0) return;
|
|
16
|
+
const output = path.join(projectDir, "dist", "main.mjs");
|
|
17
|
+
child = spawn(process.execPath, [output], { cwd: projectDir, stdio: "inherit" });
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
restart();
|
|
21
|
+
fs.watch(sourcePath, { persistent: true }, () => restart());
|
|
22
|
+
console.log(`Watching ${sourcePath} for hot reload changes. Press Ctrl+C to stop.`);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseSource } from "@cobolx/compiler";
|
|
4
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
5
|
+
|
|
6
|
+
export function runDocCommand(projectDir: string): number {
|
|
7
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
8
|
+
const sourcePath = path.join(projectDir, manifest.package.entry);
|
|
9
|
+
const source = fs.readFileSync(sourcePath, "utf8");
|
|
10
|
+
const program = parseSource(source);
|
|
11
|
+
const outputDir = path.join(projectDir, "docs-output");
|
|
12
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
13
|
+
const html = `<!doctype html><html><body><h1>${program.name}</h1><h2>Functions</h2><ul>${program.functions
|
|
14
|
+
.map((fn) => `<li><strong>${fn.signature.name}</strong><p>${(fn.docs ?? []).join(" ")}</p></li>`)
|
|
15
|
+
.join("")}</ul><h2>Traits</h2><ul>${program.traits.map((trait) => `<li>${trait.name}</li>`).join("")}</ul></body></html>`;
|
|
16
|
+
fs.writeFileSync(path.join(outputDir, "index.html"), html, "utf8");
|
|
17
|
+
console.log(`Generated docs at ${path.join(outputDir, "index.html")}`);
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { formatSource } from "@cobolx/formatter";
|
|
4
|
+
import { readManifest } from "@cobolx/cargox";
|
|
5
|
+
import { manifestPath } from "../project.js";
|
|
6
|
+
|
|
7
|
+
export function runFmtCommand(projectDir: string): number {
|
|
8
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
9
|
+
const inputPath = path.join(projectDir, manifest.package.entry);
|
|
10
|
+
const source = fs.readFileSync(inputPath, "utf8");
|
|
11
|
+
fs.writeFileSync(inputPath, formatSource(source), "utf8");
|
|
12
|
+
console.log(`Formatted ${inputPath}`);
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { CobolxError, analyzeSource } from "@cobolx/compiler";
|
|
4
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
5
|
+
|
|
6
|
+
export function runFuzzCommand(projectDir: string, target = "parser"): number {
|
|
7
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
8
|
+
const sourcePath = path.join(projectDir, manifest.package.entry);
|
|
9
|
+
const source = fs.readFileSync(sourcePath, "utf8");
|
|
10
|
+
const seeds = [source, source.replace(/DISPLAY/g, "DISPLAY"), source.slice(0, Math.max(1, source.length - 1)), `${source}\nDISPLAY "fuzz"`];
|
|
11
|
+
for (const seed of seeds) {
|
|
12
|
+
try {
|
|
13
|
+
analyzeSource(seed);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (error instanceof CobolxError) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
console.error(`Fuzz case crashed ${target}: ${String(error)}`);
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
console.log(`Fuzzed ${target} with ${seeds.length} mutated inputs`);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseSource } from "@cobolx/compiler";
|
|
4
|
+
import { readManifest, manifestPath } from "../project.js";
|
|
5
|
+
|
|
6
|
+
export function runGenerateCommand(projectDir: string, target?: string, arg?: string): number {
|
|
7
|
+
const generatedDir = path.join(projectDir, "generated");
|
|
8
|
+
fs.mkdirSync(generatedDir, { recursive: true });
|
|
9
|
+
|
|
10
|
+
if (target === "api") {
|
|
11
|
+
const file = path.join(generatedDir, "api.cbx");
|
|
12
|
+
fs.writeFileSync(file, 'PROGRAM Api\n\nBEGIN\nDISPLAY "Generated API"\nEND\n', "utf8");
|
|
13
|
+
console.log(`Generated ${file}`);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (target === "model" && arg) {
|
|
18
|
+
const file = path.join(generatedDir, `${arg}.cbx`);
|
|
19
|
+
fs.writeFileSync(file, `PROGRAM ${arg}\n\nBEGIN\nDISPLAY "${arg}"\nEND\n`, "utf8");
|
|
20
|
+
console.log(`Generated ${file}`);
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (target === "client" && arg === "typescript") {
|
|
25
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
26
|
+
const source = fs.readFileSync(path.join(projectDir, manifest.package.entry), "utf8");
|
|
27
|
+
const program = parseSource(source);
|
|
28
|
+
const file = path.join(generatedDir, "client-types.ts");
|
|
29
|
+
const enums = program.enums.map((item) => `export type ${item.name} = ${item.variants.map((variant) => `'${variant.name}'`).join(" | ")};`).join("\n");
|
|
30
|
+
const functions = program.functions.map((fn) => `export function ${fn.signature.name}(...args: unknown[]): Promise<unknown>;`).join("\n");
|
|
31
|
+
fs.writeFileSync(file, `${enums}\n${functions}\n`, "utf8");
|
|
32
|
+
console.log(`Generated ${file}`);
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.error("Usage: cobolx generate <api|model <Name>|client typescript>");
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readManifest, resolveDependencyGraph, writeLockfile } from "@cobolx/cargox";
|
|
4
|
+
import { lockfilePath, manifestPath } from "../project.js";
|
|
5
|
+
|
|
6
|
+
export function runInstallCommand(projectDir: string): number {
|
|
7
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
8
|
+
const graph = resolveDependencyGraph(manifest.package.name, manifest.dependencies);
|
|
9
|
+
const packagesDir = path.join(projectDir, ".cargox", "packages");
|
|
10
|
+
fs.mkdirSync(packagesDir, { recursive: true });
|
|
11
|
+
|
|
12
|
+
for (const [name, version] of Object.entries(graph.dependencies)) {
|
|
13
|
+
const packageDir = path.join(packagesDir, `${name}-${version}`);
|
|
14
|
+
fs.mkdirSync(packageDir, { recursive: true });
|
|
15
|
+
fs.writeFileSync(
|
|
16
|
+
path.join(packageDir, "manifest.json"),
|
|
17
|
+
JSON.stringify({ name, version, installedAt: new Date().toISOString() }, null, 2),
|
|
18
|
+
"utf8"
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
writeLockfile(lockfilePath(projectDir), graph.root, graph.dependencies);
|
|
23
|
+
console.log(`Installed ${Object.keys(graph.dependencies).length} package(s)`);
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export function runLegacyConvertCommand(projectDir: string, legacyPath?: string): number {
|
|
5
|
+
if (!legacyPath) {
|
|
6
|
+
console.error("Usage: cobolx legacy <path-to-.cob/.col>");
|
|
7
|
+
return 1;
|
|
8
|
+
}
|
|
9
|
+
const source = fs.readFileSync(path.resolve(projectDir, legacyPath), "utf8");
|
|
10
|
+
const programName = /PROGRAM-ID\.\s+([A-Za-z0-9_-]+)/i.exec(source)?.[1] ?? "Legacy";
|
|
11
|
+
const converted = `PROGRAM ${programName}\n\nBEGIN\nDISPLAY "Converted legacy COBOL program ${programName}"\nEND\n`;
|
|
12
|
+
const output = path.join(projectDir, "generated", `${programName}.cbx`);
|
|
13
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
14
|
+
fs.writeFileSync(output, converted, "utf8");
|
|
15
|
+
console.log(`Converted legacy COBOL to ${output}`);
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { formatDiagnostic } from "@cobolx/compiler";
|
|
4
|
+
import type { Diagnostic } from "@cobolx/compiler";
|
|
5
|
+
import { lintSource } from "@cobolx/linter";
|
|
6
|
+
import { readManifest } from "@cobolx/cargox";
|
|
7
|
+
import { manifestPath } from "../project.js";
|
|
8
|
+
|
|
9
|
+
export function runLintCommand(projectDir: string): number {
|
|
10
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
11
|
+
const inputPath = path.join(projectDir, manifest.package.entry);
|
|
12
|
+
const diagnostics = lintSource(fs.readFileSync(inputPath, "utf8"));
|
|
13
|
+
for (const diagnostic of diagnostics as Diagnostic[]) {
|
|
14
|
+
console.log(formatDiagnostic(inputPath, diagnostic));
|
|
15
|
+
}
|
|
16
|
+
return diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export function runMigrateCreateCommand(projectDir: string, name = "migration"): number {
|
|
5
|
+
const migrationsDir = path.join(projectDir, "migrations");
|
|
6
|
+
fs.mkdirSync(migrationsDir, { recursive: true });
|
|
7
|
+
const timestamp = new Date().toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
8
|
+
const file = path.join(migrationsDir, `${timestamp}_${name}.sql`);
|
|
9
|
+
fs.writeFileSync(file, "-- Write migration SQL here\n", "utf8");
|
|
10
|
+
console.log(`Created migration ${file}`);
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function runMigrateRunCommand(projectDir: string): number {
|
|
15
|
+
const migrationsDir = path.join(projectDir, "migrations");
|
|
16
|
+
const stateFile = path.join(projectDir, ".cobolx-cache", "migrations.json");
|
|
17
|
+
fs.mkdirSync(path.dirname(stateFile), { recursive: true });
|
|
18
|
+
const applied = fs.existsSync(stateFile) ? new Set<string>(JSON.parse(fs.readFileSync(stateFile, "utf8"))) : new Set<string>();
|
|
19
|
+
const files = fs.existsSync(migrationsDir) ? fs.readdirSync(migrationsDir).filter((file) => file.endsWith(".sql")).sort() : [];
|
|
20
|
+
for (const file of files) {
|
|
21
|
+
if (applied.has(file)) continue;
|
|
22
|
+
console.log(`Applying migration ${file}`);
|
|
23
|
+
applied.add(file);
|
|
24
|
+
}
|
|
25
|
+
fs.writeFileSync(stateFile, JSON.stringify([...applied], null, 2), "utf8");
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { scaffoldProject } from "../project.js";
|
|
4
|
+
|
|
5
|
+
export function runNewCommand(projectName?: string, template = "default"): number {
|
|
6
|
+
if (!projectName) {
|
|
7
|
+
console.error("Usage: cobolx new <project-name> [default|api|microservice|cli]");
|
|
8
|
+
return 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const targetDir = path.resolve(projectName);
|
|
12
|
+
if (fs.existsSync(targetDir)) {
|
|
13
|
+
console.error(`Directory already exists: ${targetDir}`);
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
scaffoldProject(targetDir, projectName, template);
|
|
18
|
+
console.log(`Created COBOLX project at ${targetDir}`);
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { profile } from "@cobolx/profiler";
|
|
2
|
+
import { runRunCommand } from "./run.js";
|
|
3
|
+
|
|
4
|
+
export async function runProfileCommand(projectDir: string): Promise<number> {
|
|
5
|
+
const measurement = await profile("run", () => runRunCommand(projectDir));
|
|
6
|
+
console.log(`Profile: ${measurement.label} completed in ${measurement.durationMs.toFixed(2)}ms`);
|
|
7
|
+
return measurement.result;
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { publishToLocalRegistry, readManifest } from "@cobolx/cargox";
|
|
4
|
+
import { manifestPath } from "../project.js";
|
|
5
|
+
|
|
6
|
+
export function runPublishCommand(projectDir: string): number {
|
|
7
|
+
const manifest = readManifest(manifestPath(projectDir));
|
|
8
|
+
const entryPath = path.join(projectDir, manifest.package.entry);
|
|
9
|
+
const registryDir = path.join(projectDir, ".cargox-registry");
|
|
10
|
+
const publishedDir = publishToLocalRegistry(registryDir, manifest.package.name, manifest.package.version, [
|
|
11
|
+
{ path: "cobolx.toml", content: fs.readFileSync(manifestPath(projectDir), "utf8") },
|
|
12
|
+
{ path: manifest.package.entry, content: fs.readFileSync(entryPath, "utf8") }
|
|
13
|
+
]);
|
|
14
|
+
console.log(`Published ${manifest.package.name}@${manifest.package.version} to ${publishedDir}`);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import readline from "node:readline";
|
|
2
|
+
import { analyzeSource, compileSource, compilerStdlibDir } from "@cobolx/compiler";
|
|
3
|
+
|
|
4
|
+
export async function runReplCommand(): Promise<number> {
|
|
5
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: "cobolx> " });
|
|
6
|
+
console.log("COBOL-X REPL. Enter DISPLAY expressions or PROGRAM blocks. Type .exit to quit.");
|
|
7
|
+
rl.prompt();
|
|
8
|
+
|
|
9
|
+
return await new Promise<number>((resolve) => {
|
|
10
|
+
rl.on("line", (line) => {
|
|
11
|
+
if (line.trim() === ".exit") {
|
|
12
|
+
rl.close();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const source = line.trim().startsWith("PROGRAM") ? line : `PROGRAM Repl\n\nBEGIN\n${line}\nEND\n`;
|
|
16
|
+
try {
|
|
17
|
+
const result = compileSource(source, "repl.mjs", compilerStdlibDir());
|
|
18
|
+
if (result.diagnostics.length > 0) {
|
|
19
|
+
console.log(result.diagnostics.map((d) => d.message).join("\n"));
|
|
20
|
+
} else {
|
|
21
|
+
console.log("ok");
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(String(error));
|
|
25
|
+
}
|
|
26
|
+
rl.prompt();
|
|
27
|
+
});
|
|
28
|
+
rl.on("close", () => resolve(0));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { type BuildOptions, runBuildCommand } from "./build.js";
|
|
4
|
+
|
|
5
|
+
export function runRunCommand(projectDir: string, options: BuildOptions = {}): number {
|
|
6
|
+
const buildExitCode = runBuildCommand(projectDir, options);
|
|
7
|
+
if (buildExitCode !== 0) {
|
|
8
|
+
return buildExitCode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const builtFile = path.join(projectDir, "dist", options.target === "wasm" ? "main.wasm.mjs" : "main.mjs");
|
|
12
|
+
const traceFile = path.join(projectDir, "dist", "debug-timeline.json");
|
|
13
|
+
const result = spawnSync(process.execPath, [builtFile], {
|
|
14
|
+
cwd: projectDir,
|
|
15
|
+
stdio: "inherit",
|
|
16
|
+
env: {
|
|
17
|
+
...process.env,
|
|
18
|
+
COBOLX_DEBUG_TRACE_FILE: traceFile
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return result.status ?? 1;
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
export function runTaskCommand(projectDir: string, taskName = "build"): number {
|
|
7
|
+
const tasksFile = path.join(projectDir, "cobolx.tasks.json");
|
|
8
|
+
if (!fs.existsSync(tasksFile)) {
|
|
9
|
+
console.error("No cobolx.tasks.json found");
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
const tasks = JSON.parse(fs.readFileSync(tasksFile, "utf8")) as Record<string, string[]>;
|
|
13
|
+
const steps = tasks[taskName];
|
|
14
|
+
if (!steps) {
|
|
15
|
+
console.error(`Task '${taskName}' not found`);
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
for (const step of steps) {
|
|
19
|
+
const cliEntry = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../index.js");
|
|
20
|
+
const result = spawnSync(process.execPath, [cliEntry, ...step.split(" ")], {
|
|
21
|
+
cwd: projectDir,
|
|
22
|
+
stdio: "inherit"
|
|
23
|
+
});
|
|
24
|
+
if ((result.status ?? 1) !== 0) return result.status ?? 1;
|
|
25
|
+
}
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { CobolxError, compileFile, compilerStdlibDir, printDiagnostics } from "@cobolx/compiler";
|
|
5
|
+
|
|
6
|
+
export function runTestCommand(projectDir: string): number {
|
|
7
|
+
const testsDir = path.join(projectDir, "tests");
|
|
8
|
+
if (!fs.existsSync(testsDir)) {
|
|
9
|
+
console.log("No tests directory found");
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const files = fs.readdirSync(testsDir).filter((file) => file.endsWith(".cbx"));
|
|
14
|
+
const outDir = path.join(projectDir, "dist", "tests");
|
|
15
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
16
|
+
for (const file of files) {
|
|
17
|
+
const inputPath = path.join(testsDir, file);
|
|
18
|
+
const outputPath = path.join(outDir, file.replace(/\.cbx$/i, ".mjs"));
|
|
19
|
+
const diagnostics = compileFile(inputPath, outputPath, compilerStdlibDir());
|
|
20
|
+
const hasErrors = diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
21
|
+
if (diagnostics.length > 0) {
|
|
22
|
+
printDiagnostics(inputPath, diagnostics);
|
|
23
|
+
if (hasErrors) return 1;
|
|
24
|
+
}
|
|
25
|
+
const result = spawnSync(process.execPath, [outputPath], {
|
|
26
|
+
cwd: projectDir,
|
|
27
|
+
encoding: "utf8",
|
|
28
|
+
stdio: "inherit"
|
|
29
|
+
});
|
|
30
|
+
if ((result.status ?? 1) !== 0) {
|
|
31
|
+
console.error(`Test failed: ${file}`);
|
|
32
|
+
return result.status ?? 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
console.log(`Executed ${files.length} test file(s)`);
|
|
36
|
+
return 0;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error instanceof CobolxError) {
|
|
39
|
+
console.error(error.message);
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|