@dusted/anqst 0.1.1 → 0.1.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/README.md +99 -117
- package/dist/src/app.js +180 -272
- package/dist/src/build-stamp.js +5 -0
- package/dist/src/{backend/tsc/debug-dump.js → debug-dump.js} +2 -1
- package/dist/src/emit.js +368 -170
- package/dist/src/layout.js +70 -0
- package/dist/src/parser.js +124 -6
- package/dist/src/{backend/tsc/program.js → program.js} +1 -1
- package/dist/src/project.js +220 -137
- package/dist/src/verify.js +15 -2
- package/index.d.ts +1 -0
- package/package.json +7 -2
- package/spec/AnQst-Spec-DSL.d.ts +49 -17
- package/dist/src/backend/ast/emit.js +0 -5
- package/dist/src/backend/ast/index.js +0 -13
- package/dist/src/backend/ast/parser.js +0 -5
- package/dist/src/backend/ast/verify.js +0 -5
- package/dist/src/backend/index.js +0 -16
- package/dist/src/backend/tsc/emit-cpp.js +0 -13
- package/dist/src/backend/tsc/emit-node.js +0 -13
- package/dist/src/backend/tsc/index.js +0 -41
- package/dist/src/backend/tsc/parser.js +0 -19
- package/dist/src/backend/tsc/verify.js +0 -13
- package/dist/src/backend/types.js +0 -2
- /package/dist/src/{backend/tsc/typegraph.js → typegraph.js} +0 -0
package/dist/src/app.js
CHANGED
|
@@ -13,148 +13,135 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_child_process_1 = require("node:child_process");
|
|
15
15
|
const errors_1 = require("./errors");
|
|
16
|
+
const debug_dump_1 = require("./debug-dump");
|
|
16
17
|
const emit_1 = require("./emit");
|
|
17
18
|
const project_1 = require("./project");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return targets;
|
|
23
|
-
// tsc backend currently supports QWidget and node_express_ws emitters only.
|
|
24
|
-
return {
|
|
25
|
-
emitQWidget: targets.emitQWidget,
|
|
26
|
-
emitAngularService: false,
|
|
27
|
-
emitNodeExpressWs: targets.emitNodeExpressWs
|
|
28
|
-
};
|
|
29
|
-
}
|
|
19
|
+
const layout_1 = require("./layout");
|
|
20
|
+
const parser_1 = require("./parser");
|
|
21
|
+
const verify_1 = require("./verify");
|
|
22
|
+
const build_stamp_1 = require("./build-stamp");
|
|
30
23
|
function renderHelp() {
|
|
24
|
+
const version = readActiveBuildStamp();
|
|
31
25
|
return [
|
|
26
|
+
`anqst version ${version}`,
|
|
27
|
+
"",
|
|
32
28
|
"Usage:",
|
|
33
29
|
" anqst <command> [arguments] [options]",
|
|
34
30
|
"",
|
|
35
31
|
"Commands:",
|
|
36
32
|
" instill <WidgetName> Initialize AnQst in current npm project",
|
|
37
|
-
" test Verify
|
|
38
|
-
" build [--
|
|
39
|
-
" generate <specFile>
|
|
40
|
-
" verify <specFile>
|
|
33
|
+
" test Verify AnQst spec from package settings",
|
|
34
|
+
" build [--designerplugin[=true|false]] Generate artifacts from package settings",
|
|
35
|
+
" generate <specFile> Generate artifacts from explicit spec file",
|
|
36
|
+
" verify <specFile> Verify explicit spec file only",
|
|
41
37
|
" clean <path> [-f|--force] Remove generated artifacts under path",
|
|
42
38
|
"",
|
|
43
39
|
"Options:",
|
|
44
|
-
" --
|
|
45
|
-
" --
|
|
46
|
-
" -
|
|
40
|
+
" --designerplugin Build Qt Designer plugin (build command only, QWidget target required)",
|
|
41
|
+
" -h, --help Show this help output",
|
|
42
|
+
" -v, --version Print CLI version"
|
|
47
43
|
].join("\n");
|
|
48
44
|
}
|
|
49
45
|
function usageFor(command) {
|
|
50
46
|
if (command === "instill")
|
|
51
47
|
return "Usage: anqst instill <WidgetName>";
|
|
52
48
|
if (command === "build")
|
|
53
|
-
return "Usage: anqst build [--
|
|
49
|
+
return "Usage: anqst build [--designerplugin[=true|false]]";
|
|
54
50
|
if (command === "verify")
|
|
55
|
-
return "Usage: anqst verify <specFile>
|
|
51
|
+
return "Usage: anqst verify <specFile>";
|
|
56
52
|
if (command === "generate")
|
|
57
|
-
return "Usage: anqst generate <specFile>
|
|
53
|
+
return "Usage: anqst generate <specFile>";
|
|
58
54
|
if (command === "clean")
|
|
59
55
|
return "Usage: anqst clean <path> [-f|--force]";
|
|
60
56
|
return renderHelp();
|
|
61
57
|
}
|
|
62
|
-
function
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
success: true,
|
|
69
|
-
message: verification.message
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function runGenerate(specArg, backendId = "ast") {
|
|
73
|
-
const cwd = process.cwd();
|
|
74
|
-
const specPath = node_path_1.default.resolve(cwd, specArg);
|
|
75
|
-
const backend = (0, backend_1.resolveBackend)(backendId);
|
|
76
|
-
const parsed = backend.parseSpecFile(specPath);
|
|
77
|
-
const verification = backend.verifySpec(parsed);
|
|
78
|
-
const generationTargets = generationTargetsForBackend(backend.id, resolveGenerationTargetsFromCwd(cwd));
|
|
79
|
-
const outputs = backend.generateOutputs(parsed, generationTargets);
|
|
80
|
-
if (backend.emitsArtifacts) {
|
|
81
|
-
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
82
|
-
if (generationTargets.emitAngularService) {
|
|
83
|
-
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
84
|
-
}
|
|
85
|
-
if (generationTargets.emitQWidget) {
|
|
86
|
-
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
87
|
-
}
|
|
58
|
+
function resetGeneratedTargets(cwd, widgetName, targets) {
|
|
59
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
60
|
+
const roots = new Set();
|
|
61
|
+
if (targets.emitAngularService) {
|
|
62
|
+
roots.add(layout.frontendRoot);
|
|
88
63
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
64
|
+
if (targets.emitNodeExpressWs) {
|
|
65
|
+
roots.add(layout.nodeExpressRoot);
|
|
66
|
+
}
|
|
67
|
+
if (targets.emitQWidget) {
|
|
68
|
+
roots.add(layout.cppQtWidgetRoot);
|
|
69
|
+
roots.add(layout.cppCmakeRoot);
|
|
70
|
+
}
|
|
71
|
+
if ((0, debug_dump_1.isDebugEnabled)()) {
|
|
72
|
+
roots.add(layout.debugIntermediateRoot);
|
|
73
|
+
}
|
|
74
|
+
for (const root of roots) {
|
|
75
|
+
node_fs_1.default.rmSync(root, { recursive: true, force: true });
|
|
96
76
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
const
|
|
77
|
+
}
|
|
78
|
+
function buildGenerateSummary(cwd, specPath, widgetName, generationTargets) {
|
|
79
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
80
|
+
const relativeSpecFile = (0, layout_1.normalizeSlashes)(node_path_1.default.relative(cwd, specPath));
|
|
81
|
+
const servicePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"));
|
|
82
|
+
const typePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"));
|
|
83
|
+
const widgetRootPath = (0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot);
|
|
84
|
+
const nodePath = (0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot);
|
|
102
85
|
const messageLines = [];
|
|
103
86
|
messageLines.push(`AnQst spec ${relativeSpecFile} built.`);
|
|
104
87
|
if (generationTargets.emitAngularService) {
|
|
105
|
-
messageLines.push(` Services
|
|
106
|
-
messageLines.push(` Generated types are available from ${
|
|
88
|
+
messageLines.push(` Services are available from ${servicePath}.`);
|
|
89
|
+
messageLines.push(` Generated types are available from ${typePath}.`);
|
|
107
90
|
}
|
|
108
91
|
if (generationTargets.emitQWidget) {
|
|
109
|
-
messageLines.push(` Widget library available in ${
|
|
92
|
+
messageLines.push(` Widget library available in ${widgetRootPath}.`);
|
|
110
93
|
}
|
|
111
94
|
if (generationTargets.emitNodeExpressWs) {
|
|
112
|
-
messageLines.push(` Node Express WS module available in ${
|
|
95
|
+
messageLines.push(` Node Express WS module available in ${nodePath}.`);
|
|
113
96
|
}
|
|
114
97
|
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
115
98
|
messageLines.push(" No outputs selected by AnQst.generate.");
|
|
116
99
|
}
|
|
100
|
+
return `\n${messageLines.join("\n")}\n`;
|
|
101
|
+
}
|
|
102
|
+
function runVerify(specArg) {
|
|
103
|
+
const specPath = node_path_1.default.resolve(process.cwd(), specArg);
|
|
104
|
+
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
105
|
+
const verification = (0, verify_1.verifySpec)(parsed);
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
message: verification.message
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function runGenerate(specArg) {
|
|
112
|
+
const cwd = process.cwd();
|
|
113
|
+
const specPath = node_path_1.default.resolve(cwd, specArg);
|
|
114
|
+
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
115
|
+
const verification = (0, verify_1.verifySpec)(parsed);
|
|
116
|
+
const generationTargets = resolveGenerationTargetsFromCwd(cwd);
|
|
117
|
+
resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
|
|
118
|
+
const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
|
|
119
|
+
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
120
|
+
if (generationTargets.emitQWidget) {
|
|
121
|
+
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
122
|
+
}
|
|
117
123
|
return {
|
|
118
124
|
success: true,
|
|
119
125
|
verificationMessage: verification.message,
|
|
120
|
-
message:
|
|
126
|
+
message: buildGenerateSummary(cwd, specPath, parsed.widgetName, generationTargets)
|
|
121
127
|
};
|
|
122
128
|
}
|
|
123
129
|
function runTest(cwd) {
|
|
124
130
|
const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const verification = backend.verifySpec(parsed);
|
|
131
|
+
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
132
|
+
const verification = (0, verify_1.verifySpec)(parsed);
|
|
128
133
|
return {
|
|
129
134
|
success: true,
|
|
130
135
|
message: verification.message
|
|
131
136
|
};
|
|
132
137
|
}
|
|
133
|
-
function resolveAnQstGenRoot() {
|
|
134
|
-
return node_path_1.default.resolve(__dirname, "..", "..");
|
|
135
|
-
}
|
|
136
138
|
function readActiveBuildStamp() {
|
|
137
|
-
|
|
138
|
-
return process.env.ANQST_BUILD_STAMP.trim();
|
|
139
|
-
}
|
|
140
|
-
const activePath = node_path_1.default.join(resolveAnQstGenRoot(), ANQSTGEN_ACTIVE_STAMP_FILE);
|
|
141
|
-
if (!node_fs_1.default.existsSync(activePath)) {
|
|
142
|
-
return "unknown_build_0";
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
const parsed = JSON.parse(node_fs_1.default.readFileSync(activePath, "utf8"));
|
|
146
|
-
if (typeof parsed.active === "string" && parsed.active.trim().length > 0) {
|
|
147
|
-
return parsed.active.trim();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
// Fallback to deterministic unknown stamp.
|
|
152
|
-
}
|
|
153
|
-
return "unknown_build_0";
|
|
139
|
+
return build_stamp_1.ANQST_BUILD_STAMP;
|
|
154
140
|
}
|
|
155
|
-
function runDesignerPluginBuild(cwd) {
|
|
156
|
-
const
|
|
157
|
-
const
|
|
141
|
+
function runDesignerPluginBuild(cwd, widgetName) {
|
|
142
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
143
|
+
const pluginSourceDir = layout.designerPluginRoot;
|
|
144
|
+
const pluginBuildDir = layout.designerPluginBuildRoot;
|
|
158
145
|
const webBaseDir = process.env.ANQST_WEBBASE_DIR?.trim();
|
|
159
146
|
if (!webBaseDir) {
|
|
160
147
|
throw new errors_1.VerifyError("Missing ANQST_WEBBASE_DIR environment variable for --designerplugin build.");
|
|
@@ -187,181 +174,117 @@ function runDesignerPluginBuild(cwd) {
|
|
|
187
174
|
throw new errors_1.VerifyError("CMake build failed while compiling Qt Designer plugin.");
|
|
188
175
|
}
|
|
189
176
|
}
|
|
190
|
-
function runBuild(cwd,
|
|
177
|
+
function runBuild(cwd, designerPlugin = false) {
|
|
191
178
|
const buildVersion = readActiveBuildStamp();
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
|
|
216
|
-
if (hasAngularProject && generationTargets.emitQWidget) {
|
|
217
|
-
const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
|
|
218
|
-
cwd,
|
|
219
|
-
stdio: "inherit",
|
|
220
|
-
shell: process.platform === "win32"
|
|
221
|
-
});
|
|
222
|
-
if (angularBuild.status !== 0) {
|
|
223
|
-
throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (generationTargets.emitQWidget) {
|
|
227
|
-
const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
|
|
228
|
-
if (hasAngularProject && !embedded) {
|
|
229
|
-
throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
let designerPluginBuilt = false;
|
|
233
|
-
if (designerPlugin) {
|
|
234
|
-
if (backend.id !== "tsc") {
|
|
235
|
-
console.warn("[AnQst] --designerplugin is only supported with --backend tsc. Skipping designer plugin build.");
|
|
236
|
-
}
|
|
237
|
-
else if (!generationTargets.emitQWidget) {
|
|
238
|
-
console.warn("[AnQst] --designerplugin requested but QWidget target is not enabled. Skipping designer plugin build.");
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
const widgetCategory = (0, project_1.resolveAnQstWidgetCategory)(cwd);
|
|
242
|
-
(0, emit_1.installQtDesignerPluginCMake)(cwd, parsed.widgetName, { widgetCategory });
|
|
243
|
-
runDesignerPluginBuild(cwd);
|
|
244
|
-
designerPluginBuilt = true;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
248
|
-
return {
|
|
249
|
-
success: true,
|
|
250
|
-
message: [
|
|
251
|
-
"Build completed.",
|
|
252
|
-
` anqst version ${buildVersion}`,
|
|
253
|
-
" No outputs selected by AnQst.generate."
|
|
254
|
-
].join("\n")
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
const detailLines = [];
|
|
258
|
-
if (generationTargets.emitAngularService) {
|
|
259
|
-
detailLines.push(" Target AngularService:");
|
|
260
|
-
detailLines.push(" - Services output: src/anqst-generated/services");
|
|
261
|
-
detailLines.push(" - Types output: src/anqst-generated/types");
|
|
179
|
+
const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
|
|
180
|
+
const configuredWidgetName = (0, project_1.resolveAnQstWidgetName)(cwd);
|
|
181
|
+
const generationTargets = resolveGenerationTargetsFromCwd(cwd, true);
|
|
182
|
+
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
183
|
+
(0, verify_1.verifySpec)(parsed);
|
|
184
|
+
if (parsed.widgetName !== configuredWidgetName) {
|
|
185
|
+
throw new errors_1.VerifyError(`Settings widgetName '${configuredWidgetName}' does not match spec namespace '${parsed.widgetName}'.`);
|
|
186
|
+
}
|
|
187
|
+
resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
|
|
188
|
+
const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
|
|
189
|
+
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
190
|
+
if (generationTargets.emitQWidget) {
|
|
191
|
+
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
192
|
+
}
|
|
193
|
+
const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
|
|
194
|
+
if (hasAngularProject) {
|
|
195
|
+
const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
|
|
196
|
+
cwd,
|
|
197
|
+
stdio: "inherit",
|
|
198
|
+
shell: process.platform === "win32"
|
|
199
|
+
});
|
|
200
|
+
if (angularBuild.status !== 0) {
|
|
201
|
+
throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
|
|
262
202
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
203
|
+
}
|
|
204
|
+
if (generationTargets.emitQWidget) {
|
|
205
|
+
const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
|
|
206
|
+
if (hasAngularProject && !embedded) {
|
|
207
|
+
throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
|
|
268
208
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
209
|
+
}
|
|
210
|
+
let designerPluginBuilt = false;
|
|
211
|
+
if (designerPlugin) {
|
|
212
|
+
if (!generationTargets.emitQWidget) {
|
|
213
|
+
console.warn("[AnQst] --designerplugin requested but QWidget target is not enabled. Skipping designer plugin build.");
|
|
272
214
|
}
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
detailLines.push(" - Install target dir: <QT_INSTALL_PLUGINS>/designer");
|
|
279
|
-
detailLines.push(" - Discover QT_INSTALL_PLUGINS: qmake -query QT_INSTALL_PLUGINS");
|
|
280
|
-
detailLines.push(` - Example install: cp ${pluginBinaryPath} "$(qmake -query QT_INSTALL_PLUGINS)/designer/"`);
|
|
281
|
-
detailLines.push(` - User-local install: mkdir -p "$HOME/.local/lib/qt5/plugins/designer" && cp ${pluginBinaryPath} "$HOME/.local/lib/qt5/plugins/designer/"`);
|
|
215
|
+
else {
|
|
216
|
+
const widgetCategory = (0, project_1.resolveAnQstWidgetCategory)(cwd);
|
|
217
|
+
(0, emit_1.installQtDesignerPluginCMake)(cwd, parsed.widgetName, { widgetCategory });
|
|
218
|
+
runDesignerPluginBuild(cwd, parsed.widgetName);
|
|
219
|
+
designerPluginBuilt = true;
|
|
282
220
|
}
|
|
221
|
+
}
|
|
222
|
+
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
283
223
|
return {
|
|
284
224
|
success: true,
|
|
285
225
|
message: [
|
|
286
226
|
"Build completed.",
|
|
287
227
|
` anqst version ${buildVersion}`,
|
|
288
|
-
|
|
228
|
+
" No outputs selected by AnQst.generate."
|
|
289
229
|
].join("\n")
|
|
290
230
|
};
|
|
291
231
|
}
|
|
292
|
-
|
|
293
|
-
|
|
232
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, parsed.widgetName);
|
|
233
|
+
const detailLines = [];
|
|
234
|
+
if (generationTargets.emitAngularService) {
|
|
235
|
+
detailLines.push(" Target AngularService:");
|
|
236
|
+
detailLines.push(` - Services output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"))}`);
|
|
237
|
+
detailLines.push(` - Types output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"))}`);
|
|
238
|
+
}
|
|
239
|
+
if (generationTargets.emitQWidget) {
|
|
240
|
+
detailLines.push(" Target QWidget:");
|
|
241
|
+
detailLines.push(` - Qt integration CMake: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.cppCmakeRoot, "CMakeLists.txt"))}`);
|
|
242
|
+
detailLines.push(` - Widget output root: ${(0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot)}`);
|
|
243
|
+
detailLines.push(" - Embedded web assets refreshed from Angular build");
|
|
244
|
+
}
|
|
245
|
+
if (generationTargets.emitNodeExpressWs) {
|
|
246
|
+
detailLines.push(" Target node_express_ws:");
|
|
247
|
+
detailLines.push(` - Module output root: ${(0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot)}`);
|
|
248
|
+
}
|
|
249
|
+
if (designerPluginBuilt) {
|
|
250
|
+
const pluginBinaryPath = (0, layout_1.normalizeSlashes)(node_path_1.default.join((0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot), designerPluginBinaryName(parsed.widgetName)));
|
|
251
|
+
detailLines.push(" Target QtDesignerPlugin:");
|
|
252
|
+
detailLines.push(` - Build output: ${(0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot)}`);
|
|
253
|
+
detailLines.push(` - Plugin binary: ${pluginBinaryPath}`);
|
|
254
|
+
detailLines.push(" - Install target dir: <QT_INSTALL_PLUGINS>/designer");
|
|
255
|
+
detailLines.push(" - Discover QT_INSTALL_PLUGINS: qmake -query QT_INSTALL_PLUGINS");
|
|
256
|
+
detailLines.push(` - Example install: cp ${pluginBinaryPath} \"$(qmake -query QT_INSTALL_PLUGINS)/designer/\"`);
|
|
257
|
+
detailLines.push(` - User-local install: mkdir -p \"$HOME/.local/lib/qt5/plugins/designer\" && cp ${pluginBinaryPath} \"$HOME/.local/lib/qt5/plugins/designer/\"`);
|
|
294
258
|
}
|
|
259
|
+
return {
|
|
260
|
+
success: true,
|
|
261
|
+
message: [
|
|
262
|
+
"Build completed.",
|
|
263
|
+
` anqst version ${buildVersion}`,
|
|
264
|
+
...detailLines
|
|
265
|
+
].join("\n")
|
|
266
|
+
};
|
|
295
267
|
}
|
|
296
|
-
function
|
|
268
|
+
function parseSpecCommandArg(commandName, specArg, extraArgs) {
|
|
297
269
|
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
298
|
-
let backendId = "ast";
|
|
299
270
|
const positional = [];
|
|
300
|
-
for (
|
|
301
|
-
const arg = allArgs[i];
|
|
302
|
-
if (arg === "--backend") {
|
|
303
|
-
const value = allArgs[i + 1];
|
|
304
|
-
if (!value || value.startsWith("-")) {
|
|
305
|
-
throw new Error(`Missing value for --backend. ${usageFor(commandName)}`);
|
|
306
|
-
}
|
|
307
|
-
if (!(0, backend_1.isBackendId)(value)) {
|
|
308
|
-
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
309
|
-
}
|
|
310
|
-
backendId = value;
|
|
311
|
-
i += 1;
|
|
312
|
-
continue;
|
|
313
|
-
}
|
|
314
|
-
if (arg.startsWith("--backend=")) {
|
|
315
|
-
const value = arg.slice("--backend=".length);
|
|
316
|
-
if (!(0, backend_1.isBackendId)(value)) {
|
|
317
|
-
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
318
|
-
}
|
|
319
|
-
backendId = value;
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
271
|
+
for (const arg of allArgs) {
|
|
322
272
|
if (arg.startsWith("-")) {
|
|
323
273
|
throw new Error(`Unknown ${commandName} flag '${arg}'. ${usageFor(commandName)}`);
|
|
324
274
|
}
|
|
325
275
|
positional.push(arg);
|
|
326
276
|
}
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
throw new Error(usageFor(commandName));
|
|
330
|
-
}
|
|
331
|
-
return { backendId, specArg: positional[0] };
|
|
277
|
+
if (positional.length !== 1) {
|
|
278
|
+
throw new Error(usageFor(commandName));
|
|
332
279
|
}
|
|
333
|
-
|
|
334
|
-
throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor(commandName)}`);
|
|
335
|
-
}
|
|
336
|
-
return { backendId };
|
|
280
|
+
return positional[0];
|
|
337
281
|
}
|
|
338
282
|
function parseBuildCommandArgs(specArg, extraArgs) {
|
|
339
283
|
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
340
|
-
let backendId = "ast";
|
|
341
284
|
let designerPlugin = false;
|
|
342
285
|
const positional = [];
|
|
343
286
|
for (let i = 0; i < allArgs.length; i += 1) {
|
|
344
287
|
const arg = allArgs[i];
|
|
345
|
-
if (arg === "--backend") {
|
|
346
|
-
const value = allArgs[i + 1];
|
|
347
|
-
if (!value || value.startsWith("-")) {
|
|
348
|
-
throw new Error(`Missing value for --backend. ${usageFor("build")}`);
|
|
349
|
-
}
|
|
350
|
-
if (!(0, backend_1.isBackendId)(value)) {
|
|
351
|
-
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
352
|
-
}
|
|
353
|
-
backendId = value;
|
|
354
|
-
i += 1;
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
if (arg.startsWith("--backend=")) {
|
|
358
|
-
const value = arg.slice("--backend=".length);
|
|
359
|
-
if (!(0, backend_1.isBackendId)(value)) {
|
|
360
|
-
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
361
|
-
}
|
|
362
|
-
backendId = value;
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
288
|
if (arg === "--designerplugin") {
|
|
366
289
|
const value = allArgs[i + 1];
|
|
367
290
|
if (value && !value.startsWith("-")) {
|
|
@@ -386,7 +309,7 @@ function parseBuildCommandArgs(specArg, extraArgs) {
|
|
|
386
309
|
if (positional.length > 0) {
|
|
387
310
|
throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor("build")}`);
|
|
388
311
|
}
|
|
389
|
-
return {
|
|
312
|
+
return { designerPlugin };
|
|
390
313
|
}
|
|
391
314
|
function parseCleanCommandArgs(specArg, extraArgs) {
|
|
392
315
|
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
@@ -442,7 +365,7 @@ function formatCleanResult(targetRoot, rows) {
|
|
|
442
365
|
const notFound = rows.filter((row) => row.status === "not_found");
|
|
443
366
|
const failed = rows.filter((row) => row.status === "failed");
|
|
444
367
|
const lines = [];
|
|
445
|
-
lines.push(`[AnQst] Clean summary for ${normalizeSlashes(targetRoot)}`);
|
|
368
|
+
lines.push(`[AnQst] Clean summary for ${(0, layout_1.normalizeSlashes)(targetRoot)}`);
|
|
446
369
|
if (deleted.length > 0) {
|
|
447
370
|
lines.push(` Deleted (${deleted.length})`);
|
|
448
371
|
for (const row of deleted)
|
|
@@ -464,14 +387,14 @@ function resolveGenerationTargetsFromCwd(cwd, requirePackageAnQst = false) {
|
|
|
464
387
|
const packagePath = node_path_1.default.join(cwd, "package.json");
|
|
465
388
|
if (!node_fs_1.default.existsSync(packagePath)) {
|
|
466
389
|
if (requirePackageAnQst) {
|
|
467
|
-
throw new errors_1.VerifyError("No package.json:
|
|
390
|
+
throw new errors_1.VerifyError("No package.json: AnQst commands must run inside an npm project.");
|
|
468
391
|
}
|
|
469
392
|
return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
|
|
470
393
|
}
|
|
471
394
|
const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
|
|
472
395
|
if (packageJson.AnQst === undefined) {
|
|
473
396
|
if (requirePackageAnQst) {
|
|
474
|
-
throw new errors_1.VerifyError("Missing package.json key 'AnQst
|
|
397
|
+
throw new errors_1.VerifyError("Missing package.json key 'AnQst'. Run 'anqst instill <WidgetName>' first.");
|
|
475
398
|
}
|
|
476
399
|
return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
|
|
477
400
|
}
|
|
@@ -484,40 +407,24 @@ function toGenerationTargets(targets) {
|
|
|
484
407
|
emitNodeExpressWs: targets.includes("node_express_ws")
|
|
485
408
|
};
|
|
486
409
|
}
|
|
487
|
-
function resolveAnQstSpecFromPackage(targetRoot) {
|
|
488
|
-
const packagePath = node_path_1.default.join(targetRoot, "package.json");
|
|
489
|
-
if (!node_fs_1.default.existsSync(packagePath)) {
|
|
490
|
-
throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
|
|
491
|
-
}
|
|
492
|
-
const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
|
|
493
|
-
const spec = packageJson.AnQst?.spec;
|
|
494
|
-
if (!spec || spec.trim().length === 0) {
|
|
495
|
-
throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
|
|
496
|
-
}
|
|
497
|
-
return node_path_1.default.resolve(targetRoot, spec);
|
|
498
|
-
}
|
|
499
410
|
function runClean(pathArg, force) {
|
|
500
411
|
const targetRoot = node_path_1.default.resolve(process.cwd(), pathArg);
|
|
501
|
-
const broadDirs = [
|
|
502
|
-
"generated_output",
|
|
503
|
-
node_path_1.default.join("src", "anqst-generated"),
|
|
504
|
-
"anqst-cmake"
|
|
505
|
-
];
|
|
506
412
|
if (force) {
|
|
507
|
-
const rows = runCleanup(targetRoot,
|
|
413
|
+
const rows = runCleanup(targetRoot, [(0, layout_1.normalizeSlashes)(node_path_1.default.join("AnQst", "generated"))]);
|
|
508
414
|
return {
|
|
509
415
|
success: true,
|
|
510
416
|
message: formatCleanResult(targetRoot, rows),
|
|
511
417
|
hadFailures: rows.some((row) => row.status === "failed")
|
|
512
418
|
};
|
|
513
419
|
}
|
|
514
|
-
const
|
|
515
|
-
const
|
|
420
|
+
const context = (0, project_1.resolveAnQstSettings)(targetRoot);
|
|
421
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(targetRoot, context.settings.widgetName);
|
|
516
422
|
const widgetDirs = [
|
|
517
|
-
node_path_1.default.
|
|
518
|
-
node_path_1.default.
|
|
519
|
-
node_path_1.default.
|
|
520
|
-
|
|
423
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.frontendRoot)),
|
|
424
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.nodeExpressRoot)),
|
|
425
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppQtWidgetRoot)),
|
|
426
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppCmakeRoot)),
|
|
427
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.debugIntermediateRoot))
|
|
521
428
|
];
|
|
522
429
|
const rows = runCleanup(targetRoot, widgetDirs);
|
|
523
430
|
return {
|
|
@@ -526,9 +433,6 @@ function runClean(pathArg, force) {
|
|
|
526
433
|
hadFailures: rows.some((row) => row.status === "failed")
|
|
527
434
|
};
|
|
528
435
|
}
|
|
529
|
-
function normalizeSlashes(inputPath) {
|
|
530
|
-
return inputPath.split(node_path_1.default.sep).join("/");
|
|
531
|
-
}
|
|
532
436
|
function designerPluginBinaryName(widgetName) {
|
|
533
437
|
const targetName = `${widgetName}DesignerPlugin`;
|
|
534
438
|
if (process.platform === "win32") {
|
|
@@ -556,6 +460,10 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
556
460
|
console.log(renderHelp());
|
|
557
461
|
return 0;
|
|
558
462
|
}
|
|
463
|
+
if (command === "-v" || command === "--version" || command === "version") {
|
|
464
|
+
console.log(`anqst version ${readActiveBuildStamp()}`);
|
|
465
|
+
return 0;
|
|
466
|
+
}
|
|
559
467
|
const normalizedCommand = command === "install" ? "instill" : command;
|
|
560
468
|
if (command === "install") {
|
|
561
469
|
console.log(renderInstallAliasMessage());
|
|
@@ -576,19 +484,19 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
576
484
|
}
|
|
577
485
|
if (normalizedCommand === "build") {
|
|
578
486
|
const parsedArgs = parseBuildCommandArgs(specArg, extraArgs);
|
|
579
|
-
const res = runBuild(process.cwd(), parsedArgs.
|
|
487
|
+
const res = runBuild(process.cwd(), parsedArgs.designerPlugin);
|
|
580
488
|
console.log(res.message);
|
|
581
489
|
return 0;
|
|
582
490
|
}
|
|
583
491
|
if (normalizedCommand === "verify") {
|
|
584
|
-
const
|
|
585
|
-
const res = runVerify(
|
|
492
|
+
const specArgParsed = parseSpecCommandArg("verify", specArg, extraArgs);
|
|
493
|
+
const res = runVerify(specArgParsed);
|
|
586
494
|
console.log(res.message);
|
|
587
495
|
return 0;
|
|
588
496
|
}
|
|
589
497
|
if (normalizedCommand === "generate") {
|
|
590
|
-
const
|
|
591
|
-
const res = runGenerate(
|
|
498
|
+
const specArgParsed = parseSpecCommandArg("generate", specArg, extraArgs);
|
|
499
|
+
const res = runGenerate(specArgParsed);
|
|
592
500
|
if (res.verificationMessage) {
|
|
593
501
|
console.log(res.verificationMessage);
|
|
594
502
|
}
|
|
@@ -9,11 +9,12 @@ exports.inspectText = inspectText;
|
|
|
9
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const node_util_1 = __importDefault(require("node:util"));
|
|
12
|
+
const layout_1 = require("./layout");
|
|
12
13
|
function isDebugEnabled() {
|
|
13
14
|
return process.env.ANQST_DEBUG === "true";
|
|
14
15
|
}
|
|
15
16
|
function baseIntermediateDir(cwd) {
|
|
16
|
-
return
|
|
17
|
+
return (0, layout_1.anqstDebugIntermediateRootDir)(cwd);
|
|
17
18
|
}
|
|
18
19
|
function writeDebugFile(cwd, relativePath, content) {
|
|
19
20
|
if (!isDebugEnabled())
|