alex-c-line 2.6.2 → 2.7.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/index.cjs +64 -28
- package/dist/index.js +64 -28
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ let _alextheman_utility_internal = require("@alextheman/utility/internal");
|
|
|
42
42
|
let zod = require("zod");
|
|
43
43
|
zod = __toESM(zod);
|
|
44
44
|
let node_module = require("node:module");
|
|
45
|
+
let toml = require("toml");
|
|
45
46
|
let gray_matter = require("gray-matter");
|
|
46
47
|
gray_matter = __toESM(gray_matter);
|
|
47
48
|
let _alextheman_utility_node = require("@alextheman/utility/node");
|
|
@@ -120,8 +121,8 @@ function cache(program) {
|
|
|
120
121
|
loadCommands(program.command("cache").description("Commands related to the alex-c-line cache"), { cachePath });
|
|
121
122
|
}
|
|
122
123
|
//#endregion
|
|
123
|
-
//#region src/utility/constants/
|
|
124
|
-
const
|
|
124
|
+
//#region src/utility/constants/ERROR_PREFIX.ts
|
|
125
|
+
const ERROR_PREFIX = "❌ ERROR:";
|
|
125
126
|
//#endregion
|
|
126
127
|
//#region src/utility/envFile/upsertDotenvFile.ts
|
|
127
128
|
async function upsertDotenvFile(contents, envFilePath) {
|
|
@@ -132,14 +133,14 @@ async function upsertDotenvFile(contents, envFilePath) {
|
|
|
132
133
|
async function addVariable(program, envFileContents, file) {
|
|
133
134
|
const newVariableName = await (0, _inquirer_prompts.input)({ message: "Please enter the name of the environment variable you would like to add." });
|
|
134
135
|
if (newVariableName in envFileContents) program.error(`
|
|
135
|
-
${
|
|
136
|
+
${ERROR_PREFIX} Error with chosen environment variable name ${newVariableName}.
|
|
136
137
|
Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
|
|
137
138
|
`, {
|
|
138
139
|
exitCode: 2,
|
|
139
140
|
code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
|
|
140
141
|
});
|
|
141
142
|
if (/[ \t\r\n]/.test(newVariableName)) program.error(_alextheman_utility.normaliseIndents`
|
|
142
|
-
${
|
|
143
|
+
${ERROR_PREFIX} Error with chosen environment variable name ${newVariableName}.
|
|
143
144
|
Environment variables are not allowed to have whitespace.
|
|
144
145
|
`, {
|
|
145
146
|
exitCode: 2,
|
|
@@ -274,7 +275,7 @@ function checkLockfileVersionDiscrepancy(program) {
|
|
|
274
275
|
const { version: packageVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package.json"), "utf-8"));
|
|
275
276
|
const { version: packageLockVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package-lock.json"), "utf-8"));
|
|
276
277
|
if (packageVersion !== packageLockVersion) {
|
|
277
|
-
console.error(`${
|
|
278
|
+
console.error(`${ERROR_PREFIX} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
|
|
278
279
|
process.exitCode = 1;
|
|
279
280
|
return;
|
|
280
281
|
}
|
|
@@ -287,7 +288,7 @@ function gitPostMergeCleanup(program) {
|
|
|
287
288
|
program.command("git-post-merge-cleanup").alias("git-cleanup").description("Run after merging into a given branch to quickly clean up").argument("[branch]", "The branch you want to merge into", "main").option("--rebase", "Enable if your repository mainly rebases into main", true).action(async (branch, { rebase }) => {
|
|
288
289
|
console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
|
|
289
290
|
const { stdout: currentBranch } = await execa.execa`git branch --show-current`;
|
|
290
|
-
if (currentBranch === branch) program.error(`${
|
|
291
|
+
if (currentBranch === branch) program.error(`${ERROR_PREFIX} Cannot run cleanup on ${branch} branch!`, {
|
|
291
292
|
exitCode: 1,
|
|
292
293
|
code: "INVALID_BRANCH"
|
|
293
294
|
});
|
|
@@ -303,7 +304,7 @@ function gitPostMergeCleanup(program) {
|
|
|
303
304
|
const { stdout: changes } = await execa.execa`git diff ${branch}..${currentBranch}`;
|
|
304
305
|
if (changes) {
|
|
305
306
|
await execa.execa`git checkout ${currentBranch}`;
|
|
306
|
-
program.error(`${
|
|
307
|
+
program.error(`${ERROR_PREFIX} Changes on branch not fully merged!`, {
|
|
307
308
|
exitCode: 1,
|
|
308
309
|
code: "CHANGES_NOT_MERGED"
|
|
309
310
|
});
|
|
@@ -313,7 +314,7 @@ function gitPostMergeCleanup(program) {
|
|
|
313
314
|
const { stdout: branchDeletedMessage, exitCode } = await (0, execa.execa)({ reject: false })`git branch --delete ${currentBranch}`;
|
|
314
315
|
if (exitCode !== 0) {
|
|
315
316
|
await execa.execa`git checkout ${currentBranch}`;
|
|
316
|
-
program.error(`${
|
|
317
|
+
program.error(`${ERROR_PREFIX} Changes on branch not fully merged!`, {
|
|
317
318
|
exitCode: 1,
|
|
318
319
|
code: "CHANGES_NOT_MERGED"
|
|
319
320
|
});
|
|
@@ -323,8 +324,8 @@ function gitPostMergeCleanup(program) {
|
|
|
323
324
|
});
|
|
324
325
|
}
|
|
325
326
|
//#endregion
|
|
326
|
-
//#region src/utility/constants/
|
|
327
|
-
const
|
|
327
|
+
//#region src/utility/constants/WARNING_PREFIX.ts
|
|
328
|
+
const WARNING_PREFIX = "WARNING:";
|
|
328
329
|
//#endregion
|
|
329
330
|
//#region src/utility/fileSystem/readdirSafe.ts
|
|
330
331
|
async function readdirSafe(path) {
|
|
@@ -361,7 +362,7 @@ function internalMediaGenerate(program) {
|
|
|
361
362
|
if (resolution) return await runManimCommand`manim -qh -r ${resolution} ${file}`;
|
|
362
363
|
return await runManimCommand`manim -qh ${file}`;
|
|
363
364
|
} catch (error) {
|
|
364
|
-
if (error instanceof execa.ExecaError) program.error(`${
|
|
365
|
+
if (error instanceof execa.ExecaError) program.error(`${ERROR_PREFIX} An error has occurred with Manim while rendering ${relativePath}.`, {
|
|
365
366
|
exitCode: error.exitCode ?? 1,
|
|
366
367
|
code: "MANIM_ERROR"
|
|
367
368
|
});
|
|
@@ -380,7 +381,7 @@ function internalMediaGenerate(program) {
|
|
|
380
381
|
const statResult = await (0, node_fs_promises.stat)(target);
|
|
381
382
|
if (statResult.isFile()) await renderFile(target);
|
|
382
383
|
else if (statResult.isDirectory()) await readDirectory(target);
|
|
383
|
-
else console.warn(`${
|
|
384
|
+
else console.warn(`${WARNING_PREFIX} Not a file or directory.`);
|
|
384
385
|
});
|
|
385
386
|
}
|
|
386
387
|
//#endregion
|
|
@@ -404,7 +405,7 @@ async function findPackageRoot(startDirectory, packageName) {
|
|
|
404
405
|
throw new _alextheman_utility.DataError({ packageName }, "PACKAGE_ROOT_NOT_FOUND", `Could not find package root for ${packageName}`);
|
|
405
406
|
}
|
|
406
407
|
//#endregion
|
|
407
|
-
//#region src/utility/constants/
|
|
408
|
+
//#region src/utility/constants/ALEX_C_LINE_PACKAGE_ROOT.ts
|
|
408
409
|
const __filename$3 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
409
410
|
const ALEX_C_LINE_PACKAGE_ROOT = findPackageRoot(node_path.default.dirname(__filename$3), "alex-c-line");
|
|
410
411
|
//#endregion
|
|
@@ -655,7 +656,7 @@ function localPackageUse(program) {
|
|
|
655
656
|
stdio: "inherit",
|
|
656
657
|
reject: false
|
|
657
658
|
});
|
|
658
|
-
if (exitCode !== 0) program.error(`${
|
|
659
|
+
if (exitCode !== 0) program.error(`${ERROR_PREFIX} An error occurred during the local \`alex-c-line\` run.`, {
|
|
659
660
|
exitCode,
|
|
660
661
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
661
662
|
});
|
|
@@ -718,6 +719,43 @@ function localPackage(program) {
|
|
|
718
719
|
loadCommands(program.command("local-package").description("Manage the use of local packages in your JavaScript project."), { localPackageUse });
|
|
719
720
|
}
|
|
720
721
|
//#endregion
|
|
722
|
+
//#region src/utility/constants/SUCCESS_PREFIX.ts
|
|
723
|
+
const SUCCESS_PREFIX = chalk.default.green("✓");
|
|
724
|
+
//#endregion
|
|
725
|
+
//#region src/cli/commands/pyproject/check/preferExactDependencyVersions.ts
|
|
726
|
+
const pyprojectSchema = zod.default.object({
|
|
727
|
+
project: zod.default.object({ dependencies: zod.default.array(zod.default.string()).optional() }),
|
|
728
|
+
"dependency-groups": zod.default.object({ dev: zod.default.array(zod.default.string()).optional() })
|
|
729
|
+
}).partial();
|
|
730
|
+
async function preferExactDependencyVersions(program) {
|
|
731
|
+
const data = (0, _alextheman_utility.parseZodSchema)(pyprojectSchema, (0, toml.parse)(await (0, node_fs_promises.readFile)("pyproject.toml", "utf-8")));
|
|
732
|
+
const sections = [data.project?.dependencies ?? [], data["dependency-groups"]?.dev ?? []];
|
|
733
|
+
const violations = [];
|
|
734
|
+
for (const dependencies of sections) for (const dependency of dependencies) if (!dependency.includes("==")) violations.push(dependency);
|
|
735
|
+
if (violations.length !== 0) program.error(`${ERROR_PREFIX} Non-exact dependencies found:\n\n${violations.join("\n")}`, {
|
|
736
|
+
code: "NON_EXACT_DEPENDENCIES_FOUND",
|
|
737
|
+
exitCode: 2
|
|
738
|
+
});
|
|
739
|
+
console.info(`${SUCCESS_PREFIX} All dependencies are exactly pinned`);
|
|
740
|
+
}
|
|
741
|
+
//#endregion
|
|
742
|
+
//#region src/cli/commands/pyproject/check/index.ts
|
|
743
|
+
const RuleName$1 = { PREFER_EXACT_DEPENDENCY_VERSIONS: "prefer-exact-dependency-versions" };
|
|
744
|
+
function pyprojectCheck(program) {
|
|
745
|
+
program.command("check").description("Run checks on your pyproject.toml file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
746
|
+
const rawRuleNamesArray = rawRules.split(",");
|
|
747
|
+
return (0, _alextheman_utility.parseZodSchema)(zod.default.array(zod.default.enum(RuleName$1)), rawRuleNamesArray);
|
|
748
|
+
}).action(async ({ rules }) => {
|
|
749
|
+
if (rules?.includes("prefer-exact-dependency-versions")) await preferExactDependencyVersions(program);
|
|
750
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
//#endregion
|
|
754
|
+
//#region src/cli/commands/pyproject/index.ts
|
|
755
|
+
function pyproject(program) {
|
|
756
|
+
loadCommands(program.command("pyproject").description("Manage the pyproject.toml file."), { pyprojectCheck });
|
|
757
|
+
}
|
|
758
|
+
//#endregion
|
|
721
759
|
//#region src/cli/commands/root/pre-commit/createStepRunner.ts
|
|
722
760
|
const runCommandAndLogToConsole = (0, execa.execa)({
|
|
723
761
|
stdio: "inherit",
|
|
@@ -755,7 +793,7 @@ function createStepRunner(program) {
|
|
|
755
793
|
//#endregion
|
|
756
794
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
757
795
|
function getCommandArguments(program, script, scripts, args) {
|
|
758
|
-
if (!(script in (scripts ?? {}))) program.error(`${
|
|
796
|
+
if (!(script in (scripts ?? {}))) program.error(`${ERROR_PREFIX} Could not find script \`${script}\` in package.json.`, {
|
|
759
797
|
exitCode: 1,
|
|
760
798
|
code: "SCRIPT_NOT_FOUND"
|
|
761
799
|
});
|
|
@@ -788,7 +826,7 @@ function preCommit(program) {
|
|
|
788
826
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
789
827
|
const { exitCode: diffExitCode } = await (0, execa.execa)({ reject: false })`git diff --cached --quiet`;
|
|
790
828
|
switch (diffExitCode) {
|
|
791
|
-
case 128: program.error(`${
|
|
829
|
+
case 128: program.error(`${ERROR_PREFIX} Not currently in a Git repository`, {
|
|
792
830
|
exitCode: 1,
|
|
793
831
|
code: "GIT_DIFF_FAILED"
|
|
794
832
|
});
|
|
@@ -900,12 +938,9 @@ function templatePullRequest(program) {
|
|
|
900
938
|
loadCommands(program.command("pull-request").description("Manage the pull request templates."), { templatePullRequestCreate });
|
|
901
939
|
}
|
|
902
940
|
//#endregion
|
|
903
|
-
//#region src/utility/constants/successPrefix.ts
|
|
904
|
-
const successPrefix = chalk.default.green("✓");
|
|
905
|
-
//#endregion
|
|
906
941
|
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
907
942
|
function convertDataErrorToProgramError(dataError, program, options) {
|
|
908
|
-
program.error(`${
|
|
943
|
+
program.error(`${ERROR_PREFIX} ${dataError.message}`, {
|
|
909
944
|
exitCode: options?.exitCode ?? 1,
|
|
910
945
|
code: dataError.code
|
|
911
946
|
});
|
|
@@ -1006,7 +1041,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
1006
1041
|
}).join("."));
|
|
1007
1042
|
try {
|
|
1008
1043
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
1009
|
-
console.info(`${
|
|
1044
|
+
console.info(`${SUCCESS_PREFIX} Release document is valid!`);
|
|
1010
1045
|
} catch (error) {
|
|
1011
1046
|
if (_alextheman_utility.DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
1012
1047
|
else throw error;
|
|
@@ -1098,7 +1133,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1098
1133
|
await (0, node_fs_promises.mkdir)(node_path.default.dirname(releaseNotePath), { recursive: true });
|
|
1099
1134
|
await (0, node_fs_promises.writeFile)(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1100
1135
|
} catch (error) {
|
|
1101
|
-
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${
|
|
1136
|
+
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${ERROR_PREFIX} Release notes already exist.`, {
|
|
1102
1137
|
exitCode: 1,
|
|
1103
1138
|
code: "RELEASE_NOTE_EXISTS"
|
|
1104
1139
|
});
|
|
@@ -1168,7 +1203,7 @@ function template(program) {
|
|
|
1168
1203
|
//#endregion
|
|
1169
1204
|
//#region package.json
|
|
1170
1205
|
var name = "alex-c-line";
|
|
1171
|
-
var version$1 = "2.
|
|
1206
|
+
var version$1 = "2.7.0";
|
|
1172
1207
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1173
1208
|
//#endregion
|
|
1174
1209
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1317,12 +1352,12 @@ async function noFileDependencies(program) {
|
|
|
1317
1352
|
};
|
|
1318
1353
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1319
1354
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1320
|
-
if (Object.keys(allFileDependencies).length !== 0) program.error(`${
|
|
1355
|
+
if (Object.keys(allFileDependencies).length !== 0) program.error(`${ERROR_PREFIX} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
|
|
1321
1356
|
`, {
|
|
1322
1357
|
exitCode: 2,
|
|
1323
1358
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
1324
1359
|
});
|
|
1325
|
-
console.info(`${
|
|
1360
|
+
console.info(`${SUCCESS_PREFIX} No file dependencies found!`);
|
|
1326
1361
|
}
|
|
1327
1362
|
//#endregion
|
|
1328
1363
|
//#region src/cli/commands/package-json/check/noPreReleaseDependencies.ts
|
|
@@ -1340,7 +1375,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1340
1375
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1341
1376
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1342
1377
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(_alextheman_utility.normaliseIndents`
|
|
1343
|
-
${
|
|
1378
|
+
${ERROR_PREFIX} Pre-release version pinning is not allowed. Found the following violations:
|
|
1344
1379
|
|
|
1345
1380
|
` + JSON.stringify({
|
|
1346
1381
|
dependencies: preReleaseDependencies,
|
|
@@ -1349,7 +1384,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1349
1384
|
exitCode: 2,
|
|
1350
1385
|
code: "UNEXPECTED_PRE_RELEASE_VERSION"
|
|
1351
1386
|
});
|
|
1352
|
-
console.info(`${
|
|
1387
|
+
console.info(`${SUCCESS_PREFIX} No pre-release versions found!`);
|
|
1353
1388
|
}
|
|
1354
1389
|
//#endregion
|
|
1355
1390
|
//#region src/cli/commands/package-json/check/index.ts
|
|
@@ -1364,7 +1399,7 @@ function packageJsonCheck(program) {
|
|
|
1364
1399
|
}).action(async ({ rules }) => {
|
|
1365
1400
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1366
1401
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
1367
|
-
console.info(`${
|
|
1402
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
1368
1403
|
});
|
|
1369
1404
|
}
|
|
1370
1405
|
//#endregion
|
|
@@ -1382,6 +1417,7 @@ function createCommands(program) {
|
|
|
1382
1417
|
internal,
|
|
1383
1418
|
localPackage,
|
|
1384
1419
|
packageJson,
|
|
1420
|
+
pyproject,
|
|
1385
1421
|
root,
|
|
1386
1422
|
template,
|
|
1387
1423
|
update,
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { ExecaError, execa } from "execa";
|
|
|
14
14
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
15
15
|
import { DependencyGroup, PackageManager, getDependenciesFromGroup, getExpectedTgzName, getPackageJsonContents, packageJsonNotFoundError } from "@alextheman/utility/internal";
|
|
16
16
|
import z from "zod";
|
|
17
|
+
import { parse as parse$1 } from "toml";
|
|
17
18
|
import matter from "gray-matter";
|
|
18
19
|
import { parseFilePath } from "@alextheman/utility/node";
|
|
19
20
|
import axios from "axios";
|
|
@@ -89,8 +90,8 @@ function cache(program) {
|
|
|
89
90
|
loadCommands(program.command("cache").description("Commands related to the alex-c-line cache"), { cachePath });
|
|
90
91
|
}
|
|
91
92
|
//#endregion
|
|
92
|
-
//#region src/utility/constants/
|
|
93
|
-
const
|
|
93
|
+
//#region src/utility/constants/ERROR_PREFIX.ts
|
|
94
|
+
const ERROR_PREFIX = "❌ ERROR:";
|
|
94
95
|
//#endregion
|
|
95
96
|
//#region src/utility/envFile/upsertDotenvFile.ts
|
|
96
97
|
async function upsertDotenvFile(contents, envFilePath) {
|
|
@@ -101,14 +102,14 @@ async function upsertDotenvFile(contents, envFilePath) {
|
|
|
101
102
|
async function addVariable(program, envFileContents, file) {
|
|
102
103
|
const newVariableName = await input({ message: "Please enter the name of the environment variable you would like to add." });
|
|
103
104
|
if (newVariableName in envFileContents) program.error(`
|
|
104
|
-
${
|
|
105
|
+
${ERROR_PREFIX} Error with chosen environment variable name ${newVariableName}.
|
|
105
106
|
Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
|
|
106
107
|
`, {
|
|
107
108
|
exitCode: 2,
|
|
108
109
|
code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
|
|
109
110
|
});
|
|
110
111
|
if (/[ \t\r\n]/.test(newVariableName)) program.error(normaliseIndents`
|
|
111
|
-
${
|
|
112
|
+
${ERROR_PREFIX} Error with chosen environment variable name ${newVariableName}.
|
|
112
113
|
Environment variables are not allowed to have whitespace.
|
|
113
114
|
`, {
|
|
114
115
|
exitCode: 2,
|
|
@@ -243,7 +244,7 @@ function checkLockfileVersionDiscrepancy(program) {
|
|
|
243
244
|
const { version: packageVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package.json"), "utf-8"));
|
|
244
245
|
const { version: packageLockVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package-lock.json"), "utf-8"));
|
|
245
246
|
if (packageVersion !== packageLockVersion) {
|
|
246
|
-
console.error(`${
|
|
247
|
+
console.error(`${ERROR_PREFIX} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
|
|
247
248
|
process.exitCode = 1;
|
|
248
249
|
return;
|
|
249
250
|
}
|
|
@@ -256,7 +257,7 @@ function gitPostMergeCleanup(program) {
|
|
|
256
257
|
program.command("git-post-merge-cleanup").alias("git-cleanup").description("Run after merging into a given branch to quickly clean up").argument("[branch]", "The branch you want to merge into", "main").option("--rebase", "Enable if your repository mainly rebases into main", true).action(async (branch, { rebase }) => {
|
|
257
258
|
console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
|
|
258
259
|
const { stdout: currentBranch } = await execa`git branch --show-current`;
|
|
259
|
-
if (currentBranch === branch) program.error(`${
|
|
260
|
+
if (currentBranch === branch) program.error(`${ERROR_PREFIX} Cannot run cleanup on ${branch} branch!`, {
|
|
260
261
|
exitCode: 1,
|
|
261
262
|
code: "INVALID_BRANCH"
|
|
262
263
|
});
|
|
@@ -272,7 +273,7 @@ function gitPostMergeCleanup(program) {
|
|
|
272
273
|
const { stdout: changes } = await execa`git diff ${branch}..${currentBranch}`;
|
|
273
274
|
if (changes) {
|
|
274
275
|
await execa`git checkout ${currentBranch}`;
|
|
275
|
-
program.error(`${
|
|
276
|
+
program.error(`${ERROR_PREFIX} Changes on branch not fully merged!`, {
|
|
276
277
|
exitCode: 1,
|
|
277
278
|
code: "CHANGES_NOT_MERGED"
|
|
278
279
|
});
|
|
@@ -282,7 +283,7 @@ function gitPostMergeCleanup(program) {
|
|
|
282
283
|
const { stdout: branchDeletedMessage, exitCode } = await execa({ reject: false })`git branch --delete ${currentBranch}`;
|
|
283
284
|
if (exitCode !== 0) {
|
|
284
285
|
await execa`git checkout ${currentBranch}`;
|
|
285
|
-
program.error(`${
|
|
286
|
+
program.error(`${ERROR_PREFIX} Changes on branch not fully merged!`, {
|
|
286
287
|
exitCode: 1,
|
|
287
288
|
code: "CHANGES_NOT_MERGED"
|
|
288
289
|
});
|
|
@@ -292,8 +293,8 @@ function gitPostMergeCleanup(program) {
|
|
|
292
293
|
});
|
|
293
294
|
}
|
|
294
295
|
//#endregion
|
|
295
|
-
//#region src/utility/constants/
|
|
296
|
-
const
|
|
296
|
+
//#region src/utility/constants/WARNING_PREFIX.ts
|
|
297
|
+
const WARNING_PREFIX = "WARNING:";
|
|
297
298
|
//#endregion
|
|
298
299
|
//#region src/utility/fileSystem/readdirSafe.ts
|
|
299
300
|
async function readdirSafe(path) {
|
|
@@ -330,7 +331,7 @@ function internalMediaGenerate(program) {
|
|
|
330
331
|
if (resolution) return await runManimCommand`manim -qh -r ${resolution} ${file}`;
|
|
331
332
|
return await runManimCommand`manim -qh ${file}`;
|
|
332
333
|
} catch (error) {
|
|
333
|
-
if (error instanceof ExecaError) program.error(`${
|
|
334
|
+
if (error instanceof ExecaError) program.error(`${ERROR_PREFIX} An error has occurred with Manim while rendering ${relativePath}.`, {
|
|
334
335
|
exitCode: error.exitCode ?? 1,
|
|
335
336
|
code: "MANIM_ERROR"
|
|
336
337
|
});
|
|
@@ -349,7 +350,7 @@ function internalMediaGenerate(program) {
|
|
|
349
350
|
const statResult = await stat(target);
|
|
350
351
|
if (statResult.isFile()) await renderFile(target);
|
|
351
352
|
else if (statResult.isDirectory()) await readDirectory(target);
|
|
352
|
-
else console.warn(`${
|
|
353
|
+
else console.warn(`${WARNING_PREFIX} Not a file or directory.`);
|
|
353
354
|
});
|
|
354
355
|
}
|
|
355
356
|
//#endregion
|
|
@@ -373,7 +374,7 @@ async function findPackageRoot(startDirectory, packageName) {
|
|
|
373
374
|
throw new DataError({ packageName }, "PACKAGE_ROOT_NOT_FOUND", `Could not find package root for ${packageName}`);
|
|
374
375
|
}
|
|
375
376
|
//#endregion
|
|
376
|
-
//#region src/utility/constants/
|
|
377
|
+
//#region src/utility/constants/ALEX_C_LINE_PACKAGE_ROOT.ts
|
|
377
378
|
const __filename$2 = fileURLToPath(import.meta.url);
|
|
378
379
|
const ALEX_C_LINE_PACKAGE_ROOT = findPackageRoot(path.dirname(__filename$2), "alex-c-line");
|
|
379
380
|
//#endregion
|
|
@@ -624,7 +625,7 @@ function localPackageUse(program) {
|
|
|
624
625
|
stdio: "inherit",
|
|
625
626
|
reject: false
|
|
626
627
|
});
|
|
627
|
-
if (exitCode !== 0) program.error(`${
|
|
628
|
+
if (exitCode !== 0) program.error(`${ERROR_PREFIX} An error occurred during the local \`alex-c-line\` run.`, {
|
|
628
629
|
exitCode,
|
|
629
630
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
630
631
|
});
|
|
@@ -687,6 +688,43 @@ function localPackage(program) {
|
|
|
687
688
|
loadCommands(program.command("local-package").description("Manage the use of local packages in your JavaScript project."), { localPackageUse });
|
|
688
689
|
}
|
|
689
690
|
//#endregion
|
|
691
|
+
//#region src/utility/constants/SUCCESS_PREFIX.ts
|
|
692
|
+
const SUCCESS_PREFIX = chalk.green("✓");
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/cli/commands/pyproject/check/preferExactDependencyVersions.ts
|
|
695
|
+
const pyprojectSchema = z.object({
|
|
696
|
+
project: z.object({ dependencies: z.array(z.string()).optional() }),
|
|
697
|
+
"dependency-groups": z.object({ dev: z.array(z.string()).optional() })
|
|
698
|
+
}).partial();
|
|
699
|
+
async function preferExactDependencyVersions(program) {
|
|
700
|
+
const data = parseZodSchema(pyprojectSchema, parse$1(await readFile("pyproject.toml", "utf-8")));
|
|
701
|
+
const sections = [data.project?.dependencies ?? [], data["dependency-groups"]?.dev ?? []];
|
|
702
|
+
const violations = [];
|
|
703
|
+
for (const dependencies of sections) for (const dependency of dependencies) if (!dependency.includes("==")) violations.push(dependency);
|
|
704
|
+
if (violations.length !== 0) program.error(`${ERROR_PREFIX} Non-exact dependencies found:\n\n${violations.join("\n")}`, {
|
|
705
|
+
code: "NON_EXACT_DEPENDENCIES_FOUND",
|
|
706
|
+
exitCode: 2
|
|
707
|
+
});
|
|
708
|
+
console.info(`${SUCCESS_PREFIX} All dependencies are exactly pinned`);
|
|
709
|
+
}
|
|
710
|
+
//#endregion
|
|
711
|
+
//#region src/cli/commands/pyproject/check/index.ts
|
|
712
|
+
const RuleName$1 = { PREFER_EXACT_DEPENDENCY_VERSIONS: "prefer-exact-dependency-versions" };
|
|
713
|
+
function pyprojectCheck(program) {
|
|
714
|
+
program.command("check").description("Run checks on your pyproject.toml file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
715
|
+
const rawRuleNamesArray = rawRules.split(",");
|
|
716
|
+
return parseZodSchema(z.array(z.enum(RuleName$1)), rawRuleNamesArray);
|
|
717
|
+
}).action(async ({ rules }) => {
|
|
718
|
+
if (rules?.includes("prefer-exact-dependency-versions")) await preferExactDependencyVersions(program);
|
|
719
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
//#endregion
|
|
723
|
+
//#region src/cli/commands/pyproject/index.ts
|
|
724
|
+
function pyproject(program) {
|
|
725
|
+
loadCommands(program.command("pyproject").description("Manage the pyproject.toml file."), { pyprojectCheck });
|
|
726
|
+
}
|
|
727
|
+
//#endregion
|
|
690
728
|
//#region src/cli/commands/root/pre-commit/createStepRunner.ts
|
|
691
729
|
const runCommandAndLogToConsole = execa({
|
|
692
730
|
stdio: "inherit",
|
|
@@ -724,7 +762,7 @@ function createStepRunner(program) {
|
|
|
724
762
|
//#endregion
|
|
725
763
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
726
764
|
function getCommandArguments(program, script, scripts, args) {
|
|
727
|
-
if (!(script in (scripts ?? {}))) program.error(`${
|
|
765
|
+
if (!(script in (scripts ?? {}))) program.error(`${ERROR_PREFIX} Could not find script \`${script}\` in package.json.`, {
|
|
728
766
|
exitCode: 1,
|
|
729
767
|
code: "SCRIPT_NOT_FOUND"
|
|
730
768
|
});
|
|
@@ -757,7 +795,7 @@ function preCommit(program) {
|
|
|
757
795
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
758
796
|
const { exitCode: diffExitCode } = await execa({ reject: false })`git diff --cached --quiet`;
|
|
759
797
|
switch (diffExitCode) {
|
|
760
|
-
case 128: program.error(`${
|
|
798
|
+
case 128: program.error(`${ERROR_PREFIX} Not currently in a Git repository`, {
|
|
761
799
|
exitCode: 1,
|
|
762
800
|
code: "GIT_DIFF_FAILED"
|
|
763
801
|
});
|
|
@@ -869,12 +907,9 @@ function templatePullRequest(program) {
|
|
|
869
907
|
loadCommands(program.command("pull-request").description("Manage the pull request templates."), { templatePullRequestCreate });
|
|
870
908
|
}
|
|
871
909
|
//#endregion
|
|
872
|
-
//#region src/utility/constants/successPrefix.ts
|
|
873
|
-
const successPrefix = chalk.green("✓");
|
|
874
|
-
//#endregion
|
|
875
910
|
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
876
911
|
function convertDataErrorToProgramError(dataError, program, options) {
|
|
877
|
-
program.error(`${
|
|
912
|
+
program.error(`${ERROR_PREFIX} ${dataError.message}`, {
|
|
878
913
|
exitCode: options?.exitCode ?? 1,
|
|
879
914
|
code: dataError.code
|
|
880
915
|
});
|
|
@@ -975,7 +1010,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
975
1010
|
}).join("."));
|
|
976
1011
|
try {
|
|
977
1012
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
978
|
-
console.info(`${
|
|
1013
|
+
console.info(`${SUCCESS_PREFIX} Release document is valid!`);
|
|
979
1014
|
} catch (error) {
|
|
980
1015
|
if (DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
981
1016
|
else throw error;
|
|
@@ -1067,7 +1102,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1067
1102
|
await mkdir(path.dirname(releaseNotePath), { recursive: true });
|
|
1068
1103
|
await writeFile(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1069
1104
|
} catch (error) {
|
|
1070
|
-
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${
|
|
1105
|
+
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${ERROR_PREFIX} Release notes already exist.`, {
|
|
1071
1106
|
exitCode: 1,
|
|
1072
1107
|
code: "RELEASE_NOTE_EXISTS"
|
|
1073
1108
|
});
|
|
@@ -1137,7 +1172,7 @@ function template(program) {
|
|
|
1137
1172
|
//#endregion
|
|
1138
1173
|
//#region package.json
|
|
1139
1174
|
var name = "alex-c-line";
|
|
1140
|
-
var version$1 = "2.
|
|
1175
|
+
var version$1 = "2.7.0";
|
|
1141
1176
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1142
1177
|
//#endregion
|
|
1143
1178
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1286,12 +1321,12 @@ async function noFileDependencies(program) {
|
|
|
1286
1321
|
};
|
|
1287
1322
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1288
1323
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1289
|
-
if (Object.keys(allFileDependencies).length !== 0) program.error(`${
|
|
1324
|
+
if (Object.keys(allFileDependencies).length !== 0) program.error(`${ERROR_PREFIX} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
|
|
1290
1325
|
`, {
|
|
1291
1326
|
exitCode: 2,
|
|
1292
1327
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
1293
1328
|
});
|
|
1294
|
-
console.info(`${
|
|
1329
|
+
console.info(`${SUCCESS_PREFIX} No file dependencies found!`);
|
|
1295
1330
|
}
|
|
1296
1331
|
//#endregion
|
|
1297
1332
|
//#region src/cli/commands/package-json/check/noPreReleaseDependencies.ts
|
|
@@ -1309,7 +1344,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1309
1344
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1310
1345
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1311
1346
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(normaliseIndents`
|
|
1312
|
-
${
|
|
1347
|
+
${ERROR_PREFIX} Pre-release version pinning is not allowed. Found the following violations:
|
|
1313
1348
|
|
|
1314
1349
|
` + JSON.stringify({
|
|
1315
1350
|
dependencies: preReleaseDependencies,
|
|
@@ -1318,7 +1353,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1318
1353
|
exitCode: 2,
|
|
1319
1354
|
code: "UNEXPECTED_PRE_RELEASE_VERSION"
|
|
1320
1355
|
});
|
|
1321
|
-
console.info(`${
|
|
1356
|
+
console.info(`${SUCCESS_PREFIX} No pre-release versions found!`);
|
|
1322
1357
|
}
|
|
1323
1358
|
//#endregion
|
|
1324
1359
|
//#region src/cli/commands/package-json/check/index.ts
|
|
@@ -1333,7 +1368,7 @@ function packageJsonCheck(program) {
|
|
|
1333
1368
|
}).action(async ({ rules }) => {
|
|
1334
1369
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1335
1370
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
1336
|
-
console.info(`${
|
|
1371
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
1337
1372
|
});
|
|
1338
1373
|
}
|
|
1339
1374
|
//#endregion
|
|
@@ -1351,6 +1386,7 @@ function createCommands(program) {
|
|
|
1351
1386
|
internal,
|
|
1352
1387
|
localPackage,
|
|
1353
1388
|
packageJson,
|
|
1389
|
+
pyproject,
|
|
1354
1390
|
root,
|
|
1355
1391
|
template,
|
|
1356
1392
|
update,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alex-c-line",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Command-line tool with commands to streamline the developer workflow.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"gray-matter": "4.0.3",
|
|
49
49
|
"semver": "7.7.4",
|
|
50
50
|
"supports-color": "10.2.2",
|
|
51
|
+
"toml": "4.1.1",
|
|
51
52
|
"zod": "4.3.6"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|