@dafish/gogo-meta 1.5.0 → 1.6.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/dist/cli.js +104 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +104 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,8 +3,8 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { readFileSync } from 'fs';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { dirname, join, basename, resolve } from 'path';
|
|
6
|
-
import { unlink, mkdir, appendFile, access, writeFile, readFile, symlink } from 'fs/promises';
|
|
7
|
-
import {
|
|
6
|
+
import { unlink, mkdir, appendFile, access, writeFile, readFile, symlink, readdir } from 'fs/promises';
|
|
7
|
+
import { parse, stringify } from 'yaml';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import pc from 'picocolors';
|
|
10
10
|
import { homedir } from 'os';
|
|
@@ -470,7 +470,7 @@ function commandOutput(stdout, stderr) {
|
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
472
|
function summary(results) {
|
|
473
|
-
const { success: successCount, failed, total } = results;
|
|
473
|
+
const { success: successCount, failed, total, failedProjects } = results;
|
|
474
474
|
console.log("");
|
|
475
475
|
if (failed === 0) {
|
|
476
476
|
console.log(`${symbols.success} ${pc.green(`All ${total} projects completed successfully`)}`);
|
|
@@ -478,6 +478,13 @@ function summary(results) {
|
|
|
478
478
|
console.log(
|
|
479
479
|
`${symbols.warning} ${pc.yellow(`${successCount}/${total} projects succeeded, ${failed} failed`)}`
|
|
480
480
|
);
|
|
481
|
+
if (failedProjects && failedProjects.length > 0) {
|
|
482
|
+
console.log("");
|
|
483
|
+
console.log("Failed projects:");
|
|
484
|
+
for (const project of failedProjects) {
|
|
485
|
+
console.log(` ${symbols.error} ${pc.red(project)}`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
481
488
|
}
|
|
482
489
|
}
|
|
483
490
|
|
|
@@ -651,9 +658,14 @@ async function loop(command, context, options = {}) {
|
|
|
651
658
|
}
|
|
652
659
|
const results = options.parallel ? await runParallel(command, directories, context, options) : await runSequential(command, directories, context, options);
|
|
653
660
|
if (!options.suppressOutput) {
|
|
654
|
-
const
|
|
655
|
-
const
|
|
656
|
-
summary({
|
|
661
|
+
const failedResults = results.filter((r) => !r.success);
|
|
662
|
+
const successCount = results.length - failedResults.length;
|
|
663
|
+
summary({
|
|
664
|
+
success: successCount,
|
|
665
|
+
failed: failedResults.length,
|
|
666
|
+
total: results.length,
|
|
667
|
+
failedProjects: failedResults.map((r) => r.directory)
|
|
668
|
+
});
|
|
657
669
|
}
|
|
658
670
|
return results;
|
|
659
671
|
}
|
|
@@ -1449,6 +1461,91 @@ function registerNpmCommands(program) {
|
|
|
1449
1461
|
await runCommand2(script, options);
|
|
1450
1462
|
});
|
|
1451
1463
|
}
|
|
1464
|
+
function isGogoConfigFile(filename) {
|
|
1465
|
+
return filename === ".gogo" || filename.startsWith(".gogo.");
|
|
1466
|
+
}
|
|
1467
|
+
async function findConfigFiles(cwd) {
|
|
1468
|
+
const entries = await readdir(cwd);
|
|
1469
|
+
const configFiles = [];
|
|
1470
|
+
for (const entry of entries) {
|
|
1471
|
+
if (isGogoConfigFile(entry)) {
|
|
1472
|
+
configFiles.push(entry);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
if (entries.includes(LOOPRC_FILE)) {
|
|
1476
|
+
configFiles.push(LOOPRC_FILE);
|
|
1477
|
+
}
|
|
1478
|
+
return configFiles.sort();
|
|
1479
|
+
}
|
|
1480
|
+
async function validateCommand() {
|
|
1481
|
+
const cwd = process.cwd();
|
|
1482
|
+
const results = [];
|
|
1483
|
+
const configFiles = await findConfigFiles(cwd);
|
|
1484
|
+
for (const filename of configFiles) {
|
|
1485
|
+
const filePath = join(cwd, filename);
|
|
1486
|
+
if (filename === LOOPRC_FILE) {
|
|
1487
|
+
results.push(await validateLoopRcFile(filePath));
|
|
1488
|
+
} else {
|
|
1489
|
+
results.push(await validateConfigFile(filePath, filename));
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
if (results.length === 0) {
|
|
1493
|
+
warning("No config files found in current directory");
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
const hasErrors = results.some((r) => !r.valid);
|
|
1497
|
+
for (const result of results) {
|
|
1498
|
+
if (result.valid) {
|
|
1499
|
+
projectStatus(result.file, "success");
|
|
1500
|
+
} else {
|
|
1501
|
+
projectStatus(result.file, "error", result.error);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
if (hasErrors) {
|
|
1505
|
+
throw new Error("Validation failed");
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
async function validateConfigFile(filePath, filename) {
|
|
1509
|
+
const format = detectFormat(filePath);
|
|
1510
|
+
try {
|
|
1511
|
+
const content = await readFile(filePath, "utf-8");
|
|
1512
|
+
const parsed = format === "yaml" ? parse(content) : JSON.parse(content);
|
|
1513
|
+
MetaConfigSchema.parse(parsed);
|
|
1514
|
+
return { file: filename, valid: true };
|
|
1515
|
+
} catch (error2) {
|
|
1516
|
+
if (error2 instanceof SyntaxError) {
|
|
1517
|
+
return { file: filename, valid: false, error: "Invalid JSON" };
|
|
1518
|
+
}
|
|
1519
|
+
if (error2 instanceof Error && error2.name === "YAMLParseError") {
|
|
1520
|
+
return { file: filename, valid: false, error: "Invalid YAML" };
|
|
1521
|
+
}
|
|
1522
|
+
if (error2 instanceof Error && error2.name === "ZodError") {
|
|
1523
|
+
return { file: filename, valid: false, error: `Invalid structure: ${error2.message}` };
|
|
1524
|
+
}
|
|
1525
|
+
return { file: filename, valid: false, error: String(error2) };
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
async function validateLoopRcFile(filePath) {
|
|
1529
|
+
try {
|
|
1530
|
+
const content = await readFile(filePath, "utf-8");
|
|
1531
|
+
const parsed = JSON.parse(content);
|
|
1532
|
+
LoopRcSchema.parse(parsed);
|
|
1533
|
+
return { file: LOOPRC_FILE, valid: true };
|
|
1534
|
+
} catch (error2) {
|
|
1535
|
+
if (error2 instanceof SyntaxError) {
|
|
1536
|
+
return { file: LOOPRC_FILE, valid: false, error: "Invalid JSON" };
|
|
1537
|
+
}
|
|
1538
|
+
if (error2 instanceof Error && error2.name === "ZodError") {
|
|
1539
|
+
return { file: LOOPRC_FILE, valid: false, error: `Invalid structure: ${error2.message}` };
|
|
1540
|
+
}
|
|
1541
|
+
return { file: LOOPRC_FILE, valid: false, error: String(error2) };
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
function registerValidateCommand(program) {
|
|
1545
|
+
program.command("validate").description("Validate all config files in the current directory").action(async () => {
|
|
1546
|
+
await validateCommand();
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1452
1549
|
|
|
1453
1550
|
// src/cli.ts
|
|
1454
1551
|
function getVersion() {
|
|
@@ -1479,6 +1576,7 @@ function createProgram() {
|
|
|
1479
1576
|
registerGitCommands(program);
|
|
1480
1577
|
registerProjectCommands(program);
|
|
1481
1578
|
registerNpmCommands(program);
|
|
1579
|
+
registerValidateCommand(program);
|
|
1482
1580
|
return program;
|
|
1483
1581
|
}
|
|
1484
1582
|
async function main() {
|