alex-c-line 2.0.0 → 2.0.1
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 +16 -12
- package/dist/configs/index.d.cts +5 -5
- package/dist/configs/index.d.ts +5 -5
- package/dist/configs/internal/index.d.cts +5 -5
- package/dist/configs/internal/index.d.ts +5 -6
- package/dist/index.cjs +35 -57
- package/dist/index.js +35 -57
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/alextheman231/alex-c-line/actions/workflows/ci.yml)
|
|
8
8
|
[](https://github.com/alextheman231/alex-c-line/actions/workflows/publish.yml)
|
|
9
9
|
|
|
10
|
-
<img src="./
|
|
10
|
+
<img src="./media/alex-c-line.png" alt="alex-c-line artwork" width=250 height=250>
|
|
11
11
|
|
|
12
12
|
This is my command-line tool, which serves as a developer toolkit that can be used in any repository to streamline the developer workflow. It provides a flexible configuration system so you can customise its behaviour to match your workflow.
|
|
13
13
|
|
|
@@ -40,24 +40,24 @@ alex-c-line say-hello
|
|
|
40
40
|
Some commands may even take extra arguments. For example:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
alex-c-line
|
|
43
|
+
alex-c-line version increment v1.2.3 major
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Flags may also be passed through in the following way.
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
alex-c-line
|
|
49
|
+
alex-c-line version increment v1.2.3 major --no-prefix
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
Note that for `
|
|
52
|
+
Note that for `local-package use` specifically, you will need to add `--` before the local `alex-c-line` arguments to ensure that all flags get passed through correctly. Example:
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
-
alex-c-line
|
|
55
|
+
alex-c-line local-package use alex-c-line -- version increment v1.2.3 major --no-prefix
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## Configs
|
|
59
59
|
|
|
60
|
-
Some commands also support usage of the config system. For example, `pre-commit
|
|
60
|
+
Some commands also support usage of the config system. For example, `pre-commit` supports the `alex-c-line.config.js` file, and `local-package use` supports the more user-specific `.alex-c-line.private.config.js` file. `alex-c-line.config.js` is intended for shared configurations per repository, whereas `.alex-c-line.private.config.js` are for configurations specific to the user's usage.
|
|
61
61
|
|
|
62
62
|
The `configs` subpath provides some helper functions and types that may be helpful when constructing these configs. Namely, `defineAlexCLineConfig` can be used as a type helper, so that you get better type hints in the editor.
|
|
63
63
|
|
|
@@ -65,9 +65,11 @@ The `configs` subpath provides some helper functions and types that may be helpf
|
|
|
65
65
|
import { defineAlexCLineConfig } from "alex-c-line/configs";
|
|
66
66
|
|
|
67
67
|
export default defineAlexCLineConfig({
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
template: {
|
|
69
|
+
pullRequest: {
|
|
70
|
+
category: "general",
|
|
71
|
+
projectType: "package",
|
|
72
|
+
}
|
|
71
73
|
},
|
|
72
74
|
preCommit: {
|
|
73
75
|
packageManager: "pnpm",
|
|
@@ -84,9 +86,11 @@ import type { AlexCLineConfig } from "alex-c-line/configs";
|
|
|
84
86
|
import { scripts } from "./package.json" with { type: "json" };
|
|
85
87
|
|
|
86
88
|
const alexCLineConfig: AlexCLineConfig<keyof typeof scripts> = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
template: {
|
|
90
|
+
pullRequest: {
|
|
91
|
+
category: "general",
|
|
92
|
+
projectType: "package",
|
|
93
|
+
}
|
|
90
94
|
},
|
|
91
95
|
preCommit: {
|
|
92
96
|
packageManager: "pnpm",
|
package/dist/configs/index.d.cts
CHANGED
|
@@ -9,14 +9,14 @@ interface BaseOptions {
|
|
|
9
9
|
}
|
|
10
10
|
interface StepRunner<ExecaOptions extends Options = BaseOptions> {
|
|
11
11
|
<NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
|
|
12
|
-
(command: string, args?:
|
|
13
|
-
(strings: TemplateStringsArray, ...interpolations: TemplateExpression
|
|
12
|
+
(command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
|
|
13
|
+
(strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
|
|
14
14
|
}
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/configs/types/preCommit/PreCommitConfig.d.ts
|
|
17
17
|
interface PreCommitStepOptions {
|
|
18
18
|
/** Arguments to pass to the given script */
|
|
19
|
-
arguments?: string
|
|
19
|
+
arguments?: Array<string>;
|
|
20
20
|
}
|
|
21
21
|
type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
|
|
22
22
|
interface PreCommitConfig<ScriptName extends string = string> {
|
|
@@ -25,7 +25,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
|
|
|
25
25
|
/** Allow the hook to run even if there are no staged changes. */
|
|
26
26
|
allowNoStagedChanges?: boolean;
|
|
27
27
|
/** The steps to run in the pre-commit hook. */
|
|
28
|
-
steps:
|
|
28
|
+
steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
|
|
29
29
|
/** Update the git index after the run */
|
|
30
30
|
updateIndex?: boolean;
|
|
31
31
|
}
|
|
@@ -96,7 +96,7 @@ declare function definePreCommitConfig<ScriptName extends string = string>(confi
|
|
|
96
96
|
//#region src/configs/types/preCommit/PreCommitPrivateConfig.d.ts
|
|
97
97
|
interface PreCommitPrivateConfig<ScriptName extends string = string> {
|
|
98
98
|
/** List of script names to skip */
|
|
99
|
-
disableSteps?: ScriptName
|
|
99
|
+
disableSteps?: Array<ScriptName>;
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region src/configs/helpers/preCommit/definePreCommitPrivateConfig.d.ts
|
package/dist/configs/index.d.ts
CHANGED
|
@@ -10,14 +10,14 @@ interface BaseOptions {
|
|
|
10
10
|
}
|
|
11
11
|
interface StepRunner<ExecaOptions extends Options = BaseOptions> {
|
|
12
12
|
<NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
|
|
13
|
-
(command: string, args?:
|
|
14
|
-
(strings: TemplateStringsArray, ...interpolations: TemplateExpression
|
|
13
|
+
(command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
|
|
14
|
+
(strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/configs/types/preCommit/PreCommitConfig.d.ts
|
|
18
18
|
interface PreCommitStepOptions {
|
|
19
19
|
/** Arguments to pass to the given script */
|
|
20
|
-
arguments?: string
|
|
20
|
+
arguments?: Array<string>;
|
|
21
21
|
}
|
|
22
22
|
type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
|
|
23
23
|
interface PreCommitConfig<ScriptName extends string = string> {
|
|
@@ -26,7 +26,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
|
|
|
26
26
|
/** Allow the hook to run even if there are no staged changes. */
|
|
27
27
|
allowNoStagedChanges?: boolean;
|
|
28
28
|
/** The steps to run in the pre-commit hook. */
|
|
29
|
-
steps:
|
|
29
|
+
steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
|
|
30
30
|
/** Update the git index after the run */
|
|
31
31
|
updateIndex?: boolean;
|
|
32
32
|
}
|
|
@@ -97,7 +97,7 @@ declare function definePreCommitConfig<ScriptName extends string = string>(confi
|
|
|
97
97
|
//#region src/configs/types/preCommit/PreCommitPrivateConfig.d.ts
|
|
98
98
|
interface PreCommitPrivateConfig<ScriptName extends string = string> {
|
|
99
99
|
/** List of script names to skip */
|
|
100
|
-
disableSteps?: ScriptName
|
|
100
|
+
disableSteps?: Array<ScriptName>;
|
|
101
101
|
}
|
|
102
102
|
//#endregion
|
|
103
103
|
//#region src/configs/helpers/preCommit/definePreCommitPrivateConfig.d.ts
|
|
@@ -8,14 +8,14 @@ interface BaseOptions {
|
|
|
8
8
|
}
|
|
9
9
|
interface StepRunner<ExecaOptions extends Options = BaseOptions> {
|
|
10
10
|
<NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
|
|
11
|
-
(command: string, args?:
|
|
12
|
-
(strings: TemplateStringsArray, ...interpolations: TemplateExpression
|
|
11
|
+
(command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
|
|
12
|
+
(strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
|
|
13
13
|
}
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/configs/types/preCommit/PreCommitConfig.d.ts
|
|
16
16
|
interface PreCommitStepOptions {
|
|
17
17
|
/** Arguments to pass to the given script */
|
|
18
|
-
arguments?: string
|
|
18
|
+
arguments?: Array<string>;
|
|
19
19
|
}
|
|
20
20
|
type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
|
|
21
21
|
interface PreCommitConfig<ScriptName extends string = string> {
|
|
@@ -24,7 +24,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
|
|
|
24
24
|
/** Allow the hook to run even if there are no staged changes. */
|
|
25
25
|
allowNoStagedChanges?: boolean;
|
|
26
26
|
/** The steps to run in the pre-commit hook. */
|
|
27
|
-
steps:
|
|
27
|
+
steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
|
|
28
28
|
/** Update the git index after the run */
|
|
29
29
|
updateIndex?: boolean;
|
|
30
30
|
}
|
|
@@ -114,7 +114,7 @@ declare const PreCommitStep: {
|
|
|
114
114
|
type PreCommitStep = "build" | "format" | "lint" | "test";
|
|
115
115
|
//#endregion
|
|
116
116
|
//#region src/configs/internal/packageConfig.d.ts
|
|
117
|
-
declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?:
|
|
117
|
+
declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: Array<StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions]>): AlexCLineConfig<PreCommitStep>;
|
|
118
118
|
//#endregion
|
|
119
119
|
//#region src/configs/internal/testConfig.d.ts
|
|
120
120
|
declare const testConfig: AlexCLineConfig<"artwork">;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { PackageManager } from "@alextheman/utility/internal";
|
|
2
2
|
import { Options, Result, TemplateExpression } from "execa";
|
|
3
|
-
import "@alextheman/utility";
|
|
4
3
|
|
|
5
4
|
//#region src/cli/commands/root/pre-commit/createStepRunner.d.ts
|
|
6
5
|
interface BaseOptions {
|
|
@@ -9,14 +8,14 @@ interface BaseOptions {
|
|
|
9
8
|
}
|
|
10
9
|
interface StepRunner<ExecaOptions extends Options = BaseOptions> {
|
|
11
10
|
<NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
|
|
12
|
-
(command: string, args?:
|
|
13
|
-
(strings: TemplateStringsArray, ...interpolations: TemplateExpression
|
|
11
|
+
(command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
|
|
12
|
+
(strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
|
|
14
13
|
}
|
|
15
14
|
//#endregion
|
|
16
15
|
//#region src/configs/types/preCommit/PreCommitConfig.d.ts
|
|
17
16
|
interface PreCommitStepOptions {
|
|
18
17
|
/** Arguments to pass to the given script */
|
|
19
|
-
arguments?: string
|
|
18
|
+
arguments?: Array<string>;
|
|
20
19
|
}
|
|
21
20
|
type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
|
|
22
21
|
interface PreCommitConfig<ScriptName extends string = string> {
|
|
@@ -25,7 +24,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
|
|
|
25
24
|
/** Allow the hook to run even if there are no staged changes. */
|
|
26
25
|
allowNoStagedChanges?: boolean;
|
|
27
26
|
/** The steps to run in the pre-commit hook. */
|
|
28
|
-
steps:
|
|
27
|
+
steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
|
|
29
28
|
/** Update the git index after the run */
|
|
30
29
|
updateIndex?: boolean;
|
|
31
30
|
}
|
|
@@ -115,7 +114,7 @@ declare const PreCommitStep: {
|
|
|
115
114
|
type PreCommitStep = "build" | "format" | "lint" | "test";
|
|
116
115
|
//#endregion
|
|
117
116
|
//#region src/configs/internal/packageConfig.d.ts
|
|
118
|
-
declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?:
|
|
117
|
+
declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: Array<StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions]>): AlexCLineConfig<PreCommitStep>;
|
|
119
118
|
//#endregion
|
|
120
119
|
//#region src/configs/internal/testConfig.d.ts
|
|
121
120
|
declare const testConfig: AlexCLineConfig<"artwork">;
|
package/dist/index.cjs
CHANGED
|
@@ -192,7 +192,7 @@ function cache(program) {
|
|
|
192
192
|
|
|
193
193
|
//#endregion
|
|
194
194
|
//#region src/utility/constants/errorPrefix.ts
|
|
195
|
-
const errorPrefix = "❌ ERROR";
|
|
195
|
+
const errorPrefix = "❌ ERROR:";
|
|
196
196
|
|
|
197
197
|
//#endregion
|
|
198
198
|
//#region src/utility/envFile/upsertDotenvFile.ts
|
|
@@ -205,14 +205,14 @@ async function upsertDotenvFile(contents, envFilePath) {
|
|
|
205
205
|
async function addVariable(program, envFileContents, file) {
|
|
206
206
|
const newVariableName = await (0, _inquirer_prompts.input)({ message: "Please enter the name of the environment variable you would like to add." });
|
|
207
207
|
if (newVariableName in envFileContents) program.error(`
|
|
208
|
-
${errorPrefix}
|
|
208
|
+
${errorPrefix} Error with chosen environment variable name ${newVariableName}.
|
|
209
209
|
Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
|
|
210
210
|
`, {
|
|
211
211
|
exitCode: 2,
|
|
212
212
|
code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
|
|
213
213
|
});
|
|
214
214
|
if (/[ \t\r\n]/.test(newVariableName)) program.error(_alextheman_utility.normaliseIndents`
|
|
215
|
-
${errorPrefix}
|
|
215
|
+
${errorPrefix} Error with chosen environment variable name ${newVariableName}.
|
|
216
216
|
Environment variables are not allowed to have whitespace.
|
|
217
217
|
`, {
|
|
218
218
|
exitCode: 2,
|
|
@@ -355,7 +355,7 @@ function checkLockfileVersionDiscrepancy(program) {
|
|
|
355
355
|
const { version: packageVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package.json"), "utf-8"));
|
|
356
356
|
const { version: packageLockVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package-lock.json"), "utf-8"));
|
|
357
357
|
if (packageVersion !== packageLockVersion) {
|
|
358
|
-
console.error(
|
|
358
|
+
console.error(`${errorPrefix} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
|
|
359
359
|
process.exitCode = 1;
|
|
360
360
|
return;
|
|
361
361
|
}
|
|
@@ -369,7 +369,7 @@ function gitPostMergeCleanup(program) {
|
|
|
369
369
|
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 }) => {
|
|
370
370
|
console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
|
|
371
371
|
const { stdout: currentBranch } = await execa.execa`git branch --show-current`;
|
|
372
|
-
if (currentBranch === branch) program.error(
|
|
372
|
+
if (currentBranch === branch) program.error(`${errorPrefix} Cannot run cleanup on ${branch} branch!`, {
|
|
373
373
|
exitCode: 1,
|
|
374
374
|
code: "INVALID_BRANCH"
|
|
375
375
|
});
|
|
@@ -385,7 +385,7 @@ function gitPostMergeCleanup(program) {
|
|
|
385
385
|
const { stdout: changes } = await execa.execa`git diff ${branch}..${currentBranch}`;
|
|
386
386
|
if (changes) {
|
|
387
387
|
await execa.execa`git checkout ${currentBranch}`;
|
|
388
|
-
program.error(
|
|
388
|
+
program.error(`${errorPrefix} Changes on branch not fully merged!`, {
|
|
389
389
|
exitCode: 1,
|
|
390
390
|
code: "CHANGES_NOT_MERGED"
|
|
391
391
|
});
|
|
@@ -395,7 +395,7 @@ function gitPostMergeCleanup(program) {
|
|
|
395
395
|
const { stdout: branchDeletedMessage, exitCode } = await (0, execa.execa)({ reject: false })`git branch --delete ${currentBranch}`;
|
|
396
396
|
if (exitCode !== 0) {
|
|
397
397
|
await execa.execa`git checkout ${currentBranch}`;
|
|
398
|
-
program.error(
|
|
398
|
+
program.error(`${errorPrefix} Changes on branch not fully merged!`, {
|
|
399
399
|
exitCode: 1,
|
|
400
400
|
code: "CHANGES_NOT_MERGED"
|
|
401
401
|
});
|
|
@@ -653,10 +653,7 @@ function localPackageUse(program) {
|
|
|
653
653
|
PrivateConfigFileName.ES_MODULES_JAVASCRIPT,
|
|
654
654
|
PrivateConfigFileName.STANDARD_JAVASCRIPT
|
|
655
655
|
]);
|
|
656
|
-
if (!configPath)
|
|
657
|
-
exitCode: 1,
|
|
658
|
-
code: "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND"
|
|
659
|
-
});
|
|
656
|
+
if (!configPath) throw new _alextheman_utility.DataError({ configPath }, "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?");
|
|
660
657
|
const { localPackage: { enableCache, localPackages } } = await loadAlexCLinePrivateConfig(configPath);
|
|
661
658
|
const localPackage = localPackages[packageName];
|
|
662
659
|
if (!localPackage) throw new _alextheman_utility.DataError({
|
|
@@ -693,8 +690,8 @@ function localPackageUse(program) {
|
|
|
693
690
|
stdio: "inherit",
|
|
694
691
|
reject: false
|
|
695
692
|
});
|
|
696
|
-
if (exitCode !== 0
|
|
697
|
-
exitCode
|
|
693
|
+
if (exitCode !== 0) program.error(`${errorPrefix} An error occurred during the local \`alex-c-line\` run.`, {
|
|
694
|
+
exitCode,
|
|
698
695
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
699
696
|
});
|
|
700
697
|
} else {
|
|
@@ -764,7 +761,7 @@ function encryptWithKey(program) {
|
|
|
764
761
|
try {
|
|
765
762
|
console.info(await (0, _alextheman_utility.encryptWithKey)(publicKey, plaintextValue));
|
|
766
763
|
} catch {
|
|
767
|
-
program.error(
|
|
764
|
+
program.error(`${errorPrefix} Encryption failed. Please double-check that the given key is a valid base 64 string.`, {
|
|
768
765
|
exitCode: 1,
|
|
769
766
|
code: "ENCRYPTION_FAILED"
|
|
770
767
|
});
|
|
@@ -811,7 +808,7 @@ function createStepRunner(program) {
|
|
|
811
808
|
//#endregion
|
|
812
809
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
813
810
|
function getCommandArguments(program, script, scripts, args) {
|
|
814
|
-
if (!(script in (scripts ?? {}))) program.error(
|
|
811
|
+
if (!(script in (scripts ?? {}))) program.error(`${errorPrefix} Could not find script \`${script}\` in package.json.`, {
|
|
815
812
|
exitCode: 1,
|
|
816
813
|
code: "SCRIPT_NOT_FOUND"
|
|
817
814
|
});
|
|
@@ -837,19 +834,16 @@ async function loadAlexCLineConfig(filePath) {
|
|
|
837
834
|
function preCommit(program) {
|
|
838
835
|
program.command("pre-commit").description("Run the pre-commit scripts specified in the alex-c-line config (v2 experiment).").option("--allow-no-staged-changes", "Run even if nothing is staged").option("--no-update-index").option("--update-index", "Update the git index after the run").action(async (options) => {
|
|
839
836
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
840
|
-
if (!configPath)
|
|
841
|
-
exitCode: 1,
|
|
842
|
-
code: "ALEX_C_LINE_CONFIG_NOT_FOUND"
|
|
843
|
-
});
|
|
837
|
+
if (!configPath) throw new _alextheman_utility.DataError({ configPath }, "ALEX_C_LINE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line config file. Does it exist?");
|
|
844
838
|
const { preCommit: preCommitConfig } = await loadAlexCLineConfig(configPath);
|
|
845
|
-
if (!preCommitConfig)
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
});
|
|
839
|
+
if (!preCommitConfig) throw new _alextheman_utility.DataError({
|
|
840
|
+
configPath,
|
|
841
|
+
preCommitConfig
|
|
842
|
+
}, "PRE_COMMIT_CONFIG_NOT_FOUND", "Could not find the pre-commit config in alex-c-line config.");
|
|
849
843
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
850
844
|
const { exitCode: diffExitCode } = await (0, execa.execa)({ reject: false })`git diff --cached --quiet`;
|
|
851
845
|
switch (diffExitCode) {
|
|
852
|
-
case 128: program.error(
|
|
846
|
+
case 128: program.error(`${errorPrefix} Not currently in a Git repository`, {
|
|
853
847
|
exitCode: 1,
|
|
854
848
|
code: "GIT_DIFF_FAILED"
|
|
855
849
|
});
|
|
@@ -939,12 +933,7 @@ function templatePullRequestCreate(program) {
|
|
|
939
933
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
940
934
|
const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
|
|
941
935
|
const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
|
|
942
|
-
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo
|
|
943
|
-
program.error("Invalid package.json - expected package.json to contain a `name` property.", {
|
|
944
|
-
exitCode: 1,
|
|
945
|
-
code: "INVALID_PACKAGE_JSON"
|
|
946
|
-
});
|
|
947
|
-
});
|
|
936
|
+
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo);
|
|
948
937
|
if (!projectName) throw new _alextheman_utility.DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
|
|
949
938
|
const parsedOptions = parseTemplatePullRequestConfig((0, _alextheman_utility.removeUndefinedFromObject)({
|
|
950
939
|
category: commandLineOptions.category ?? config?.category ?? "general",
|
|
@@ -976,6 +965,15 @@ function templatePullRequest(program) {
|
|
|
976
965
|
//#region src/utility/constants/successPrefix.ts
|
|
977
966
|
const successPrefix = chalk.default.green("✓");
|
|
978
967
|
|
|
968
|
+
//#endregion
|
|
969
|
+
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
970
|
+
function convertDataErrorToProgramError(dataError, program, options) {
|
|
971
|
+
program.error(`${errorPrefix} ${dataError.message}`, {
|
|
972
|
+
exitCode: options?.exitCode ?? 1,
|
|
973
|
+
code: dataError.code
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
|
|
979
977
|
//#endregion
|
|
980
978
|
//#region src/utility/markdownTemplates/releaseNote/types/ReleaseStatus.ts
|
|
981
979
|
const ReleaseStatus = {
|
|
@@ -1082,10 +1080,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
1082
1080
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
1083
1081
|
console.info(`${successPrefix} Release document is valid!`);
|
|
1084
1082
|
} catch (error) {
|
|
1085
|
-
if (_alextheman_utility.DataError.check(error)) program
|
|
1086
|
-
exitCode: 1,
|
|
1087
|
-
code: error.code
|
|
1088
|
-
});
|
|
1083
|
+
if (_alextheman_utility.DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
1089
1084
|
else throw error;
|
|
1090
1085
|
}
|
|
1091
1086
|
});
|
|
@@ -1173,12 +1168,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1173
1168
|
const { name, version: packageVersion } = (0, _alextheman_utility.parseZodSchema)(zod.default.object({
|
|
1174
1169
|
name: zod.default.string(),
|
|
1175
1170
|
version: zod.default.string()
|
|
1176
|
-
}), packageInfo
|
|
1177
|
-
program.error("Invalid package.json - expected package.json to contain a `name` and `version` property.", {
|
|
1178
|
-
exitCode: 1,
|
|
1179
|
-
code: "INVALID_PACKAGE_JSON"
|
|
1180
|
-
});
|
|
1181
|
-
});
|
|
1171
|
+
}), packageInfo);
|
|
1182
1172
|
const versionNumber = target instanceof _alextheman_utility.VersionNumber ? target : target ? new _alextheman_utility.VersionNumber(packageVersion).increment(target) : new _alextheman_utility.VersionNumber(packageVersion);
|
|
1183
1173
|
const releaseNotePath = getReleaseNotePath(versionNumber);
|
|
1184
1174
|
const releaseNoteTemplate = await getReleaseNoteTemplateFromMarkdown(name, versionNumber, { status: "In progress" });
|
|
@@ -1186,7 +1176,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1186
1176
|
await (0, node_fs_promises.mkdir)(node_path.default.dirname(releaseNotePath), { recursive: true });
|
|
1187
1177
|
await (0, node_fs_promises.writeFile)(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1188
1178
|
} catch (error) {
|
|
1189
|
-
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(
|
|
1179
|
+
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${errorPrefix} Release notes already exist.`, {
|
|
1190
1180
|
exitCode: 1,
|
|
1191
1181
|
code: "RELEASE_NOTE_EXISTS"
|
|
1192
1182
|
});
|
|
@@ -1273,10 +1263,7 @@ function templateReleaseNoteSetStatus(program) {
|
|
|
1273
1263
|
program.command("set-status").description("Change the release status on a given release document initially generated from the `create-release-note` command.").argument("<documentPath>", "The path to the document").argument("[status]", "The status to set the document to", parseReleaseStatus, ReleaseStatus.RELEASED).action(async (documentPath, status) => {
|
|
1274
1264
|
const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
|
|
1275
1265
|
const { name } = (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo, new _alextheman_utility.DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
|
|
1276
|
-
if (!documentPath.endsWith("md"))
|
|
1277
|
-
exitCode: 1,
|
|
1278
|
-
code: "INVALID_FILE_PATH"
|
|
1279
|
-
});
|
|
1266
|
+
if (!documentPath.endsWith("md")) throw new _alextheman_utility.DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
|
|
1280
1267
|
const versionNumber = new _alextheman_utility.VersionNumber(node_path.default.basename(documentPath).split(".").filter((part) => {
|
|
1281
1268
|
return part !== "md";
|
|
1282
1269
|
}).join("."));
|
|
@@ -1321,7 +1308,7 @@ function template(program) {
|
|
|
1321
1308
|
//#endregion
|
|
1322
1309
|
//#region package.json
|
|
1323
1310
|
var name = "alex-c-line";
|
|
1324
|
-
var version$1 = "2.0.
|
|
1311
|
+
var version$1 = "2.0.1";
|
|
1325
1312
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1326
1313
|
|
|
1327
1314
|
//#endregion
|
|
@@ -1387,15 +1374,6 @@ function uuid(program) {
|
|
|
1387
1374
|
loadCommands(program.command("uuid").description("Commands to help manage UUIDs"), { generateUUID });
|
|
1388
1375
|
}
|
|
1389
1376
|
|
|
1390
|
-
//#endregion
|
|
1391
|
-
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
1392
|
-
function convertDataErrorToProgramError(dataError, program, options) {
|
|
1393
|
-
program.error(dataError.message, {
|
|
1394
|
-
exitCode: options?.exitCode ?? 1,
|
|
1395
|
-
code: dataError.code
|
|
1396
|
-
});
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
1377
|
//#endregion
|
|
1400
1378
|
//#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
|
|
1401
1379
|
function parseZodSchemaForProgram(program, schema, data) {
|
|
@@ -1487,7 +1465,7 @@ async function noFileDependencies(program) {
|
|
|
1487
1465
|
};
|
|
1488
1466
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1489
1467
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1490
|
-
if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix}
|
|
1468
|
+
if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
|
|
1491
1469
|
`, {
|
|
1492
1470
|
exitCode: 2,
|
|
1493
1471
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
@@ -1511,7 +1489,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1511
1489
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1512
1490
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1513
1491
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(_alextheman_utility.normaliseIndents`
|
|
1514
|
-
${errorPrefix}
|
|
1492
|
+
${errorPrefix} Pre-release version pinning is not allowed. Found the following violations:
|
|
1515
1493
|
|
|
1516
1494
|
` + JSON.stringify({
|
|
1517
1495
|
dependencies: preReleaseDependencies,
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ function cache(program) {
|
|
|
157
157
|
|
|
158
158
|
//#endregion
|
|
159
159
|
//#region src/utility/constants/errorPrefix.ts
|
|
160
|
-
const errorPrefix = "❌ ERROR";
|
|
160
|
+
const errorPrefix = "❌ ERROR:";
|
|
161
161
|
|
|
162
162
|
//#endregion
|
|
163
163
|
//#region src/utility/envFile/upsertDotenvFile.ts
|
|
@@ -170,14 +170,14 @@ async function upsertDotenvFile(contents, envFilePath) {
|
|
|
170
170
|
async function addVariable(program, envFileContents, file) {
|
|
171
171
|
const newVariableName = await input({ message: "Please enter the name of the environment variable you would like to add." });
|
|
172
172
|
if (newVariableName in envFileContents) program.error(`
|
|
173
|
-
${errorPrefix}
|
|
173
|
+
${errorPrefix} Error with chosen environment variable name ${newVariableName}.
|
|
174
174
|
Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
|
|
175
175
|
`, {
|
|
176
176
|
exitCode: 2,
|
|
177
177
|
code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
|
|
178
178
|
});
|
|
179
179
|
if (/[ \t\r\n]/.test(newVariableName)) program.error(normaliseIndents`
|
|
180
|
-
${errorPrefix}
|
|
180
|
+
${errorPrefix} Error with chosen environment variable name ${newVariableName}.
|
|
181
181
|
Environment variables are not allowed to have whitespace.
|
|
182
182
|
`, {
|
|
183
183
|
exitCode: 2,
|
|
@@ -320,7 +320,7 @@ function checkLockfileVersionDiscrepancy(program) {
|
|
|
320
320
|
const { version: packageVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package.json"), "utf-8"));
|
|
321
321
|
const { version: packageLockVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package-lock.json"), "utf-8"));
|
|
322
322
|
if (packageVersion !== packageLockVersion) {
|
|
323
|
-
console.error(
|
|
323
|
+
console.error(`${errorPrefix} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
|
|
324
324
|
process.exitCode = 1;
|
|
325
325
|
return;
|
|
326
326
|
}
|
|
@@ -334,7 +334,7 @@ function gitPostMergeCleanup(program) {
|
|
|
334
334
|
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 }) => {
|
|
335
335
|
console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
|
|
336
336
|
const { stdout: currentBranch } = await execa`git branch --show-current`;
|
|
337
|
-
if (currentBranch === branch) program.error(
|
|
337
|
+
if (currentBranch === branch) program.error(`${errorPrefix} Cannot run cleanup on ${branch} branch!`, {
|
|
338
338
|
exitCode: 1,
|
|
339
339
|
code: "INVALID_BRANCH"
|
|
340
340
|
});
|
|
@@ -350,7 +350,7 @@ function gitPostMergeCleanup(program) {
|
|
|
350
350
|
const { stdout: changes } = await execa`git diff ${branch}..${currentBranch}`;
|
|
351
351
|
if (changes) {
|
|
352
352
|
await execa`git checkout ${currentBranch}`;
|
|
353
|
-
program.error(
|
|
353
|
+
program.error(`${errorPrefix} Changes on branch not fully merged!`, {
|
|
354
354
|
exitCode: 1,
|
|
355
355
|
code: "CHANGES_NOT_MERGED"
|
|
356
356
|
});
|
|
@@ -360,7 +360,7 @@ function gitPostMergeCleanup(program) {
|
|
|
360
360
|
const { stdout: branchDeletedMessage, exitCode } = await execa({ reject: false })`git branch --delete ${currentBranch}`;
|
|
361
361
|
if (exitCode !== 0) {
|
|
362
362
|
await execa`git checkout ${currentBranch}`;
|
|
363
|
-
program.error(
|
|
363
|
+
program.error(`${errorPrefix} Changes on branch not fully merged!`, {
|
|
364
364
|
exitCode: 1,
|
|
365
365
|
code: "CHANGES_NOT_MERGED"
|
|
366
366
|
});
|
|
@@ -618,10 +618,7 @@ function localPackageUse(program) {
|
|
|
618
618
|
PrivateConfigFileName.ES_MODULES_JAVASCRIPT,
|
|
619
619
|
PrivateConfigFileName.STANDARD_JAVASCRIPT
|
|
620
620
|
]);
|
|
621
|
-
if (!configPath)
|
|
622
|
-
exitCode: 1,
|
|
623
|
-
code: "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND"
|
|
624
|
-
});
|
|
621
|
+
if (!configPath) throw new DataError({ configPath }, "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?");
|
|
625
622
|
const { localPackage: { enableCache, localPackages } } = await loadAlexCLinePrivateConfig(configPath);
|
|
626
623
|
const localPackage = localPackages[packageName];
|
|
627
624
|
if (!localPackage) throw new DataError({
|
|
@@ -658,8 +655,8 @@ function localPackageUse(program) {
|
|
|
658
655
|
stdio: "inherit",
|
|
659
656
|
reject: false
|
|
660
657
|
});
|
|
661
|
-
if (exitCode !== 0
|
|
662
|
-
exitCode
|
|
658
|
+
if (exitCode !== 0) program.error(`${errorPrefix} An error occurred during the local \`alex-c-line\` run.`, {
|
|
659
|
+
exitCode,
|
|
663
660
|
code: "LOCAL_ALEX_C_LINE_ERROR"
|
|
664
661
|
});
|
|
665
662
|
} else {
|
|
@@ -729,7 +726,7 @@ function encryptWithKey$1(program) {
|
|
|
729
726
|
try {
|
|
730
727
|
console.info(await encryptWithKey(publicKey, plaintextValue));
|
|
731
728
|
} catch {
|
|
732
|
-
program.error(
|
|
729
|
+
program.error(`${errorPrefix} Encryption failed. Please double-check that the given key is a valid base 64 string.`, {
|
|
733
730
|
exitCode: 1,
|
|
734
731
|
code: "ENCRYPTION_FAILED"
|
|
735
732
|
});
|
|
@@ -776,7 +773,7 @@ function createStepRunner(program) {
|
|
|
776
773
|
//#endregion
|
|
777
774
|
//#region src/cli/commands/root/pre-commit/getCommandArguments.ts
|
|
778
775
|
function getCommandArguments(program, script, scripts, args) {
|
|
779
|
-
if (!(script in (scripts ?? {}))) program.error(
|
|
776
|
+
if (!(script in (scripts ?? {}))) program.error(`${errorPrefix} Could not find script \`${script}\` in package.json.`, {
|
|
780
777
|
exitCode: 1,
|
|
781
778
|
code: "SCRIPT_NOT_FOUND"
|
|
782
779
|
});
|
|
@@ -802,19 +799,16 @@ async function loadAlexCLineConfig(filePath) {
|
|
|
802
799
|
function preCommit(program) {
|
|
803
800
|
program.command("pre-commit").description("Run the pre-commit scripts specified in the alex-c-line config (v2 experiment).").option("--allow-no-staged-changes", "Run even if nothing is staged").option("--no-update-index").option("--update-index", "Update the git index after the run").action(async (options) => {
|
|
804
801
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
805
|
-
if (!configPath)
|
|
806
|
-
exitCode: 1,
|
|
807
|
-
code: "ALEX_C_LINE_CONFIG_NOT_FOUND"
|
|
808
|
-
});
|
|
802
|
+
if (!configPath) throw new DataError({ configPath }, "ALEX_C_LINE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line config file. Does it exist?");
|
|
809
803
|
const { preCommit: preCommitConfig } = await loadAlexCLineConfig(configPath);
|
|
810
|
-
if (!preCommitConfig)
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
});
|
|
804
|
+
if (!preCommitConfig) throw new DataError({
|
|
805
|
+
configPath,
|
|
806
|
+
preCommitConfig
|
|
807
|
+
}, "PRE_COMMIT_CONFIG_NOT_FOUND", "Could not find the pre-commit config in alex-c-line config.");
|
|
814
808
|
const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
|
|
815
809
|
const { exitCode: diffExitCode } = await execa({ reject: false })`git diff --cached --quiet`;
|
|
816
810
|
switch (diffExitCode) {
|
|
817
|
-
case 128: program.error(
|
|
811
|
+
case 128: program.error(`${errorPrefix} Not currently in a Git repository`, {
|
|
818
812
|
exitCode: 1,
|
|
819
813
|
code: "GIT_DIFF_FAILED"
|
|
820
814
|
});
|
|
@@ -904,12 +898,7 @@ function templatePullRequestCreate(program) {
|
|
|
904
898
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
905
899
|
const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
|
|
906
900
|
const packageInfo = await getPackageJsonContents(process.cwd());
|
|
907
|
-
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : parseZodSchema(z.object({ name: z.string() }), packageInfo
|
|
908
|
-
program.error("Invalid package.json - expected package.json to contain a `name` property.", {
|
|
909
|
-
exitCode: 1,
|
|
910
|
-
code: "INVALID_PACKAGE_JSON"
|
|
911
|
-
});
|
|
912
|
-
});
|
|
901
|
+
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : parseZodSchema(z.object({ name: z.string() }), packageInfo);
|
|
913
902
|
if (!projectName) throw new DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
|
|
914
903
|
const parsedOptions = parseTemplatePullRequestConfig(removeUndefinedFromObject({
|
|
915
904
|
category: commandLineOptions.category ?? config?.category ?? "general",
|
|
@@ -941,6 +930,15 @@ function templatePullRequest(program) {
|
|
|
941
930
|
//#region src/utility/constants/successPrefix.ts
|
|
942
931
|
const successPrefix = chalk.green("✓");
|
|
943
932
|
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
935
|
+
function convertDataErrorToProgramError(dataError, program, options) {
|
|
936
|
+
program.error(`${errorPrefix} ${dataError.message}`, {
|
|
937
|
+
exitCode: options?.exitCode ?? 1,
|
|
938
|
+
code: dataError.code
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
|
|
944
942
|
//#endregion
|
|
945
943
|
//#region src/utility/markdownTemplates/releaseNote/types/ReleaseStatus.ts
|
|
946
944
|
const ReleaseStatus = {
|
|
@@ -1047,10 +1045,7 @@ function templateReleaseNoteCheck(program) {
|
|
|
1047
1045
|
await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
|
|
1048
1046
|
console.info(`${successPrefix} Release document is valid!`);
|
|
1049
1047
|
} catch (error) {
|
|
1050
|
-
if (DataError.check(error)) program
|
|
1051
|
-
exitCode: 1,
|
|
1052
|
-
code: error.code
|
|
1053
|
-
});
|
|
1048
|
+
if (DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
|
|
1054
1049
|
else throw error;
|
|
1055
1050
|
}
|
|
1056
1051
|
});
|
|
@@ -1138,12 +1133,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1138
1133
|
const { name, version: packageVersion } = parseZodSchema(z.object({
|
|
1139
1134
|
name: z.string(),
|
|
1140
1135
|
version: z.string()
|
|
1141
|
-
}), packageInfo
|
|
1142
|
-
program.error("Invalid package.json - expected package.json to contain a `name` and `version` property.", {
|
|
1143
|
-
exitCode: 1,
|
|
1144
|
-
code: "INVALID_PACKAGE_JSON"
|
|
1145
|
-
});
|
|
1146
|
-
});
|
|
1136
|
+
}), packageInfo);
|
|
1147
1137
|
const versionNumber = target instanceof VersionNumber ? target : target ? new VersionNumber(packageVersion).increment(target) : new VersionNumber(packageVersion);
|
|
1148
1138
|
const releaseNotePath = getReleaseNotePath(versionNumber);
|
|
1149
1139
|
const releaseNoteTemplate = await getReleaseNoteTemplateFromMarkdown(name, versionNumber, { status: "In progress" });
|
|
@@ -1151,7 +1141,7 @@ function templateReleaseNoteCreate(program) {
|
|
|
1151
1141
|
await mkdir(path.dirname(releaseNotePath), { recursive: true });
|
|
1152
1142
|
await writeFile(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
|
|
1153
1143
|
} catch (error) {
|
|
1154
|
-
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(
|
|
1144
|
+
if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${errorPrefix} Release notes already exist.`, {
|
|
1155
1145
|
exitCode: 1,
|
|
1156
1146
|
code: "RELEASE_NOTE_EXISTS"
|
|
1157
1147
|
});
|
|
@@ -1238,10 +1228,7 @@ function templateReleaseNoteSetStatus(program) {
|
|
|
1238
1228
|
program.command("set-status").description("Change the release status on a given release document initially generated from the `create-release-note` command.").argument("<documentPath>", "The path to the document").argument("[status]", "The status to set the document to", parseReleaseStatus, ReleaseStatus.RELEASED).action(async (documentPath, status) => {
|
|
1239
1229
|
const packageInfo = await getPackageJsonContents(process.cwd());
|
|
1240
1230
|
const { name } = parseZodSchema(z.object({ name: z.string() }), packageInfo, new DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
|
|
1241
|
-
if (!documentPath.endsWith("md"))
|
|
1242
|
-
exitCode: 1,
|
|
1243
|
-
code: "INVALID_FILE_PATH"
|
|
1244
|
-
});
|
|
1231
|
+
if (!documentPath.endsWith("md")) throw new DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
|
|
1245
1232
|
const versionNumber = new VersionNumber(path.basename(documentPath).split(".").filter((part) => {
|
|
1246
1233
|
return part !== "md";
|
|
1247
1234
|
}).join("."));
|
|
@@ -1286,7 +1273,7 @@ function template(program) {
|
|
|
1286
1273
|
//#endregion
|
|
1287
1274
|
//#region package.json
|
|
1288
1275
|
var name = "alex-c-line";
|
|
1289
|
-
var version$1 = "2.0.
|
|
1276
|
+
var version$1 = "2.0.1";
|
|
1290
1277
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1291
1278
|
|
|
1292
1279
|
//#endregion
|
|
@@ -1352,15 +1339,6 @@ function uuid(program) {
|
|
|
1352
1339
|
loadCommands(program.command("uuid").description("Commands to help manage UUIDs"), { generateUUID });
|
|
1353
1340
|
}
|
|
1354
1341
|
|
|
1355
|
-
//#endregion
|
|
1356
|
-
//#region src/utility/errors/convertDataErrorToProgramError.ts
|
|
1357
|
-
function convertDataErrorToProgramError(dataError, program, options) {
|
|
1358
|
-
program.error(dataError.message, {
|
|
1359
|
-
exitCode: options?.exitCode ?? 1,
|
|
1360
|
-
code: dataError.code
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
1342
|
//#endregion
|
|
1365
1343
|
//#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
|
|
1366
1344
|
function parseZodSchemaForProgram(program, schema, data) {
|
|
@@ -1452,7 +1430,7 @@ async function noFileDependencies(program) {
|
|
|
1452
1430
|
};
|
|
1453
1431
|
if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
|
|
1454
1432
|
if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
|
|
1455
|
-
if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix}
|
|
1433
|
+
if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
|
|
1456
1434
|
`, {
|
|
1457
1435
|
exitCode: 2,
|
|
1458
1436
|
code: "FILE_DEPENDENCIES_FOUND"
|
|
@@ -1476,7 +1454,7 @@ async function noPreReleaseDependencies(program) {
|
|
|
1476
1454
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
|
|
1477
1455
|
for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
|
|
1478
1456
|
if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(normaliseIndents`
|
|
1479
|
-
${errorPrefix}
|
|
1457
|
+
${errorPrefix} Pre-release version pinning is not allowed. Found the following violations:
|
|
1480
1458
|
|
|
1481
1459
|
` + JSON.stringify({
|
|
1482
1460
|
dependencies: preReleaseDependencies,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alex-c-line",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Command-line tool with commands to streamline the developer workflow.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"zod": "^4.3.6"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@alextheman/eslint-plugin": "^5.
|
|
55
|
+
"@alextheman/eslint-plugin": "^5.10.0",
|
|
56
56
|
"@commander-js/extra-typings": "^14.0.0",
|
|
57
57
|
"@types/eslint": "^9.6.1",
|
|
58
58
|
"@types/node": "^25.3.2",
|