alex-c-line 2.6.1 → 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 +74 -36
- package/dist/index.js +74 -36
- package/package.json +3 -2
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) {
|
|
@@ -338,7 +339,7 @@ async function readdirSafe(path) {
|
|
|
338
339
|
//#endregion
|
|
339
340
|
//#region src/cli/commands/internal/media/generate.ts
|
|
340
341
|
function internalMediaGenerate(program) {
|
|
341
|
-
program.command("generate").argument("[target]", "The directory to generate from", process.cwd()).option("--ignore <ignore>", "Extra directories to ignore as comma-separated list").action(async (target, { ignore }) => {
|
|
342
|
+
program.command("generate").argument("[target]", "The directory to generate from.", process.cwd()).option("--ignore <ignore>", "Extra directories to ignore as comma-separated list.").option("-r --resolution <resolution>", "The resolution of the rendered scenes, with a comma between width and height.").action(async (target, { ignore, resolution }) => {
|
|
342
343
|
const ignored = new Set([
|
|
343
344
|
".git",
|
|
344
345
|
"node_modules",
|
|
@@ -350,16 +351,18 @@ function internalMediaGenerate(program) {
|
|
|
350
351
|
async function renderFile(file) {
|
|
351
352
|
const relativePath = node_path.default.relative(process.cwd(), file);
|
|
352
353
|
console.info(`Rendering ${relativePath}...`);
|
|
354
|
+
const runManimCommand = (0, execa.execa)({
|
|
355
|
+
stdio: "inherit",
|
|
356
|
+
env: {
|
|
357
|
+
...process.env,
|
|
358
|
+
PYTHONPATH: node_path.default.resolve("src")
|
|
359
|
+
}
|
|
360
|
+
});
|
|
353
361
|
try {
|
|
354
|
-
return await
|
|
355
|
-
|
|
356
|
-
env: {
|
|
357
|
-
...process.env,
|
|
358
|
-
PYTHONPATH: node_path.default.resolve("src")
|
|
359
|
-
}
|
|
360
|
-
})`manim -qh ${file}`;
|
|
362
|
+
if (resolution) return await runManimCommand`manim -qh -r ${resolution} ${file}`;
|
|
363
|
+
return await runManimCommand`manim -qh ${file}`;
|
|
361
364
|
} catch (error) {
|
|
362
|
-
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}.`, {
|
|
363
366
|
exitCode: error.exitCode ?? 1,
|
|
364
367
|
code: "MANIM_ERROR"
|
|
365
368
|
});
|
|
@@ -378,7 +381,7 @@ function internalMediaGenerate(program) {
|
|
|
378
381
|
const statResult = await (0, node_fs_promises.stat)(target);
|
|
379
382
|
if (statResult.isFile()) await renderFile(target);
|
|
380
383
|
else if (statResult.isDirectory()) await readDirectory(target);
|
|
381
|
-
else console.warn(`${
|
|
384
|
+
else console.warn(`${WARNING_PREFIX} Not a file or directory.`);
|
|
382
385
|
});
|
|
383
386
|
}
|
|
384
387
|
//#endregion
|
|
@@ -402,7 +405,7 @@ async function findPackageRoot(startDirectory, packageName) {
|
|
|
402
405
|
throw new _alextheman_utility.DataError({ packageName }, "PACKAGE_ROOT_NOT_FOUND", `Could not find package root for ${packageName}`);
|
|
403
406
|
}
|
|
404
407
|
//#endregion
|
|
405
|
-
//#region src/utility/constants/
|
|
408
|
+
//#region src/utility/constants/ALEX_C_LINE_PACKAGE_ROOT.ts
|
|
406
409
|
const __filename$3 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
407
410
|
const ALEX_C_LINE_PACKAGE_ROOT = findPackageRoot(node_path.default.dirname(__filename$3), "alex-c-line");
|
|
408
411
|
//#endregion
|
|
@@ -653,7 +656,7 @@ function localPackageUse(program) {
|
|
|
653
656
|
stdio: "inherit",
|
|
654
657
|
reject: false
|
|
655
658
|
});
|
|
656
|
-
if (exitCode !== 0) program.error(`${
|
|
659
|
+
if (exitCode !== 0) program.error(`${ERROR_PREFIX} An error occurred during the local \`alex-c-line\` run.`, {
|
|
657
660
|
exitCode,
|
|
658
661
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
659
662
|
});
|
|
@@ -716,6 +719,43 @@ function localPackage(program) {
|
|
|
716
719
|
loadCommands(program.command("local-package").description("Manage the use of local packages in your JavaScript project."), { localPackageUse });
|
|
717
720
|
}
|
|
718
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
|
|
719
759
|
//#region src/cli/commands/root/pre-commit/createStepRunner.ts
|
|
720
760
|
const runCommandAndLogToConsole = (0, execa.execa)({
|
|
721
761
|
stdio: "inherit",
|
|
@@ -753,7 +793,7 @@ function createStepRunner(program) {
|
|
|
753
793
|
//#endregion
|
|
754
794
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
755
795
|
function getCommandArguments(program, script, scripts, args) {
|
|
756
|
-
if (!(script in (scripts ?? {}))) program.error(`${
|
|
796
|
+
if (!(script in (scripts ?? {}))) program.error(`${ERROR_PREFIX} Could not find script \`${script}\` in package.json.`, {
|
|
757
797
|
exitCode: 1,
|
|
758
798
|
code: "SCRIPT_NOT_FOUND"
|
|
759
799
|
});
|
|
@@ -786,7 +826,7 @@ function preCommit(program) {
|
|
|
786
826
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
787
827
|
const { exitCode: diffExitCode } = await (0, execa.execa)({ reject: false })`git diff --cached --quiet`;
|
|
788
828
|
switch (diffExitCode) {
|
|
789
|
-
case 128: program.error(`${
|
|
829
|
+
case 128: program.error(`${ERROR_PREFIX} Not currently in a Git repository`, {
|
|
790
830
|
exitCode: 1,
|
|
791
831
|
code: "GIT_DIFF_FAILED"
|
|
792
832
|
});
|
|
@@ -898,12 +938,9 @@ function templatePullRequest(program) {
|
|
|
898
938
|
loadCommands(program.command("pull-request").description("Manage the pull request templates."), { templatePullRequestCreate });
|
|
899
939
|
}
|
|
900
940
|
//#endregion
|
|
901
|
-
//#region src/utility/constants/successPrefix.ts
|
|
902
|
-
const successPrefix = chalk.default.green("✓");
|
|
903
|
-
//#endregion
|
|
904
941
|
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
905
942
|
function convertDataErrorToProgramError(dataError, program, options) {
|
|
906
|
-
program.error(`${
|
|
943
|
+
program.error(`${ERROR_PREFIX} ${dataError.message}`, {
|
|
907
944
|
exitCode: options?.exitCode ?? 1,
|
|
908
945
|
code: dataError.code
|
|
909
946
|
});
|
|
@@ -1004,7 +1041,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
1004
1041
|
}).join("."));
|
|
1005
1042
|
try {
|
|
1006
1043
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
1007
|
-
console.info(`${
|
|
1044
|
+
console.info(`${SUCCESS_PREFIX} Release document is valid!`);
|
|
1008
1045
|
} catch (error) {
|
|
1009
1046
|
if (_alextheman_utility.DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
1010
1047
|
else throw error;
|
|
@@ -1096,7 +1133,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1096
1133
|
await (0, node_fs_promises.mkdir)(node_path.default.dirname(releaseNotePath), { recursive: true });
|
|
1097
1134
|
await (0, node_fs_promises.writeFile)(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1098
1135
|
} catch (error) {
|
|
1099
|
-
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.`, {
|
|
1100
1137
|
exitCode: 1,
|
|
1101
1138
|
code: "RELEASE_NOTE_EXISTS"
|
|
1102
1139
|
});
|
|
@@ -1166,7 +1203,7 @@ function template(program) {
|
|
|
1166
1203
|
//#endregion
|
|
1167
1204
|
//#region package.json
|
|
1168
1205
|
var name = "alex-c-line";
|
|
1169
|
-
var version$1 = "2.
|
|
1206
|
+
var version$1 = "2.7.0";
|
|
1170
1207
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1171
1208
|
//#endregion
|
|
1172
1209
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1315,12 +1352,12 @@ async function noFileDependencies(program) {
|
|
|
1315
1352
|
};
|
|
1316
1353
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1317
1354
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1318
|
-
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)}
|
|
1319
1356
|
`, {
|
|
1320
1357
|
exitCode: 2,
|
|
1321
1358
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
1322
1359
|
});
|
|
1323
|
-
console.info(`${
|
|
1360
|
+
console.info(`${SUCCESS_PREFIX} No file dependencies found!`);
|
|
1324
1361
|
}
|
|
1325
1362
|
//#endregion
|
|
1326
1363
|
//#region src/cli/commands/package-json/check/noPreReleaseDependencies.ts
|
|
@@ -1338,7 +1375,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1338
1375
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1339
1376
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1340
1377
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(_alextheman_utility.normaliseIndents`
|
|
1341
|
-
${
|
|
1378
|
+
${ERROR_PREFIX} Pre-release version pinning is not allowed. Found the following violations:
|
|
1342
1379
|
|
|
1343
1380
|
` + JSON.stringify({
|
|
1344
1381
|
dependencies: preReleaseDependencies,
|
|
@@ -1347,7 +1384,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1347
1384
|
exitCode: 2,
|
|
1348
1385
|
code: "UNEXPECTED_PRE_RELEASE_VERSION"
|
|
1349
1386
|
});
|
|
1350
|
-
console.info(`${
|
|
1387
|
+
console.info(`${SUCCESS_PREFIX} No pre-release versions found!`);
|
|
1351
1388
|
}
|
|
1352
1389
|
//#endregion
|
|
1353
1390
|
//#region src/cli/commands/package-json/check/index.ts
|
|
@@ -1362,7 +1399,7 @@ function packageJsonCheck(program) {
|
|
|
1362
1399
|
}).action(async ({ rules }) => {
|
|
1363
1400
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1364
1401
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
1365
|
-
console.info(`${
|
|
1402
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
1366
1403
|
});
|
|
1367
1404
|
}
|
|
1368
1405
|
//#endregion
|
|
@@ -1380,6 +1417,7 @@ function createCommands(program) {
|
|
|
1380
1417
|
internal,
|
|
1381
1418
|
localPackage,
|
|
1382
1419
|
packageJson,
|
|
1420
|
+
pyproject,
|
|
1383
1421
|
root,
|
|
1384
1422
|
template,
|
|
1385
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) {
|
|
@@ -307,7 +308,7 @@ async function readdirSafe(path) {
|
|
|
307
308
|
//#endregion
|
|
308
309
|
//#region src/cli/commands/internal/media/generate.ts
|
|
309
310
|
function internalMediaGenerate(program) {
|
|
310
|
-
program.command("generate").argument("[target]", "The directory to generate from", process.cwd()).option("--ignore <ignore>", "Extra directories to ignore as comma-separated list").action(async (target, { ignore }) => {
|
|
311
|
+
program.command("generate").argument("[target]", "The directory to generate from.", process.cwd()).option("--ignore <ignore>", "Extra directories to ignore as comma-separated list.").option("-r --resolution <resolution>", "The resolution of the rendered scenes, with a comma between width and height.").action(async (target, { ignore, resolution }) => {
|
|
311
312
|
const ignored = new Set([
|
|
312
313
|
".git",
|
|
313
314
|
"node_modules",
|
|
@@ -319,16 +320,18 @@ function internalMediaGenerate(program) {
|
|
|
319
320
|
async function renderFile(file) {
|
|
320
321
|
const relativePath = path.relative(process.cwd(), file);
|
|
321
322
|
console.info(`Rendering ${relativePath}...`);
|
|
323
|
+
const runManimCommand = execa({
|
|
324
|
+
stdio: "inherit",
|
|
325
|
+
env: {
|
|
326
|
+
...process.env,
|
|
327
|
+
PYTHONPATH: path.resolve("src")
|
|
328
|
+
}
|
|
329
|
+
});
|
|
322
330
|
try {
|
|
323
|
-
return await
|
|
324
|
-
|
|
325
|
-
env: {
|
|
326
|
-
...process.env,
|
|
327
|
-
PYTHONPATH: path.resolve("src")
|
|
328
|
-
}
|
|
329
|
-
})`manim -qh ${file}`;
|
|
331
|
+
if (resolution) return await runManimCommand`manim -qh -r ${resolution} ${file}`;
|
|
332
|
+
return await runManimCommand`manim -qh ${file}`;
|
|
330
333
|
} catch (error) {
|
|
331
|
-
if (error instanceof ExecaError) program.error(`${
|
|
334
|
+
if (error instanceof ExecaError) program.error(`${ERROR_PREFIX} An error has occurred with Manim while rendering ${relativePath}.`, {
|
|
332
335
|
exitCode: error.exitCode ?? 1,
|
|
333
336
|
code: "MANIM_ERROR"
|
|
334
337
|
});
|
|
@@ -347,7 +350,7 @@ function internalMediaGenerate(program) {
|
|
|
347
350
|
const statResult = await stat(target);
|
|
348
351
|
if (statResult.isFile()) await renderFile(target);
|
|
349
352
|
else if (statResult.isDirectory()) await readDirectory(target);
|
|
350
|
-
else console.warn(`${
|
|
353
|
+
else console.warn(`${WARNING_PREFIX} Not a file or directory.`);
|
|
351
354
|
});
|
|
352
355
|
}
|
|
353
356
|
//#endregion
|
|
@@ -371,7 +374,7 @@ async function findPackageRoot(startDirectory, packageName) {
|
|
|
371
374
|
throw new DataError({ packageName }, "PACKAGE_ROOT_NOT_FOUND", `Could not find package root for ${packageName}`);
|
|
372
375
|
}
|
|
373
376
|
//#endregion
|
|
374
|
-
//#region src/utility/constants/
|
|
377
|
+
//#region src/utility/constants/ALEX_C_LINE_PACKAGE_ROOT.ts
|
|
375
378
|
const __filename$2 = fileURLToPath(import.meta.url);
|
|
376
379
|
const ALEX_C_LINE_PACKAGE_ROOT = findPackageRoot(path.dirname(__filename$2), "alex-c-line");
|
|
377
380
|
//#endregion
|
|
@@ -622,7 +625,7 @@ function localPackageUse(program) {
|
|
|
622
625
|
stdio: "inherit",
|
|
623
626
|
reject: false
|
|
624
627
|
});
|
|
625
|
-
if (exitCode !== 0) program.error(`${
|
|
628
|
+
if (exitCode !== 0) program.error(`${ERROR_PREFIX} An error occurred during the local \`alex-c-line\` run.`, {
|
|
626
629
|
exitCode,
|
|
627
630
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
628
631
|
});
|
|
@@ -685,6 +688,43 @@ function localPackage(program) {
|
|
|
685
688
|
loadCommands(program.command("local-package").description("Manage the use of local packages in your JavaScript project."), { localPackageUse });
|
|
686
689
|
}
|
|
687
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
|
|
688
728
|
//#region src/cli/commands/root/pre-commit/createStepRunner.ts
|
|
689
729
|
const runCommandAndLogToConsole = execa({
|
|
690
730
|
stdio: "inherit",
|
|
@@ -722,7 +762,7 @@ function createStepRunner(program) {
|
|
|
722
762
|
//#endregion
|
|
723
763
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
724
764
|
function getCommandArguments(program, script, scripts, args) {
|
|
725
|
-
if (!(script in (scripts ?? {}))) program.error(`${
|
|
765
|
+
if (!(script in (scripts ?? {}))) program.error(`${ERROR_PREFIX} Could not find script \`${script}\` in package.json.`, {
|
|
726
766
|
exitCode: 1,
|
|
727
767
|
code: "SCRIPT_NOT_FOUND"
|
|
728
768
|
});
|
|
@@ -755,7 +795,7 @@ function preCommit(program) {
|
|
|
755
795
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
756
796
|
const { exitCode: diffExitCode } = await execa({ reject: false })`git diff --cached --quiet`;
|
|
757
797
|
switch (diffExitCode) {
|
|
758
|
-
case 128: program.error(`${
|
|
798
|
+
case 128: program.error(`${ERROR_PREFIX} Not currently in a Git repository`, {
|
|
759
799
|
exitCode: 1,
|
|
760
800
|
code: "GIT_DIFF_FAILED"
|
|
761
801
|
});
|
|
@@ -867,12 +907,9 @@ function templatePullRequest(program) {
|
|
|
867
907
|
loadCommands(program.command("pull-request").description("Manage the pull request templates."), { templatePullRequestCreate });
|
|
868
908
|
}
|
|
869
909
|
//#endregion
|
|
870
|
-
//#region src/utility/constants/successPrefix.ts
|
|
871
|
-
const successPrefix = chalk.green("✓");
|
|
872
|
-
//#endregion
|
|
873
910
|
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
874
911
|
function convertDataErrorToProgramError(dataError, program, options) {
|
|
875
|
-
program.error(`${
|
|
912
|
+
program.error(`${ERROR_PREFIX} ${dataError.message}`, {
|
|
876
913
|
exitCode: options?.exitCode ?? 1,
|
|
877
914
|
code: dataError.code
|
|
878
915
|
});
|
|
@@ -973,7 +1010,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
973
1010
|
}).join("."));
|
|
974
1011
|
try {
|
|
975
1012
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
976
|
-
console.info(`${
|
|
1013
|
+
console.info(`${SUCCESS_PREFIX} Release document is valid!`);
|
|
977
1014
|
} catch (error) {
|
|
978
1015
|
if (DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
979
1016
|
else throw error;
|
|
@@ -1065,7 +1102,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1065
1102
|
await mkdir(path.dirname(releaseNotePath), { recursive: true });
|
|
1066
1103
|
await writeFile(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1067
1104
|
} catch (error) {
|
|
1068
|
-
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.`, {
|
|
1069
1106
|
exitCode: 1,
|
|
1070
1107
|
code: "RELEASE_NOTE_EXISTS"
|
|
1071
1108
|
});
|
|
@@ -1135,7 +1172,7 @@ function template(program) {
|
|
|
1135
1172
|
//#endregion
|
|
1136
1173
|
//#region package.json
|
|
1137
1174
|
var name = "alex-c-line";
|
|
1138
|
-
var version$1 = "2.
|
|
1175
|
+
var version$1 = "2.7.0";
|
|
1139
1176
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1140
1177
|
//#endregion
|
|
1141
1178
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1284,12 +1321,12 @@ async function noFileDependencies(program) {
|
|
|
1284
1321
|
};
|
|
1285
1322
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1286
1323
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1287
|
-
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)}
|
|
1288
1325
|
`, {
|
|
1289
1326
|
exitCode: 2,
|
|
1290
1327
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
1291
1328
|
});
|
|
1292
|
-
console.info(`${
|
|
1329
|
+
console.info(`${SUCCESS_PREFIX} No file dependencies found!`);
|
|
1293
1330
|
}
|
|
1294
1331
|
//#endregion
|
|
1295
1332
|
//#region src/cli/commands/package-json/check/noPreReleaseDependencies.ts
|
|
@@ -1307,7 +1344,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1307
1344
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1308
1345
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1309
1346
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(normaliseIndents`
|
|
1310
|
-
${
|
|
1347
|
+
${ERROR_PREFIX} Pre-release version pinning is not allowed. Found the following violations:
|
|
1311
1348
|
|
|
1312
1349
|
` + JSON.stringify({
|
|
1313
1350
|
dependencies: preReleaseDependencies,
|
|
@@ -1316,7 +1353,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1316
1353
|
exitCode: 2,
|
|
1317
1354
|
code: "UNEXPECTED_PRE_RELEASE_VERSION"
|
|
1318
1355
|
});
|
|
1319
|
-
console.info(`${
|
|
1356
|
+
console.info(`${SUCCESS_PREFIX} No pre-release versions found!`);
|
|
1320
1357
|
}
|
|
1321
1358
|
//#endregion
|
|
1322
1359
|
//#region src/cli/commands/package-json/check/index.ts
|
|
@@ -1331,7 +1368,7 @@ function packageJsonCheck(program) {
|
|
|
1331
1368
|
}).action(async ({ rules }) => {
|
|
1332
1369
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1333
1370
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
1334
|
-
console.info(`${
|
|
1371
|
+
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
1335
1372
|
});
|
|
1336
1373
|
}
|
|
1337
1374
|
//#endregion
|
|
@@ -1349,6 +1386,7 @@ function createCommands(program) {
|
|
|
1349
1386
|
internal,
|
|
1350
1387
|
localPackage,
|
|
1351
1388
|
packageJson,
|
|
1389
|
+
pyproject,
|
|
1352
1390
|
root,
|
|
1353
1391
|
template,
|
|
1354
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": {
|
|
@@ -87,7 +88,7 @@
|
|
|
87
88
|
"format-prettier-javascript": "prettier --write \"./**/*.js\"",
|
|
88
89
|
"format-prettier-typescript": "prettier --write --parser typescript \"./**/*.ts\"",
|
|
89
90
|
"format-prettier-yml": "prettier --write \"./**/*.{yml,yaml}\"",
|
|
90
|
-
"lint": "pnpm run lint-tsc && pnpm run lint-eslint && pnpm run lint-markdownlint && pnpm run lint-prettier && pnpm run lint-
|
|
91
|
+
"lint": "pnpm run lint-tsc && pnpm run lint-eslint && pnpm run lint-markdownlint && pnpm run lint-prettier && pnpm run lint-pre-release",
|
|
91
92
|
"lint-eslint": "eslint \"package.json\" \"{src,tests}/**/*.ts\"",
|
|
92
93
|
"lint-markdownlint": "bash -o pipefail -c 'pnpm exec markdownlint-cli2 \"**/*.md\" \"!{node_modules,dist}/**\"| grep -v \"^Finding:\"'",
|
|
93
94
|
"lint-pre-release": "node dist/index.js package-json check --rules no-pre-release-dependencies",
|