@tsonic/cli 0.0.1 → 0.0.2

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/src/cli/parser.ts DELETED
@@ -1,128 +0,0 @@
1
- /**
2
- * CLI argument parser
3
- */
4
-
5
- import type { CliOptions } from "../types.js";
6
-
7
- /**
8
- * Parse CLI arguments
9
- */
10
- export const parseArgs = (
11
- args: string[]
12
- ): {
13
- command: string;
14
- entryFile?: string;
15
- options: CliOptions;
16
- programArgs?: string[];
17
- } => {
18
- const options: CliOptions = {};
19
- let command = "";
20
- let entryFile: string | undefined;
21
- const programArgs: string[] = [];
22
- let captureProgramArgs = false;
23
-
24
- for (let i = 0; i < args.length; i++) {
25
- const arg = args[i];
26
- if (!arg) continue; // Skip if undefined
27
-
28
- // Separator for program arguments
29
- if (arg === "--") {
30
- captureProgramArgs = true;
31
- continue;
32
- }
33
-
34
- if (captureProgramArgs) {
35
- programArgs.push(arg);
36
- continue;
37
- }
38
-
39
- // Commands
40
- if (!command && !arg.startsWith("-")) {
41
- command = arg;
42
- // Handle "project init" as two-word command
43
- const nextArg = args[i + 1];
44
- if (command === "project" && nextArg === "init") {
45
- command = "project:init";
46
- i++;
47
- }
48
- continue;
49
- }
50
-
51
- // Entry file (first non-option after command)
52
- if (command && !entryFile && !arg.startsWith("-")) {
53
- entryFile = arg;
54
- continue;
55
- }
56
-
57
- // Options
58
- switch (arg) {
59
- case "-h":
60
- case "--help":
61
- options.verbose = true; // reuse for help flag
62
- return { command: "help", options: {} };
63
- case "-v":
64
- case "--version":
65
- return { command: "version", options: {} };
66
- case "-V":
67
- case "--verbose":
68
- options.verbose = true;
69
- break;
70
- case "-q":
71
- case "--quiet":
72
- options.quiet = true;
73
- break;
74
- case "-c":
75
- case "--config":
76
- options.config = args[++i] ?? "";
77
- break;
78
- case "-s":
79
- case "--src":
80
- options.src = args[++i] ?? "";
81
- break;
82
- case "-o":
83
- case "--out":
84
- options.out = args[++i] ?? "";
85
- break;
86
- case "-n":
87
- case "--namespace":
88
- options.namespace = args[++i] ?? "";
89
- break;
90
- case "-r":
91
- case "--rid":
92
- options.rid = args[++i] ?? "";
93
- break;
94
- case "--runtime":
95
- options.runtime = (args[++i] ?? "js") as "js" | "dotnet";
96
- break;
97
- case "--skip-types":
98
- options.skipTypes = true;
99
- break;
100
- case "--types-version":
101
- options.typesVersion = args[++i] ?? "";
102
- break;
103
- case "-O":
104
- case "--optimize":
105
- options.optimize = (args[++i] ?? "speed") as "size" | "speed";
106
- break;
107
- case "-k":
108
- case "--keep-temp":
109
- options.keepTemp = true;
110
- break;
111
- case "--no-strip":
112
- options.noStrip = true;
113
- break;
114
- case "-L":
115
- case "--lib":
116
- {
117
- const libPath = args[++i] ?? "";
118
- if (libPath) {
119
- options.lib = options.lib || [];
120
- options.lib.push(libPath);
121
- }
122
- }
123
- break;
124
- }
125
- }
126
-
127
- return { command, entryFile, options, programArgs };
128
- };
package/src/cli.ts DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * CLI argument parsing and command dispatch
3
- * Main dispatcher - re-exports from cli/ subdirectory
4
- */
5
-
6
- export { VERSION, showHelp, parseArgs, runCli } from "./cli/index.js";
@@ -1,264 +0,0 @@
1
- /**
2
- * tsonic build command - Build executable or library
3
- */
4
-
5
- import { spawnSync } from "node:child_process";
6
- import { join, relative } from "node:path";
7
- import { copyFileSync, chmodSync, existsSync, mkdirSync } from "node:fs";
8
- import type { ResolvedConfig, Result } from "../types.js";
9
- import { emitCommand } from "./emit.js";
10
-
11
- /**
12
- * Build native executable
13
- */
14
- const buildExecutable = (
15
- config: ResolvedConfig,
16
- generatedDir: string
17
- ): Result<{ outputPath: string }, string> => {
18
- const { outputName, rid, quiet, verbose } = config;
19
-
20
- // Step 2: Run dotnet publish
21
- if (!quiet) {
22
- console.log("Step 2/3: Compiling with dotnet publish...");
23
- }
24
-
25
- const publishArgs = [
26
- "publish",
27
- "tsonic.csproj",
28
- "-c",
29
- "Release",
30
- "-r",
31
- rid,
32
- "--nologo",
33
- ];
34
-
35
- if (quiet) {
36
- publishArgs.push("--verbosity", "quiet");
37
- } else if (verbose) {
38
- publishArgs.push("--verbosity", "detailed");
39
- } else {
40
- publishArgs.push("--verbosity", "minimal");
41
- }
42
-
43
- const publishResult = spawnSync("dotnet", publishArgs, {
44
- cwd: generatedDir,
45
- stdio: verbose ? "inherit" : "pipe",
46
- encoding: "utf-8",
47
- });
48
-
49
- if (publishResult.status !== 0) {
50
- const errorMsg =
51
- publishResult.stderr || publishResult.stdout || "Unknown error";
52
- return {
53
- ok: false,
54
- error: `dotnet publish failed:\n${errorMsg}`,
55
- };
56
- }
57
-
58
- // Step 3: Copy output binary
59
- if (!quiet) {
60
- console.log("Step 3/3: Copying output binary...");
61
- }
62
-
63
- const binaryName =
64
- process.platform === "win32" ? `${outputName}.exe` : outputName;
65
- const publishDir = join(
66
- generatedDir,
67
- "bin",
68
- "Release",
69
- config.dotnetVersion,
70
- rid,
71
- "publish"
72
- );
73
- const sourceBinary = join(publishDir, binaryName);
74
- const targetBinary = join(process.cwd(), binaryName);
75
-
76
- if (!existsSync(sourceBinary)) {
77
- return {
78
- ok: false,
79
- error: `Built binary not found at ${sourceBinary}`,
80
- };
81
- }
82
-
83
- try {
84
- copyFileSync(sourceBinary, targetBinary);
85
-
86
- // Make executable on Unix
87
- if (process.platform !== "win32") {
88
- chmodSync(targetBinary, 0o755);
89
- }
90
-
91
- if (!quiet) {
92
- const relativePath = relative(process.cwd(), targetBinary);
93
- console.log(`\n✓ Build complete: ${relativePath}`);
94
- }
95
-
96
- return {
97
- ok: true,
98
- value: { outputPath: targetBinary },
99
- };
100
- } catch (error) {
101
- return {
102
- ok: false,
103
- error: `Failed to copy binary: ${error instanceof Error ? error.message : String(error)}`,
104
- };
105
- }
106
- };
107
-
108
- /**
109
- * Build library
110
- */
111
- const buildLibrary = (
112
- config: ResolvedConfig,
113
- generatedDir: string
114
- ): Result<{ outputPath: string }, string> => {
115
- const { outputName, quiet, verbose } = config;
116
- const targetFrameworks = config.outputConfig.targetFrameworks ?? [
117
- config.dotnetVersion,
118
- ];
119
-
120
- // Step 2: Run dotnet build
121
- if (!quiet) {
122
- console.log("Step 2/3: Compiling library with dotnet build...");
123
- }
124
-
125
- const buildArgs = ["build", "tsonic.csproj", "-c", "Release", "--nologo"];
126
-
127
- if (quiet) {
128
- buildArgs.push("--verbosity", "quiet");
129
- } else if (verbose) {
130
- buildArgs.push("--verbosity", "detailed");
131
- } else {
132
- buildArgs.push("--verbosity", "minimal");
133
- }
134
-
135
- const buildResult = spawnSync("dotnet", buildArgs, {
136
- cwd: generatedDir,
137
- stdio: verbose ? "inherit" : "pipe",
138
- encoding: "utf-8",
139
- });
140
-
141
- if (buildResult.status !== 0) {
142
- const errorMsg =
143
- buildResult.stderr || buildResult.stdout || "Unknown error";
144
- return {
145
- ok: false,
146
- error: `dotnet build failed:\n${errorMsg}`,
147
- };
148
- }
149
-
150
- // Step 3: Copy output library artifacts
151
- if (!quiet) {
152
- console.log("Step 3/3: Copying library artifacts...");
153
- }
154
-
155
- const outputDir = join(process.cwd(), "dist");
156
-
157
- try {
158
- // Create output directory
159
- if (!existsSync(outputDir)) {
160
- mkdirSync(outputDir, { recursive: true });
161
- }
162
-
163
- // Copy artifacts for each target framework
164
- const copiedFiles: string[] = [];
165
-
166
- for (const framework of targetFrameworks) {
167
- const buildDir = join(generatedDir, "bin", "Release", framework);
168
-
169
- if (!existsSync(buildDir)) {
170
- continue;
171
- }
172
-
173
- const frameworkOutputDir = join(outputDir, framework);
174
- if (!existsSync(frameworkOutputDir)) {
175
- mkdirSync(frameworkOutputDir, { recursive: true });
176
- }
177
-
178
- // Copy .dll
179
- const dllSource = join(buildDir, `${outputName}.dll`);
180
- if (existsSync(dllSource)) {
181
- const dllTarget = join(frameworkOutputDir, `${outputName}.dll`);
182
- copyFileSync(dllSource, dllTarget);
183
- copiedFiles.push(relative(process.cwd(), dllTarget));
184
- }
185
-
186
- // Copy .xml (documentation)
187
- const xmlSource = join(buildDir, `${outputName}.xml`);
188
- if (existsSync(xmlSource)) {
189
- const xmlTarget = join(frameworkOutputDir, `${outputName}.xml`);
190
- copyFileSync(xmlSource, xmlTarget);
191
- copiedFiles.push(relative(process.cwd(), xmlTarget));
192
- }
193
-
194
- // Copy .pdb (symbols)
195
- const pdbSource = join(buildDir, `${outputName}.pdb`);
196
- if (existsSync(pdbSource)) {
197
- const pdbTarget = join(frameworkOutputDir, `${outputName}.pdb`);
198
- copyFileSync(pdbSource, pdbTarget);
199
- copiedFiles.push(relative(process.cwd(), pdbTarget));
200
- }
201
- }
202
-
203
- if (copiedFiles.length === 0) {
204
- return {
205
- ok: false,
206
- error: "No library artifacts found to copy",
207
- };
208
- }
209
-
210
- if (!quiet) {
211
- console.log(`\n✓ Build complete. Artifacts copied to dist/:`);
212
- for (const file of copiedFiles) {
213
- console.log(` - ${file}`);
214
- }
215
- }
216
-
217
- return {
218
- ok: true,
219
- value: { outputPath: outputDir },
220
- };
221
- } catch (error) {
222
- return {
223
- ok: false,
224
- error: `Failed to copy library artifacts: ${error instanceof Error ? error.message : String(error)}`,
225
- };
226
- }
227
- };
228
-
229
- /**
230
- * Main build command - dispatches to executable or library build
231
- */
232
- export const buildCommand = (
233
- config: ResolvedConfig
234
- ): Result<{ outputPath: string }, string> => {
235
- const { outputDirectory, quiet } = config;
236
- const outputType = config.outputConfig.type ?? "executable";
237
-
238
- // Step 1: Emit C# code
239
- if (!quiet) {
240
- console.log("Step 1/3: Generating C# code...");
241
- }
242
-
243
- const emitResult = emitCommand(config);
244
- if (!emitResult.ok) {
245
- return emitResult;
246
- }
247
-
248
- const generatedDir = emitResult.value.outputDir;
249
- const csprojPath = join(generatedDir, "tsonic.csproj");
250
-
251
- if (!existsSync(csprojPath)) {
252
- return {
253
- ok: false,
254
- error: `No tsonic.csproj found in ${outputDirectory}/. This should have been created by emit.`,
255
- };
256
- }
257
-
258
- // Dispatch to appropriate build function
259
- if (outputType === "library") {
260
- return buildLibrary(config, generatedDir);
261
- } else {
262
- return buildExecutable(config, generatedDir);
263
- }
264
- };