clispark 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli.js +241 -131
- package/dist/cli.js.map +1 -1
- package/package.json +5 -2
- package/templates/dotnet/ARCHITECTURE.md +19 -0
- package/templates/dotnet/src/Cli.csproj +7 -0
- package/templates/dotnet/src/Logging/CliLoggerFactory.cs +4 -3
- package/templates/node/.prettierignore +1 -0
- package/templates/node/.prettierrc +5 -0
- package/templates/node/ARCHITECTURE.md +22 -8
- package/templates/node/eslint.config.js +18 -0
- package/templates/node/package.json +7 -0
- package/templates/node/src/commands/task/complete.ts +2 -1
- package/templates/node/src/commands/task/list.test.ts +3 -1
- package/templates/node/src/commands/task/list.ts +9 -3
- package/templates/node/src/commands/task.test.ts +3 -1
- package/templates/node/src/commands/task.ts +7 -3
- package/templates/node/src/logger.test.ts +9 -3
- package/templates/node/src/logger.ts +26 -6
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import
|
|
4
|
+
import path21 from "path";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/wizard.ts
|
|
8
8
|
import { intro, outro, text as text2, select as select2, log, isCancel as isCancel2, cancel as cancel2 } from "@clack/prompts";
|
|
9
9
|
|
|
10
10
|
// src/languages/packs/node-oclif.ts
|
|
11
|
-
import
|
|
11
|
+
import path6 from "path";
|
|
12
12
|
|
|
13
13
|
// src/package-root.ts
|
|
14
14
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -31,8 +31,8 @@ function findPackageRoot() {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// src/update/adapters/node-oclif.ts
|
|
34
|
-
import { readFile, writeFile } from "fs/promises";
|
|
35
|
-
import
|
|
34
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
35
|
+
import path3 from "path";
|
|
36
36
|
|
|
37
37
|
// src/update/reconcile.ts
|
|
38
38
|
function reconcileEntry(currentLiveValue, oldManifestValue, newTemplateValue, isEqual) {
|
|
@@ -51,6 +51,28 @@ function deepEquals(a, b) {
|
|
|
51
51
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// src/languages/lint-support/node.ts
|
|
55
|
+
import { readFile, rm, writeFile } from "fs/promises";
|
|
56
|
+
import path2 from "path";
|
|
57
|
+
var LINT_SCRIPT_NAMES = ["lint", "format"];
|
|
58
|
+
var LINT_DEPENDENCY_NAMES = [
|
|
59
|
+
"eslint",
|
|
60
|
+
"@eslint/js",
|
|
61
|
+
"typescript-eslint",
|
|
62
|
+
"prettier",
|
|
63
|
+
"eslint-config-prettier"
|
|
64
|
+
];
|
|
65
|
+
async function stripLintTooling(targetDir) {
|
|
66
|
+
await rm(path2.join(targetDir, "eslint.config.js"), { force: true });
|
|
67
|
+
await rm(path2.join(targetDir, ".prettierrc"), { force: true });
|
|
68
|
+
await rm(path2.join(targetDir, ".prettierignore"), { force: true });
|
|
69
|
+
const pkgPath = path2.join(targetDir, "package.json");
|
|
70
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
71
|
+
for (const name of LINT_SCRIPT_NAMES) delete pkg.scripts?.[name];
|
|
72
|
+
for (const name of LINT_DEPENDENCY_NAMES) delete pkg.devDependencies?.[name];
|
|
73
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
74
|
+
}
|
|
75
|
+
|
|
54
76
|
// src/update/adapters/node-oclif.ts
|
|
55
77
|
var CORE_FILE_PATHS = [
|
|
56
78
|
"bin/run.ts",
|
|
@@ -71,10 +93,11 @@ function currentDependencyValue(pkg, name) {
|
|
|
71
93
|
}
|
|
72
94
|
return void 0;
|
|
73
95
|
}
|
|
74
|
-
function extractCoreFields(pkg) {
|
|
96
|
+
function extractCoreFields(pkg, flags) {
|
|
75
97
|
const coreDependencies = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
98
|
+
const scriptNames = flags.lintEnabled ? [...CORE_SCRIPT_NAMES, ...LINT_SCRIPT_NAMES] : CORE_SCRIPT_NAMES;
|
|
76
99
|
const coreScripts = {};
|
|
77
|
-
for (const name of
|
|
100
|
+
for (const name of scriptNames) {
|
|
78
101
|
const value = pkg.scripts?.[name];
|
|
79
102
|
if (value !== void 0) coreScripts[name] = value;
|
|
80
103
|
}
|
|
@@ -92,10 +115,11 @@ function mergePackageJson(currentPkg, oldManifest, newTemplatePkg) {
|
|
|
92
115
|
let changed = false;
|
|
93
116
|
const dependencies = [];
|
|
94
117
|
const coreDependencies = {};
|
|
95
|
-
const dependencyNames =
|
|
96
|
-
...Object.keys(newTemplatePkg.dependencies ?? {}),
|
|
97
|
-
|
|
98
|
-
|
|
118
|
+
const dependencyNames = new Set(
|
|
119
|
+
[...Object.keys(newTemplatePkg.dependencies ?? {}), ...Object.keys(newTemplatePkg.devDependencies ?? {})].filter(
|
|
120
|
+
(name) => oldManifest.lintEnabled || !LINT_DEPENDENCY_NAMES.includes(name)
|
|
121
|
+
)
|
|
122
|
+
);
|
|
99
123
|
for (const name of dependencyNames) {
|
|
100
124
|
const inNewDependencies = newTemplatePkg.dependencies?.[name] !== void 0;
|
|
101
125
|
const newValue = (inNewDependencies ? newTemplatePkg.dependencies : newTemplatePkg.devDependencies)[name];
|
|
@@ -112,7 +136,8 @@ function mergePackageJson(currentPkg, oldManifest, newTemplatePkg) {
|
|
|
112
136
|
}
|
|
113
137
|
const scripts = [];
|
|
114
138
|
const coreScripts = {};
|
|
115
|
-
|
|
139
|
+
const scriptNames = oldManifest.lintEnabled ? [...CORE_SCRIPT_NAMES, ...LINT_SCRIPT_NAMES] : CORE_SCRIPT_NAMES;
|
|
140
|
+
for (const name of scriptNames) {
|
|
116
141
|
const newValue = newTemplatePkg.scripts?.[name];
|
|
117
142
|
if (newValue === void 0) continue;
|
|
118
143
|
const currentValue = currentPkg.scripts?.[name];
|
|
@@ -164,17 +189,19 @@ function mergePackageJson(currentPkg, oldManifest, newTemplatePkg) {
|
|
|
164
189
|
};
|
|
165
190
|
}
|
|
166
191
|
var nodeOclifAdapter = {
|
|
167
|
-
coreFilePaths
|
|
192
|
+
coreFilePaths(flags) {
|
|
193
|
+
return flags.lintEnabled ? [...CORE_FILE_PATHS, "eslint.config.js", ".prettierrc", ".prettierignore"] : CORE_FILE_PATHS;
|
|
194
|
+
},
|
|
168
195
|
templateSourcePath(relativePath) {
|
|
169
196
|
return relativePath === ".gitignore" ? "gitignore" : relativePath;
|
|
170
197
|
},
|
|
171
198
|
manifestFileName: "package.json",
|
|
172
199
|
async readManifestFile(dir) {
|
|
173
|
-
const content = await
|
|
200
|
+
const content = await readFile2(path3.join(dir, "package.json"), "utf8");
|
|
174
201
|
return JSON.parse(content);
|
|
175
202
|
},
|
|
176
203
|
async writeManifestFile(dir, content) {
|
|
177
|
-
await
|
|
204
|
+
await writeFile2(path3.join(dir, "package.json"), JSON.stringify(content, null, 2) + "\n");
|
|
178
205
|
},
|
|
179
206
|
parseManifestFile(rawContent) {
|
|
180
207
|
return JSON.parse(rawContent);
|
|
@@ -182,8 +209,8 @@ var nodeOclifAdapter = {
|
|
|
182
209
|
readProjectName(manifestFile) {
|
|
183
210
|
return manifestFile.name;
|
|
184
211
|
},
|
|
185
|
-
extractCoreFields(manifestFile) {
|
|
186
|
-
return extractCoreFields(manifestFile);
|
|
212
|
+
extractCoreFields(manifestFile, flags) {
|
|
213
|
+
return extractCoreFields(manifestFile, flags);
|
|
187
214
|
},
|
|
188
215
|
mergeManifestFile(current, oldManifest, newTemplate) {
|
|
189
216
|
return mergePackageJson(current, oldManifest, newTemplate);
|
|
@@ -191,8 +218,8 @@ var nodeOclifAdapter = {
|
|
|
191
218
|
};
|
|
192
219
|
|
|
193
220
|
// src/languages/registry-checkers/npm.ts
|
|
194
|
-
import { readFile as
|
|
195
|
-
import
|
|
221
|
+
import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
222
|
+
import path4 from "path";
|
|
196
223
|
var NPM_DEFAULT_REGISTRY_URL = "https://registry.npmjs.org";
|
|
197
224
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
198
225
|
async function checkNameAvailability(name, registryUrl) {
|
|
@@ -207,13 +234,13 @@ async function checkNameAvailability(name, registryUrl) {
|
|
|
207
234
|
}
|
|
208
235
|
}
|
|
209
236
|
async function applyPrivateIntent(targetDir) {
|
|
210
|
-
const packageJsonPath =
|
|
211
|
-
const pkg = JSON.parse(await
|
|
237
|
+
const packageJsonPath = path4.join(targetDir, "package.json");
|
|
238
|
+
const pkg = JSON.parse(await readFile3(packageJsonPath, "utf8"));
|
|
212
239
|
pkg.private = true;
|
|
213
|
-
await
|
|
240
|
+
await writeFile3(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
214
241
|
}
|
|
215
242
|
async function applyRegistryUrl(targetDir, registryUrl) {
|
|
216
|
-
await
|
|
243
|
+
await writeFile3(path4.join(targetDir, ".npmrc"), `registry=${registryUrl}
|
|
217
244
|
`);
|
|
218
245
|
}
|
|
219
246
|
var npmRegistryChecker = {
|
|
@@ -223,8 +250,8 @@ var npmRegistryChecker = {
|
|
|
223
250
|
};
|
|
224
251
|
|
|
225
252
|
// src/languages/command-generators/node-oclif.ts
|
|
226
|
-
import { mkdir, readdir, writeFile as
|
|
227
|
-
import
|
|
253
|
+
import { mkdir, readdir, writeFile as writeFile4 } from "fs/promises";
|
|
254
|
+
import path5 from "path";
|
|
228
255
|
|
|
229
256
|
// src/languages/command-generator.ts
|
|
230
257
|
function buildCommandTree(paths2) {
|
|
@@ -256,20 +283,20 @@ async function collectCommandFiles(dir, baseDir = dir) {
|
|
|
256
283
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
257
284
|
const files = [];
|
|
258
285
|
for (const entry of entries) {
|
|
259
|
-
const fullPath =
|
|
286
|
+
const fullPath = path5.join(dir, entry.name);
|
|
260
287
|
if (entry.isDirectory()) {
|
|
261
288
|
files.push(...await collectCommandFiles(fullPath, baseDir));
|
|
262
289
|
} else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
|
|
263
|
-
files.push(
|
|
290
|
+
files.push(path5.relative(baseDir, fullPath));
|
|
264
291
|
}
|
|
265
292
|
}
|
|
266
293
|
return files;
|
|
267
294
|
}
|
|
268
295
|
function toCommandPath(relativeFilePath) {
|
|
269
|
-
return relativeFilePath.replace(/\.ts$/, "").split(
|
|
296
|
+
return relativeFilePath.replace(/\.ts$/, "").split(path5.sep).join(" ");
|
|
270
297
|
}
|
|
271
298
|
async function listExistingCommands(targetDir) {
|
|
272
|
-
const commandsDir =
|
|
299
|
+
const commandsDir = path5.join(targetDir, "src", "commands");
|
|
273
300
|
const files = await collectCommandFiles(commandsDir);
|
|
274
301
|
return buildCommandTree(files.map(toCommandPath));
|
|
275
302
|
}
|
|
@@ -329,13 +356,13 @@ describe('${commandInvocation}', () => {
|
|
|
329
356
|
`;
|
|
330
357
|
}
|
|
331
358
|
async function generateCommand(targetDir, spec) {
|
|
332
|
-
const relDir =
|
|
359
|
+
const relDir = path5.join("src", "commands", ...spec.pathSegments.slice(0, -1));
|
|
333
360
|
const fileName = spec.pathSegments[spec.pathSegments.length - 1];
|
|
334
|
-
const commandRelPath =
|
|
335
|
-
const testRelPath =
|
|
336
|
-
await mkdir(
|
|
337
|
-
await
|
|
338
|
-
await
|
|
361
|
+
const commandRelPath = path5.join(relDir, `${fileName}.ts`);
|
|
362
|
+
const testRelPath = path5.join(relDir, `${fileName}.test.ts`);
|
|
363
|
+
await mkdir(path5.join(targetDir, relDir), { recursive: true });
|
|
364
|
+
await writeFile4(path5.join(targetDir, commandRelPath), generateCommandFileContent(spec));
|
|
365
|
+
await writeFile4(path5.join(targetDir, testRelPath), generateTestFileContent(spec));
|
|
339
366
|
return { commandFile: commandRelPath, testFile: testRelPath };
|
|
340
367
|
}
|
|
341
368
|
var nodeOclifCommandGenerator = {
|
|
@@ -354,7 +381,7 @@ function validateProjectName(value) {
|
|
|
354
381
|
var nodeOclifPack = {
|
|
355
382
|
id: "node",
|
|
356
383
|
displayName: "Node.js / TypeScript (oclif)",
|
|
357
|
-
templateDir:
|
|
384
|
+
templateDir: path6.join(findPackageRoot(), "templates", "node"),
|
|
358
385
|
scaffoldCommands: [
|
|
359
386
|
{ command: "npm", args: ["install"] },
|
|
360
387
|
{ command: "npm", args: ["run", "build"] }
|
|
@@ -368,15 +395,16 @@ var nodeOclifPack = {
|
|
|
368
395
|
applyPrivateIntent: npmRegistryChecker.applyPrivateIntent,
|
|
369
396
|
applyRegistryUrl: npmRegistryChecker.applyRegistryUrl
|
|
370
397
|
},
|
|
371
|
-
commandGenerator: nodeOclifCommandGenerator
|
|
398
|
+
commandGenerator: nodeOclifCommandGenerator,
|
|
399
|
+
stripLintTooling
|
|
372
400
|
};
|
|
373
401
|
|
|
374
402
|
// src/languages/packs/dotnet.ts
|
|
375
|
-
import
|
|
403
|
+
import path11 from "path";
|
|
376
404
|
|
|
377
405
|
// src/update/adapters/dotnet.ts
|
|
378
|
-
import { readFile as
|
|
379
|
-
import
|
|
406
|
+
import { readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
407
|
+
import path7 from "path";
|
|
380
408
|
var CORE_FILE_PATHS2 = [
|
|
381
409
|
"Cli.slnx",
|
|
382
410
|
"src/Program.cs",
|
|
@@ -398,6 +426,16 @@ function extractTag(content, tag) {
|
|
|
398
426
|
if (!match) throw new Error(`.csproj is missing a <${tag}> tag`);
|
|
399
427
|
return match[1];
|
|
400
428
|
}
|
|
429
|
+
function extractOptionalTag(content, tag) {
|
|
430
|
+
const match = content.match(new RegExp(`<${tag}>([^<]*)</${tag}>`));
|
|
431
|
+
return match?.[1];
|
|
432
|
+
}
|
|
433
|
+
var ANALYZER_PROPERTY_NAMES = [
|
|
434
|
+
"EnableNETAnalyzers",
|
|
435
|
+
"AnalysisLevel",
|
|
436
|
+
"AnalysisMode",
|
|
437
|
+
"EnforceCodeStyleInBuild"
|
|
438
|
+
];
|
|
401
439
|
function extractPackageReferences(content) {
|
|
402
440
|
const refs = {};
|
|
403
441
|
const re = /<PackageReference\s+Include="([^"]+)"\s+Version="([^"]+)"\s*\/>/g;
|
|
@@ -420,6 +458,14 @@ function addPackageReference(content, name, version) {
|
|
|
420
458
|
return content.replace(re, (match, indent) => `${match}${indent}<PackageReference Include="${name}" Version="${version}" />
|
|
421
459
|
`);
|
|
422
460
|
}
|
|
461
|
+
function extractAnalyzerProperties(content) {
|
|
462
|
+
const properties = {};
|
|
463
|
+
for (const name of ANALYZER_PROPERTY_NAMES) {
|
|
464
|
+
const value = extractOptionalTag(content, name);
|
|
465
|
+
if (value !== void 0) properties[name] = value;
|
|
466
|
+
}
|
|
467
|
+
return properties;
|
|
468
|
+
}
|
|
423
469
|
function parseManifestFile(rawContent) {
|
|
424
470
|
return {
|
|
425
471
|
raw: rawContent,
|
|
@@ -427,14 +473,22 @@ function parseManifestFile(rawContent) {
|
|
|
427
473
|
targetFramework: extractTag(rawContent, "TargetFramework"),
|
|
428
474
|
packageId: extractTag(rawContent, "PackageId"),
|
|
429
475
|
toolCommandName: extractTag(rawContent, "ToolCommandName"),
|
|
430
|
-
packageReferences: extractPackageReferences(rawContent)
|
|
476
|
+
packageReferences: extractPackageReferences(rawContent),
|
|
477
|
+
analyzerProperties: extractAnalyzerProperties(rawContent)
|
|
431
478
|
};
|
|
432
479
|
}
|
|
433
|
-
function extractCoreFields2(manifestFile) {
|
|
480
|
+
function extractCoreFields2(manifestFile, flags) {
|
|
481
|
+
const coreFields = { TargetFramework: manifestFile.targetFramework };
|
|
482
|
+
if (flags.lintEnabled) {
|
|
483
|
+
for (const name of ANALYZER_PROPERTY_NAMES) {
|
|
484
|
+
const value = manifestFile.analyzerProperties[name];
|
|
485
|
+
if (value !== void 0) coreFields[name] = value;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
434
488
|
return {
|
|
435
489
|
coreDependencies: manifestFile.packageReferences,
|
|
436
490
|
coreScripts: {},
|
|
437
|
-
coreFields
|
|
491
|
+
coreFields
|
|
438
492
|
};
|
|
439
493
|
}
|
|
440
494
|
function mergeManifestFile(current, oldManifest, newTemplate) {
|
|
@@ -470,6 +524,26 @@ function mergeManifestFile(current, oldManifest, newTemplate) {
|
|
|
470
524
|
changed = true;
|
|
471
525
|
raw = setTag(raw, "TargetFramework", targetFrameworkResult.value);
|
|
472
526
|
}
|
|
527
|
+
const coreFields = { TargetFramework: targetFrameworkResult.value };
|
|
528
|
+
if (oldManifest.lintEnabled) {
|
|
529
|
+
for (const name of ANALYZER_PROPERTY_NAMES) {
|
|
530
|
+
const newValue = newTemplate.analyzerProperties[name];
|
|
531
|
+
if (newValue === void 0) continue;
|
|
532
|
+
const currentValue = current.analyzerProperties[name];
|
|
533
|
+
if (currentValue === void 0) {
|
|
534
|
+
fields.push({ key: name, outcome: "skipped" });
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
const oldValue = oldCoreFields[name];
|
|
538
|
+
const result = reconcileEntry(currentValue, oldValue, newValue, stringEquals);
|
|
539
|
+
fields.push({ key: name, outcome: result.outcome });
|
|
540
|
+
coreFields[name] = result.value;
|
|
541
|
+
if (result.outcome !== "skipped" && result.value !== currentValue) {
|
|
542
|
+
changed = true;
|
|
543
|
+
raw = setTag(raw, name, result.value);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
473
547
|
return {
|
|
474
548
|
updatedFile: { ...current, raw },
|
|
475
549
|
changed,
|
|
@@ -478,28 +552,30 @@ function mergeManifestFile(current, oldManifest, newTemplate) {
|
|
|
478
552
|
fields,
|
|
479
553
|
coreDependencies,
|
|
480
554
|
coreScripts: {},
|
|
481
|
-
coreFields
|
|
555
|
+
coreFields
|
|
482
556
|
};
|
|
483
557
|
}
|
|
484
558
|
var dotnetAdapter = {
|
|
485
|
-
coreFilePaths
|
|
559
|
+
coreFilePaths() {
|
|
560
|
+
return CORE_FILE_PATHS2;
|
|
561
|
+
},
|
|
486
562
|
templateSourcePath(relativePath) {
|
|
487
563
|
return relativePath === ".gitignore" ? "gitignore" : relativePath;
|
|
488
564
|
},
|
|
489
565
|
manifestFileName: "src/Cli.csproj",
|
|
490
566
|
async readManifestFile(dir) {
|
|
491
|
-
const content = await
|
|
567
|
+
const content = await readFile4(path7.join(dir, "src", "Cli.csproj"), "utf8");
|
|
492
568
|
return parseManifestFile(content);
|
|
493
569
|
},
|
|
494
570
|
async writeManifestFile(dir, content) {
|
|
495
|
-
await
|
|
571
|
+
await writeFile5(path7.join(dir, "src", "Cli.csproj"), content.raw);
|
|
496
572
|
},
|
|
497
573
|
parseManifestFile,
|
|
498
574
|
readProjectName(manifestFile) {
|
|
499
575
|
return manifestFile.packageId;
|
|
500
576
|
},
|
|
501
|
-
extractCoreFields(manifestFile) {
|
|
502
|
-
return extractCoreFields2(manifestFile);
|
|
577
|
+
extractCoreFields(manifestFile, flags) {
|
|
578
|
+
return extractCoreFields2(manifestFile, flags);
|
|
503
579
|
},
|
|
504
580
|
mergeManifestFile(current, oldManifest, newTemplate) {
|
|
505
581
|
return mergeManifestFile(current, oldManifest, newTemplate);
|
|
@@ -507,8 +583,8 @@ var dotnetAdapter = {
|
|
|
507
583
|
};
|
|
508
584
|
|
|
509
585
|
// src/languages/registry-checkers/nuget.ts
|
|
510
|
-
import { mkdir as mkdir2, readFile as
|
|
511
|
-
import
|
|
586
|
+
import { mkdir as mkdir2, readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
|
|
587
|
+
import path8 from "path";
|
|
512
588
|
var NUGET_DEFAULT_REGISTRY_URL = "https://api.nuget.org/v3/index.json";
|
|
513
589
|
var NUGET_FLATCONTAINER_BASE = "https://api.nuget.org/v3-flatcontainer";
|
|
514
590
|
var FETCH_TIMEOUT_MS2 = 5e3;
|
|
@@ -524,13 +600,13 @@ async function checkNameAvailability2(name) {
|
|
|
524
600
|
}
|
|
525
601
|
}
|
|
526
602
|
async function applyPrivateIntent2(targetDir) {
|
|
527
|
-
const csprojPath =
|
|
528
|
-
const content = await
|
|
603
|
+
const csprojPath = path8.join(targetDir, "src", "Cli.csproj");
|
|
604
|
+
const content = await readFile5(csprojPath, "utf8");
|
|
529
605
|
const updated = content.replace(
|
|
530
606
|
/(<PropertyGroup>\s*\n)/,
|
|
531
607
|
"$1 <IsPackable>false</IsPackable>\n"
|
|
532
608
|
);
|
|
533
|
-
await
|
|
609
|
+
await writeFile6(csprojPath, updated);
|
|
534
610
|
}
|
|
535
611
|
async function applyRegistryUrl2(targetDir, registryUrl) {
|
|
536
612
|
const config = [
|
|
@@ -544,7 +620,7 @@ async function applyRegistryUrl2(targetDir, registryUrl) {
|
|
|
544
620
|
""
|
|
545
621
|
].join("\n");
|
|
546
622
|
await mkdir2(targetDir, { recursive: true });
|
|
547
|
-
await
|
|
623
|
+
await writeFile6(path8.join(targetDir, "NuGet.config"), config);
|
|
548
624
|
}
|
|
549
625
|
var nugetRegistryChecker = {
|
|
550
626
|
checkNameAvailability: checkNameAvailability2,
|
|
@@ -553,15 +629,15 @@ var nugetRegistryChecker = {
|
|
|
553
629
|
};
|
|
554
630
|
|
|
555
631
|
// src/languages/command-generators/dotnet.ts
|
|
556
|
-
import { mkdir as mkdir3, readFile as
|
|
557
|
-
import
|
|
632
|
+
import { mkdir as mkdir3, readFile as readFile6, readdir as readdir2, writeFile as writeFile7 } from "fs/promises";
|
|
633
|
+
import path9 from "path";
|
|
558
634
|
async function listExistingCommands2(targetDir) {
|
|
559
|
-
const commandsDir =
|
|
635
|
+
const commandsDir = path9.join(targetDir, "src", "Commands");
|
|
560
636
|
const files = await readdir2(commandsDir);
|
|
561
637
|
const paths2 = [];
|
|
562
638
|
for (const file of files) {
|
|
563
639
|
if (!file.endsWith(".cs")) continue;
|
|
564
|
-
const content = await
|
|
640
|
+
const content = await readFile6(path9.join(commandsDir, file), "utf8");
|
|
565
641
|
const match = content.match(/\[CommandPath\("([^"]+)"\)\]/);
|
|
566
642
|
if (match) paths2.push(match[1]);
|
|
567
643
|
}
|
|
@@ -653,12 +729,12 @@ public class ${className}Tests
|
|
|
653
729
|
}
|
|
654
730
|
async function generateCommand2(targetDir, spec) {
|
|
655
731
|
const className = toClassName2(spec.pathSegments);
|
|
656
|
-
const commandRelPath =
|
|
657
|
-
const testRelPath =
|
|
658
|
-
await mkdir3(
|
|
659
|
-
await mkdir3(
|
|
660
|
-
await
|
|
661
|
-
await
|
|
732
|
+
const commandRelPath = path9.join("src", "Commands", `${className}.cs`);
|
|
733
|
+
const testRelPath = path9.join("tests", `${className}Tests.cs`);
|
|
734
|
+
await mkdir3(path9.join(targetDir, "src", "Commands"), { recursive: true });
|
|
735
|
+
await mkdir3(path9.join(targetDir, "tests"), { recursive: true });
|
|
736
|
+
await writeFile7(path9.join(targetDir, commandRelPath), generateCommandFileContent2(spec));
|
|
737
|
+
await writeFile7(path9.join(targetDir, testRelPath), generateTestFileContent2(spec));
|
|
662
738
|
return { commandFile: commandRelPath, testFile: testRelPath };
|
|
663
739
|
}
|
|
664
740
|
var dotnetCommandGenerator = {
|
|
@@ -666,6 +742,19 @@ var dotnetCommandGenerator = {
|
|
|
666
742
|
generateCommand: generateCommand2
|
|
667
743
|
};
|
|
668
744
|
|
|
745
|
+
// src/languages/lint-support/dotnet.ts
|
|
746
|
+
import { readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
|
|
747
|
+
import path10 from "path";
|
|
748
|
+
async function stripLintTooling2(targetDir) {
|
|
749
|
+
const csprojPath = path10.join(targetDir, "src", "Cli.csproj");
|
|
750
|
+
const content = await readFile7(csprojPath, "utf8");
|
|
751
|
+
const updated = content.replace(
|
|
752
|
+
/\r?\n\s*<PropertyGroup>\s*\r?\n\s*<EnableNETAnalyzers>[\s\S]*?<\/PropertyGroup>\r?\n/,
|
|
753
|
+
"\n"
|
|
754
|
+
);
|
|
755
|
+
await writeFile8(csprojPath, updated);
|
|
756
|
+
}
|
|
757
|
+
|
|
669
758
|
// src/languages/packs/dotnet.ts
|
|
670
759
|
function validateProjectName2(value) {
|
|
671
760
|
if (!value || value.trim().length === 0) return "Project name is required.";
|
|
@@ -677,7 +766,7 @@ function validateProjectName2(value) {
|
|
|
677
766
|
var dotnetPack = {
|
|
678
767
|
id: "dotnet",
|
|
679
768
|
displayName: ".NET / C# (System.CommandLine)",
|
|
680
|
-
templateDir:
|
|
769
|
+
templateDir: path11.join(findPackageRoot(), "templates", "dotnet"),
|
|
681
770
|
scaffoldCommands: [
|
|
682
771
|
{ command: "dotnet", args: ["restore"] },
|
|
683
772
|
{ command: "dotnet", args: ["build"] }
|
|
@@ -691,15 +780,16 @@ var dotnetPack = {
|
|
|
691
780
|
applyPrivateIntent: nugetRegistryChecker.applyPrivateIntent,
|
|
692
781
|
applyRegistryUrl: nugetRegistryChecker.applyRegistryUrl
|
|
693
782
|
},
|
|
694
|
-
commandGenerator: dotnetCommandGenerator
|
|
783
|
+
commandGenerator: dotnetCommandGenerator,
|
|
784
|
+
stripLintTooling: stripLintTooling2
|
|
695
785
|
};
|
|
696
786
|
|
|
697
787
|
// src/languages/packs/powershell.ts
|
|
698
|
-
import
|
|
788
|
+
import path15 from "path";
|
|
699
789
|
|
|
700
790
|
// src/update/adapters/powershell.ts
|
|
701
|
-
import { readFile as
|
|
702
|
-
import
|
|
791
|
+
import { readFile as readFile8, writeFile as writeFile9 } from "fs/promises";
|
|
792
|
+
import path12 from "path";
|
|
703
793
|
import spawn from "cross-spawn";
|
|
704
794
|
var CORE_FILE_PATHS3 = [
|
|
705
795
|
"Module.psm1",
|
|
@@ -812,14 +902,16 @@ function mergeManifestFile2(current, oldManifest, newTemplate) {
|
|
|
812
902
|
};
|
|
813
903
|
}
|
|
814
904
|
var powershellAdapter = {
|
|
815
|
-
coreFilePaths
|
|
905
|
+
coreFilePaths() {
|
|
906
|
+
return CORE_FILE_PATHS3;
|
|
907
|
+
},
|
|
816
908
|
templateSourcePath(relativePath) {
|
|
817
909
|
return relativePath === ".gitignore" ? "gitignore" : relativePath;
|
|
818
910
|
},
|
|
819
911
|
manifestFileName: "Module.psd1",
|
|
820
912
|
async readManifestFile(dir) {
|
|
821
|
-
const manifestPath =
|
|
822
|
-
const raw = await
|
|
913
|
+
const manifestPath = path12.join(dir, "Module.psd1");
|
|
914
|
+
const raw = await readFile8(manifestPath, "utf8");
|
|
823
915
|
const parsedViaPwsh = await readManifestViaPwsh(manifestPath);
|
|
824
916
|
return {
|
|
825
917
|
raw,
|
|
@@ -828,7 +920,7 @@ var powershellAdapter = {
|
|
|
828
920
|
};
|
|
829
921
|
},
|
|
830
922
|
async writeManifestFile(dir, content) {
|
|
831
|
-
await
|
|
923
|
+
await writeFile9(path12.join(dir, "Module.psd1"), content.raw);
|
|
832
924
|
},
|
|
833
925
|
parseManifestFile: parseManifestFile2,
|
|
834
926
|
readProjectName() {
|
|
@@ -843,8 +935,8 @@ var powershellAdapter = {
|
|
|
843
935
|
};
|
|
844
936
|
|
|
845
937
|
// src/languages/registry-checkers/powershell-gallery.ts
|
|
846
|
-
import { mkdir as mkdir4, writeFile as
|
|
847
|
-
import
|
|
938
|
+
import { mkdir as mkdir4, writeFile as writeFile10 } from "fs/promises";
|
|
939
|
+
import path13 from "path";
|
|
848
940
|
var POWERSHELL_GALLERY_DEFAULT_URL = "https://www.powershellgallery.com/api/v2";
|
|
849
941
|
var FETCH_TIMEOUT_MS3 = 5e3;
|
|
850
942
|
async function checkNameAvailability3(name, registryUrl) {
|
|
@@ -870,7 +962,7 @@ async function applyRegistryUrl3(targetDir, registryUrl) {
|
|
|
870
962
|
""
|
|
871
963
|
].join("\n");
|
|
872
964
|
await mkdir4(targetDir, { recursive: true });
|
|
873
|
-
await
|
|
965
|
+
await writeFile10(path13.join(targetDir, ".psresource-repository"), content);
|
|
874
966
|
}
|
|
875
967
|
var powershellGalleryRegistryChecker = {
|
|
876
968
|
checkNameAvailability: checkNameAvailability3,
|
|
@@ -879,8 +971,8 @@ var powershellGalleryRegistryChecker = {
|
|
|
879
971
|
};
|
|
880
972
|
|
|
881
973
|
// src/languages/command-generators/powershell.ts
|
|
882
|
-
import { mkdir as mkdir5, readdir as readdir3, writeFile as
|
|
883
|
-
import
|
|
974
|
+
import { mkdir as mkdir5, readdir as readdir3, writeFile as writeFile11 } from "fs/promises";
|
|
975
|
+
import path14 from "path";
|
|
884
976
|
import { select, text, isCancel, cancel } from "@clack/prompts";
|
|
885
977
|
var APPROVED_VERBS = [
|
|
886
978
|
"Get",
|
|
@@ -904,7 +996,7 @@ function exitIfCancelled(value) {
|
|
|
904
996
|
}
|
|
905
997
|
}
|
|
906
998
|
async function listExistingCommands3(targetDir) {
|
|
907
|
-
const publicDir =
|
|
999
|
+
const publicDir = path14.join(targetDir, "Public");
|
|
908
1000
|
const files = await readdir3(publicDir);
|
|
909
1001
|
const paths2 = files.filter((f) => f.endsWith(".ps1")).map((f) => f.replace(/\.ps1$/, ""));
|
|
910
1002
|
return buildCommandTree(paths2);
|
|
@@ -959,12 +1051,12 @@ function generateTestFileContent3(spec) {
|
|
|
959
1051
|
}
|
|
960
1052
|
async function generateCommand3(targetDir, spec) {
|
|
961
1053
|
const funcName = spec.pathSegments[spec.pathSegments.length - 1];
|
|
962
|
-
const commandRelPath =
|
|
963
|
-
const testRelPath =
|
|
964
|
-
await mkdir5(
|
|
965
|
-
await mkdir5(
|
|
966
|
-
await
|
|
967
|
-
await
|
|
1054
|
+
const commandRelPath = path14.join("Public", `${funcName}.ps1`);
|
|
1055
|
+
const testRelPath = path14.join("tests", `${funcName}.Tests.ps1`);
|
|
1056
|
+
await mkdir5(path14.join(targetDir, "Public"), { recursive: true });
|
|
1057
|
+
await mkdir5(path14.join(targetDir, "tests"), { recursive: true });
|
|
1058
|
+
await writeFile11(path14.join(targetDir, commandRelPath), generateCommandFileContent3(spec));
|
|
1059
|
+
await writeFile11(path14.join(targetDir, testRelPath), generateTestFileContent3(spec));
|
|
968
1060
|
return { commandFile: commandRelPath.replace(/\\/g, "/"), testFile: testRelPath.replace(/\\/g, "/") };
|
|
969
1061
|
}
|
|
970
1062
|
async function promptCommandIdentity(_pathSegments, existingPaths) {
|
|
@@ -1002,7 +1094,7 @@ function validateProjectName3(value) {
|
|
|
1002
1094
|
var powershellPack = {
|
|
1003
1095
|
id: "powershell",
|
|
1004
1096
|
displayName: "PowerShell (7.4+)",
|
|
1005
|
-
templateDir:
|
|
1097
|
+
templateDir: path15.join(findPackageRoot(), "templates", "powershell"),
|
|
1006
1098
|
scaffoldCommands: [
|
|
1007
1099
|
{
|
|
1008
1100
|
command: "pwsh",
|
|
@@ -1018,7 +1110,9 @@ var powershellPack = {
|
|
|
1018
1110
|
applyPrivateIntent: powershellGalleryRegistryChecker.applyPrivateIntent,
|
|
1019
1111
|
applyRegistryUrl: powershellGalleryRegistryChecker.applyRegistryUrl
|
|
1020
1112
|
},
|
|
1021
|
-
commandGenerator: powershellCommandGenerator
|
|
1113
|
+
commandGenerator: powershellCommandGenerator,
|
|
1114
|
+
stripLintTooling: async () => {
|
|
1115
|
+
}
|
|
1022
1116
|
};
|
|
1023
1117
|
|
|
1024
1118
|
// src/languages/index.ts
|
|
@@ -1082,6 +1176,16 @@ async function runWizard(deps = defaultDeps) {
|
|
|
1082
1176
|
});
|
|
1083
1177
|
exitIfCancelled2(publishIntentValue);
|
|
1084
1178
|
const publishIntent = publishIntentValue;
|
|
1179
|
+
const lintEnabledValue = await select2({
|
|
1180
|
+
message: "Set up lint tooling?",
|
|
1181
|
+
options: [
|
|
1182
|
+
{ value: false, label: "No" },
|
|
1183
|
+
{ value: true, label: "Yes" }
|
|
1184
|
+
],
|
|
1185
|
+
initialValue: false
|
|
1186
|
+
});
|
|
1187
|
+
exitIfCancelled2(lintEnabledValue);
|
|
1188
|
+
const lintEnabled = lintEnabledValue;
|
|
1085
1189
|
let nameAvailability = "skipped";
|
|
1086
1190
|
if (publishIntent) {
|
|
1087
1191
|
nameAvailability = await pack.registry.checkNameAvailability(projectName, registryUrl);
|
|
@@ -1100,19 +1204,19 @@ async function runWizard(deps = defaultDeps) {
|
|
|
1100
1204
|
}
|
|
1101
1205
|
}
|
|
1102
1206
|
outro(`Ready to scaffold "${projectName}".`);
|
|
1103
|
-
return { language: pack.id, projectName, profile, registryUrl, publishIntent, nameAvailability };
|
|
1207
|
+
return { language: pack.id, projectName, profile, registryUrl, publishIntent, nameAvailability, lintEnabled };
|
|
1104
1208
|
}
|
|
1105
1209
|
|
|
1106
1210
|
// src/scaffold.ts
|
|
1107
|
-
import { cp, readdir as readdir4, readFile as
|
|
1108
|
-
import
|
|
1211
|
+
import { cp, readdir as readdir4, readFile as readFile10, rename, writeFile as writeFile13 } from "fs/promises";
|
|
1212
|
+
import path17 from "path";
|
|
1109
1213
|
import spawn2 from "cross-spawn";
|
|
1110
1214
|
|
|
1111
1215
|
// src/update/manifest.ts
|
|
1112
1216
|
import { createHash } from "crypto";
|
|
1113
1217
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
1114
|
-
import { mkdir as mkdir6, readFile as
|
|
1115
|
-
import
|
|
1218
|
+
import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile12 } from "fs/promises";
|
|
1219
|
+
import path16 from "path";
|
|
1116
1220
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1117
1221
|
|
|
1118
1222
|
// src/errors.ts
|
|
@@ -1127,30 +1231,30 @@ var UserError = class extends Error {
|
|
|
1127
1231
|
function hashContent(content) {
|
|
1128
1232
|
return createHash("sha256").update(content).digest("hex");
|
|
1129
1233
|
}
|
|
1130
|
-
async function hashCoreFiles(dir, adapter) {
|
|
1234
|
+
async function hashCoreFiles(dir, adapter, flags) {
|
|
1131
1235
|
const entries = await Promise.all(
|
|
1132
|
-
adapter.coreFilePaths.map(async (relativePath) => {
|
|
1133
|
-
const content = await
|
|
1236
|
+
adapter.coreFilePaths(flags).map(async (relativePath) => {
|
|
1237
|
+
const content = await readFile9(path16.join(dir, relativePath), "utf8");
|
|
1134
1238
|
return [relativePath, hashContent(content)];
|
|
1135
1239
|
})
|
|
1136
1240
|
);
|
|
1137
1241
|
return Object.fromEntries(entries);
|
|
1138
1242
|
}
|
|
1139
|
-
async function buildManifest(targetDir, generatorVersion, language, adapter) {
|
|
1140
|
-
const coreFiles = await hashCoreFiles(targetDir, adapter);
|
|
1243
|
+
async function buildManifest(targetDir, generatorVersion, language, adapter, lintEnabled) {
|
|
1244
|
+
const coreFiles = await hashCoreFiles(targetDir, adapter, { lintEnabled });
|
|
1141
1245
|
const manifestFile = await adapter.readManifestFile(targetDir);
|
|
1142
|
-
const { coreDependencies, coreScripts, coreFields } = adapter.extractCoreFields(manifestFile);
|
|
1143
|
-
return { generatorVersion, language, coreFiles, coreDependencies, coreScripts, coreFields };
|
|
1246
|
+
const { coreDependencies, coreScripts, coreFields } = adapter.extractCoreFields(manifestFile, { lintEnabled });
|
|
1247
|
+
return { generatorVersion, language, lintEnabled, coreFiles, coreDependencies, coreScripts, coreFields };
|
|
1144
1248
|
}
|
|
1145
|
-
var MANIFEST_RELATIVE_PATH =
|
|
1249
|
+
var MANIFEST_RELATIVE_PATH = path16.join(".clispark", "manifest.json");
|
|
1146
1250
|
async function writeManifest(targetDir, manifest) {
|
|
1147
|
-
const manifestPath =
|
|
1148
|
-
await mkdir6(
|
|
1149
|
-
await
|
|
1251
|
+
const manifestPath = path16.join(targetDir, MANIFEST_RELATIVE_PATH);
|
|
1252
|
+
await mkdir6(path16.dirname(manifestPath), { recursive: true });
|
|
1253
|
+
await writeFile12(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
|
|
1150
1254
|
}
|
|
1151
1255
|
async function readManifest(targetDir) {
|
|
1152
1256
|
try {
|
|
1153
|
-
const content = await
|
|
1257
|
+
const content = await readFile9(path16.join(targetDir, MANIFEST_RELATIVE_PATH), "utf8");
|
|
1154
1258
|
return JSON.parse(content);
|
|
1155
1259
|
} catch {
|
|
1156
1260
|
return void 0;
|
|
@@ -1166,14 +1270,14 @@ async function requireManifest(targetDir) {
|
|
|
1166
1270
|
return manifest;
|
|
1167
1271
|
}
|
|
1168
1272
|
function getGeneratorVersion() {
|
|
1169
|
-
let dir =
|
|
1273
|
+
let dir = path16.dirname(fileURLToPath2(import.meta.url));
|
|
1170
1274
|
while (true) {
|
|
1171
|
-
const pkgPath =
|
|
1275
|
+
const pkgPath = path16.join(dir, "package.json");
|
|
1172
1276
|
if (existsSync2(pkgPath)) {
|
|
1173
1277
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
|
|
1174
1278
|
if (pkg.name === "clispark") return pkg.version;
|
|
1175
1279
|
}
|
|
1176
|
-
const parentDir =
|
|
1280
|
+
const parentDir = path16.dirname(dir);
|
|
1177
1281
|
if (parentDir === dir) {
|
|
1178
1282
|
throw new Error("Could not locate clispark's own package.json.");
|
|
1179
1283
|
}
|
|
@@ -1200,7 +1304,7 @@ async function collectFiles(dir) {
|
|
|
1200
1304
|
const entries = await readdir4(dir, { withFileTypes: true });
|
|
1201
1305
|
const files = await Promise.all(
|
|
1202
1306
|
entries.map((entry) => {
|
|
1203
|
-
const fullPath =
|
|
1307
|
+
const fullPath = path17.join(dir, entry.name);
|
|
1204
1308
|
return entry.isDirectory() ? collectFiles(fullPath) : Promise.resolve([fullPath]);
|
|
1205
1309
|
})
|
|
1206
1310
|
);
|
|
@@ -1210,9 +1314,9 @@ async function replacePlaceholdersInTree(targetDir, projectName) {
|
|
|
1210
1314
|
const files = await collectFiles(targetDir);
|
|
1211
1315
|
await Promise.all(
|
|
1212
1316
|
files.map(async (filePath) => {
|
|
1213
|
-
const content = await
|
|
1317
|
+
const content = await readFile10(filePath, "utf8");
|
|
1214
1318
|
if (content.includes("{{projectName}}")) {
|
|
1215
|
-
await
|
|
1319
|
+
await writeFile13(filePath, applyPlaceholders(content, projectName));
|
|
1216
1320
|
}
|
|
1217
1321
|
})
|
|
1218
1322
|
);
|
|
@@ -1221,7 +1325,7 @@ async function copyTemplate(options, pack) {
|
|
|
1221
1325
|
const { projectName, targetDir, registryUrl, publishIntent } = options;
|
|
1222
1326
|
await assertTargetDirIsUsable(targetDir);
|
|
1223
1327
|
await cp(pack.templateDir, targetDir, { recursive: true });
|
|
1224
|
-
await rename(
|
|
1328
|
+
await rename(path17.join(targetDir, "gitignore"), path17.join(targetDir, ".gitignore"));
|
|
1225
1329
|
await replacePlaceholdersInTree(targetDir, projectName);
|
|
1226
1330
|
if (publishIntent === false) {
|
|
1227
1331
|
await pack.registry.applyPrivateIntent(targetDir);
|
|
@@ -1247,7 +1351,11 @@ var defaultScaffoldDeps = { runCommand: defaultRunCommand };
|
|
|
1247
1351
|
async function scaffoldProject(options, pack, deps = defaultScaffoldDeps) {
|
|
1248
1352
|
await copyTemplate(options, pack);
|
|
1249
1353
|
const { targetDir } = options;
|
|
1250
|
-
const
|
|
1354
|
+
const lintEnabled = options.lintEnabled ?? false;
|
|
1355
|
+
if (!lintEnabled) {
|
|
1356
|
+
await pack.stripLintTooling(targetDir);
|
|
1357
|
+
}
|
|
1358
|
+
const manifest = await buildManifest(targetDir, getGeneratorVersion(), pack.id, pack.updateAdapter, lintEnabled);
|
|
1251
1359
|
await writeManifest(targetDir, manifest);
|
|
1252
1360
|
await deps.runCommand("git", ["init"], targetDir);
|
|
1253
1361
|
await deps.runCommand("git", ["add", "-A"], targetDir);
|
|
@@ -1260,7 +1368,7 @@ async function scaffoldProject(options, pack, deps = defaultScaffoldDeps) {
|
|
|
1260
1368
|
// src/logger.ts
|
|
1261
1369
|
import { randomBytes } from "crypto";
|
|
1262
1370
|
import { mkdirSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
1263
|
-
import
|
|
1371
|
+
import path18 from "path";
|
|
1264
1372
|
import envPaths from "env-paths";
|
|
1265
1373
|
import pino from "pino";
|
|
1266
1374
|
var paths = envPaths("clispark", { suffix: "" });
|
|
@@ -1296,7 +1404,7 @@ var SWEEP_MARKER_FILE = ".last-sweep";
|
|
|
1296
1404
|
var SWEEP_THROTTLE_MS = 24 * 60 * 60 * 1e3;
|
|
1297
1405
|
function sweepOldLogs(logDir) {
|
|
1298
1406
|
safely(() => {
|
|
1299
|
-
const markerPath =
|
|
1407
|
+
const markerPath = path18.join(logDir, SWEEP_MARKER_FILE);
|
|
1300
1408
|
let shouldSweep = true;
|
|
1301
1409
|
try {
|
|
1302
1410
|
shouldSweep = Date.now() - statSync(markerPath).mtimeMs >= SWEEP_THROTTLE_MS;
|
|
@@ -1306,7 +1414,7 @@ function sweepOldLogs(logDir) {
|
|
|
1306
1414
|
const cutoffMs = Date.now() - getRetentionDays() * 24 * 60 * 60 * 1e3;
|
|
1307
1415
|
for (const file of readdirSync(logDir)) {
|
|
1308
1416
|
if (file === SWEEP_MARKER_FILE) continue;
|
|
1309
|
-
const filePath =
|
|
1417
|
+
const filePath = path18.join(logDir, file);
|
|
1310
1418
|
if (statSync(filePath).mtimeMs < cutoffMs) {
|
|
1311
1419
|
unlinkSync(filePath);
|
|
1312
1420
|
}
|
|
@@ -1317,7 +1425,7 @@ function sweepOldLogs(logDir) {
|
|
|
1317
1425
|
function createLogger(commandName, logDir = paths.log) {
|
|
1318
1426
|
mkdirSync(logDir, { recursive: true });
|
|
1319
1427
|
sweepOldLogs(logDir);
|
|
1320
|
-
const logFilePath =
|
|
1428
|
+
const logFilePath = path18.join(logDir, buildLogFileName(commandName));
|
|
1321
1429
|
const fileDestination = pino.destination({ dest: logFilePath, sync: true, mode: 384 });
|
|
1322
1430
|
const destination = process.env.DEBUG ? pino.multistream([{ stream: fileDestination }, { stream: process.stdout }]) : fileDestination;
|
|
1323
1431
|
const logger = pino({ redact: buildRedactPaths([...SENSITIVE_LOG_KEYS, "registryUrl"]) }, destination);
|
|
@@ -1355,8 +1463,8 @@ function withLogging(commandName, action, logDir = paths.log, loggerFactory = cr
|
|
|
1355
1463
|
}
|
|
1356
1464
|
|
|
1357
1465
|
// src/update/update.ts
|
|
1358
|
-
import { mkdir as mkdir7, readFile as
|
|
1359
|
-
import
|
|
1466
|
+
import { mkdir as mkdir7, readFile as readFile11, writeFile as writeFile14 } from "fs/promises";
|
|
1467
|
+
import path19 from "path";
|
|
1360
1468
|
import spawn3 from "cross-spawn";
|
|
1361
1469
|
|
|
1362
1470
|
// src/update/releasenotes.ts
|
|
@@ -1442,7 +1550,7 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
|
|
|
1442
1550
|
const currentManifestFile = await adapter.readManifestFile(targetDir);
|
|
1443
1551
|
const projectName = adapter.readProjectName(currentManifestFile);
|
|
1444
1552
|
const newTemplateRaw = applyPlaceholders(
|
|
1445
|
-
await
|
|
1553
|
+
await readFile11(path19.join(templateDir, adapter.manifestFileName), "utf8"),
|
|
1446
1554
|
projectName
|
|
1447
1555
|
);
|
|
1448
1556
|
const newTemplateManifestFile = adapter.parseManifestFile(newTemplateRaw);
|
|
@@ -1450,15 +1558,15 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
|
|
|
1450
1558
|
const newCoreFiles = {};
|
|
1451
1559
|
const fileWrites = [];
|
|
1452
1560
|
const perFileResults = await Promise.all(
|
|
1453
|
-
adapter.coreFilePaths.map(async (relativePath) => {
|
|
1561
|
+
adapter.coreFilePaths(oldManifest).map(async (relativePath) => {
|
|
1454
1562
|
const newContent = applyPlaceholders(
|
|
1455
|
-
await
|
|
1563
|
+
await readFile11(path19.join(templateDir, adapter.templateSourcePath(relativePath)), "utf8"),
|
|
1456
1564
|
projectName
|
|
1457
1565
|
);
|
|
1458
1566
|
const newHash = hashContent(newContent);
|
|
1459
1567
|
let currentHash;
|
|
1460
1568
|
try {
|
|
1461
|
-
currentHash = hashContent(await
|
|
1569
|
+
currentHash = hashContent(await readFile11(path19.join(targetDir, relativePath), "utf8"));
|
|
1462
1570
|
} catch {
|
|
1463
1571
|
currentHash = void 0;
|
|
1464
1572
|
}
|
|
@@ -1470,13 +1578,13 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
|
|
|
1470
1578
|
files.push({ path: relativePath, outcome: result.outcome });
|
|
1471
1579
|
newCoreFiles[relativePath] = result.value;
|
|
1472
1580
|
if (result.outcome === "added" || result.outcome === "replaced") {
|
|
1473
|
-
fileWrites.push({ targetPath:
|
|
1581
|
+
fileWrites.push({ targetPath: path19.join(targetDir, relativePath), content: newContent });
|
|
1474
1582
|
}
|
|
1475
1583
|
}
|
|
1476
1584
|
for (const relativePath of Object.keys(oldManifest.coreFiles)) {
|
|
1477
|
-
if (adapter.coreFilePaths.includes(relativePath)) continue;
|
|
1585
|
+
if (adapter.coreFilePaths(oldManifest).includes(relativePath)) continue;
|
|
1478
1586
|
try {
|
|
1479
|
-
await
|
|
1587
|
+
await readFile11(path19.join(targetDir, relativePath), "utf8");
|
|
1480
1588
|
files.push({ path: relativePath, outcome: "no-longer-core" });
|
|
1481
1589
|
} catch {
|
|
1482
1590
|
}
|
|
@@ -1498,8 +1606,8 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
|
|
|
1498
1606
|
};
|
|
1499
1607
|
}
|
|
1500
1608
|
for (const write of fileWrites) {
|
|
1501
|
-
await mkdir7(
|
|
1502
|
-
await
|
|
1609
|
+
await mkdir7(path19.dirname(write.targetPath), { recursive: true });
|
|
1610
|
+
await writeFile14(write.targetPath, write.content);
|
|
1503
1611
|
}
|
|
1504
1612
|
if (fileMerge.changed) {
|
|
1505
1613
|
await adapter.writeManifestFile(targetDir, fileMerge.updatedFile);
|
|
@@ -1507,6 +1615,7 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
|
|
|
1507
1615
|
const newManifest = {
|
|
1508
1616
|
generatorVersion: toVersion,
|
|
1509
1617
|
language,
|
|
1618
|
+
lintEnabled: oldManifest.lintEnabled ?? false,
|
|
1510
1619
|
coreFiles: newCoreFiles,
|
|
1511
1620
|
coreDependencies: fileMerge.coreDependencies,
|
|
1512
1621
|
coreScripts: fileMerge.coreScripts,
|
|
@@ -1816,11 +1925,11 @@ ${getConfetti(randomFn)}
|
|
|
1816
1925
|
|
|
1817
1926
|
// src/hooks.ts
|
|
1818
1927
|
import { existsSync as existsSync3 } from "fs";
|
|
1819
|
-
import
|
|
1928
|
+
import path20 from "path";
|
|
1820
1929
|
import { pathToFileURL } from "url";
|
|
1821
1930
|
import envPaths2 from "env-paths";
|
|
1822
1931
|
function getPostScaffoldHookPath(configDir = envPaths2("clispark", { suffix: "" }).config) {
|
|
1823
|
-
return
|
|
1932
|
+
return path20.join(configDir, "hooks", "post-scaffold.mjs");
|
|
1824
1933
|
}
|
|
1825
1934
|
var defaultDeps2 = {
|
|
1826
1935
|
fileExists: existsSync3,
|
|
@@ -1863,7 +1972,7 @@ function resolvePack(language) {
|
|
|
1863
1972
|
program.action(
|
|
1864
1973
|
(options) => withLogging("scaffold", async (logger) => {
|
|
1865
1974
|
const answers = await runWizard();
|
|
1866
|
-
const targetDir =
|
|
1975
|
+
const targetDir = path21.join(process.cwd(), answers.projectName);
|
|
1867
1976
|
const pack = resolvePack(answers.language);
|
|
1868
1977
|
logger.info({ projectName: answers.projectName, targetDir, language: pack.id }, "scaffold started");
|
|
1869
1978
|
await scaffoldProject(
|
|
@@ -1871,7 +1980,8 @@ program.action(
|
|
|
1871
1980
|
projectName: answers.projectName,
|
|
1872
1981
|
targetDir,
|
|
1873
1982
|
registryUrl: answers.registryUrl,
|
|
1874
|
-
publishIntent: answers.publishIntent
|
|
1983
|
+
publishIntent: answers.publishIntent,
|
|
1984
|
+
lintEnabled: answers.lintEnabled
|
|
1875
1985
|
},
|
|
1876
1986
|
pack
|
|
1877
1987
|
);
|