pm-auto 1.0.6 → 1.0.7
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/config.json +45 -0
- package/dist/build_command.d.ts +6 -1
- package/dist/build_command.d.ts.map +1 -1
- package/dist/build_command.js +61 -22
- package/dist/build_command.js.map +1 -1
- package/dist/config_path.d.ts +1 -0
- package/dist/config_path.d.ts.map +1 -1
- package/dist/config_path.js +60 -2
- package/dist/config_path.js.map +1 -1
- package/dist/config_reader.d.ts +2 -12
- package/dist/config_reader.d.ts.map +1 -1
- package/dist/config_reader.js +72 -89
- package/dist/config_reader.js.map +1 -1
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +1 -0
- package/dist/display.js.map +1 -1
- package/dist/index.js +5 -6
- package/dist/index.js.map +1 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +18 -28
- package/dist/orchestrator.js.map +1 -1
- package/dist/run_commands.d.ts +6 -0
- package/dist/run_commands.d.ts.map +1 -0
- package/dist/{install.js → run_commands.js} +4 -4
- package/dist/run_commands.js.map +1 -0
- package/dist/types/index.d.ts +8 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/build_command.ts +73 -23
- package/src/config_path.ts +63 -2
- package/src/config_reader.ts +86 -107
- package/src/display.ts +1 -0
- package/src/index.ts +6 -9
- package/src/orchestrator.ts +21 -36
- package/src/{install.ts → run_commands.ts} +3 -3
- package/src/types/index.ts +12 -3
- package/tests/build_command.test.ts +239 -41
- package/tests/config_reader.test.ts +51 -92
- package/tests/{install.test.ts → run_command.test.ts} +23 -23
- package/dist/install.d.ts +0 -6
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js.map +0 -1
- package/test.json +0 -87
package/src/config_reader.ts
CHANGED
|
@@ -1,132 +1,111 @@
|
|
|
1
1
|
import fs from "fs/promises";
|
|
2
2
|
import { getConfigPath } from "./config_path.js";
|
|
3
|
-
|
|
4
|
-
import * as fsd from "fs";
|
|
5
|
-
import * as path from "path";
|
|
6
3
|
import type { CommandResult, ConfigType } from "./types/index.js";
|
|
7
4
|
import { display } from "./display.js";
|
|
8
5
|
import { confirm, isCancel, cancel } from "@clack/prompts";
|
|
9
6
|
|
|
10
|
-
type PackageManager = "npm" | "yarn" | "pnpm";
|
|
11
|
-
|
|
12
7
|
/**
|
|
13
|
-
*
|
|
8
|
+
* Gets the required packages from the config file, transforms into a js object and with the options given
|
|
9
|
+
* it modifies the object and returns it
|
|
14
10
|
*/
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (fsd.existsSync(path.join(projectPath, "package-lock.json"))) {
|
|
29
|
-
return "npm";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Default to npm if no lock file found
|
|
33
|
-
display("No Lock File Found", "error");
|
|
12
|
+
//Check if the value is an array of ConfigType objects
|
|
13
|
+
function isConfigTypeArray(value: unknown): value is ConfigType[] {
|
|
14
|
+
return (
|
|
15
|
+
Array.isArray(value) &&
|
|
16
|
+
value.every(
|
|
17
|
+
(item) =>
|
|
18
|
+
typeof item === "object" &&
|
|
19
|
+
item !== null &&
|
|
20
|
+
"packages" in item &&
|
|
21
|
+
Array.isArray((item as any).packages),
|
|
22
|
+
)
|
|
23
|
+
);
|
|
34
24
|
}
|
|
35
25
|
|
|
36
|
-
/**
|
|
37
|
-
* Gets the required packages from the config file, transforms into a js object and with the options given
|
|
38
|
-
* it modifies the object and returns it
|
|
39
|
-
*/
|
|
40
26
|
export const getConfigObject = async (
|
|
41
27
|
packages: string[],
|
|
42
28
|
options?: any,
|
|
43
|
-
): Promise<ConfigType[]
|
|
44
|
-
|
|
45
|
-
const configPath = getConfigPath();
|
|
46
|
-
|
|
47
|
-
//read config file content
|
|
48
|
-
let configContent = "";
|
|
49
|
-
try {
|
|
50
|
-
configContent = await fs.readFile(configPath as string, "utf8");
|
|
51
|
-
} catch (error) {
|
|
52
|
-
display(
|
|
53
|
-
`File not found ${error} Try updating the config file path`,
|
|
54
|
-
"error",
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const configObject = JSON.parse(configContent);
|
|
59
|
-
let result: ConfigType[] = Object.values(configObject);
|
|
60
|
-
|
|
61
|
-
//filter the packages the user wants to install
|
|
62
|
-
if (packages.length > 0) {
|
|
63
|
-
result = packages
|
|
64
|
-
.map((pkgName) => {
|
|
65
|
-
const found = result.find((pkg) => pkg.name === pkgName);
|
|
66
|
-
if (!found) {
|
|
67
|
-
display(`Package '${pkgName}' not found in config`, "warning");
|
|
68
|
-
}
|
|
69
|
-
return found;
|
|
70
|
-
})
|
|
71
|
-
.filter((pkg) => pkg !== undefined);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/*
|
|
75
|
-
* Config object modification with the options given
|
|
76
|
-
*/
|
|
77
|
-
//Add command to previous configured commands (-A/-add-command)
|
|
78
|
-
if (options.addCommand) {
|
|
79
|
-
result.forEach((config) => {
|
|
80
|
-
config.packages.forEach((pkg) => {
|
|
81
|
-
pkg.command = pkg.interactive
|
|
82
|
-
? pkg.command
|
|
83
|
-
: pkg.command + " " + options.addCommand;
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
}
|
|
29
|
+
): Promise<ConfigType[]> => {
|
|
30
|
+
const configPath = getConfigPath();
|
|
87
31
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
message: "Continue?",
|
|
99
|
-
initialValue: true,
|
|
100
|
-
});
|
|
32
|
+
//read config file content
|
|
33
|
+
let configContent = "";
|
|
34
|
+
try {
|
|
35
|
+
configContent = await fs.readFile(configPath as string, "utf8");
|
|
36
|
+
} catch (error) {
|
|
37
|
+
display(
|
|
38
|
+
`File not found ${error} Try updating the config file path`,
|
|
39
|
+
"error",
|
|
40
|
+
);
|
|
41
|
+
}
|
|
101
42
|
|
|
102
|
-
|
|
103
|
-
cancel("Operation cancelled.");
|
|
104
|
-
process.exit(0);
|
|
105
|
-
}
|
|
43
|
+
const configObject = JSON.parse(configContent);
|
|
106
44
|
|
|
107
|
-
|
|
108
|
-
display("Operation cancelled. ", "success");
|
|
109
|
-
process.exit(0);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
45
|
+
let result: ConfigType[] = [];
|
|
112
46
|
|
|
113
|
-
|
|
47
|
+
if (isConfigTypeArray(Object.values(configObject))) {
|
|
48
|
+
result = Object.values(configObject);
|
|
114
49
|
} else {
|
|
115
|
-
|
|
116
|
-
|
|
50
|
+
display("Invalid config file format", "error");
|
|
51
|
+
}
|
|
117
52
|
|
|
118
|
-
|
|
53
|
+
//filter the packages the user wants to install
|
|
54
|
+
if (packages.length > 0 && result.length > 0) {
|
|
55
|
+
result = packages
|
|
56
|
+
.map((pkgName) => {
|
|
57
|
+
const found = result.find((pkg) => pkg.presetName === pkgName);
|
|
58
|
+
if (!found) {
|
|
59
|
+
display(`Package '${pkgName}' not found in config`, "warning");
|
|
60
|
+
}
|
|
61
|
+
return found;
|
|
62
|
+
})
|
|
63
|
+
.filter((pkg) => pkg !== undefined);
|
|
64
|
+
}
|
|
119
65
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
66
|
+
/*
|
|
67
|
+
* Config object modification with the options given
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
//Add flags to previous configured flags (-A/-add-flags)
|
|
71
|
+
if (options.addFlags) {
|
|
72
|
+
result.forEach((config) => {
|
|
73
|
+
config.packages.forEach((pkg) => {
|
|
74
|
+
if (pkg.flags) {
|
|
75
|
+
pkg.flags.push(pkg.interactive ? "" : options.addFlags);
|
|
76
|
+
} else {
|
|
77
|
+
pkg.flags = [pkg.interactive ? "" : options.addFlags];
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
127
82
|
|
|
128
|
-
|
|
83
|
+
//Dry run - Display commands before execution
|
|
84
|
+
if (options.dryRun) {
|
|
85
|
+
display("Dry Run:", "info");
|
|
86
|
+
result.forEach((config) => {
|
|
87
|
+
display(`Package name -> ${config.presetName}`, "info");
|
|
88
|
+
config.packages.forEach((pkg) => {
|
|
89
|
+
display(`running ${pkg.command}`, "info");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
const continuation = await confirm({
|
|
93
|
+
message: "Continue?",
|
|
94
|
+
initialValue: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (isCancel(continuation)) {
|
|
98
|
+
cancel("Operation cancelled.");
|
|
99
|
+
process.exit(0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!continuation) {
|
|
103
|
+
display("Operation cancelled. ", "success");
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
129
106
|
}
|
|
107
|
+
|
|
108
|
+
return result;
|
|
130
109
|
};
|
|
131
110
|
|
|
132
111
|
export const getConfigKeys = async (options: any) => {
|
|
@@ -176,7 +155,7 @@ export const getPackageDescription = async (packageName: string) => {
|
|
|
176
155
|
const configObjectArray: ConfigType[] = Object.values(configObject);
|
|
177
156
|
|
|
178
157
|
configObjectArray.forEach((configObject) => {
|
|
179
|
-
if (configObject.
|
|
158
|
+
if (configObject.presetName === packageName) {
|
|
180
159
|
const description = !configObject.description
|
|
181
160
|
? "No description"
|
|
182
161
|
: configObject.description;
|
package/src/display.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -14,10 +14,8 @@ const program = new Command();
|
|
|
14
14
|
|
|
15
15
|
program
|
|
16
16
|
.name("pm-auto")
|
|
17
|
-
.version("1.0.
|
|
18
|
-
.description(
|
|
19
|
-
"A CLI tool to define and install your tech stack presets with one command.",
|
|
20
|
-
);
|
|
17
|
+
.version("1.0.7")
|
|
18
|
+
.description("Automate your project setup with one command");
|
|
21
19
|
|
|
22
20
|
program
|
|
23
21
|
.command("config <path>")
|
|
@@ -33,10 +31,9 @@ program
|
|
|
33
31
|
.description(
|
|
34
32
|
"Install packages using the detected package manager (Aliases: add, i)",
|
|
35
33
|
)
|
|
36
|
-
.option("-p, --pkg-json", "Install packages from package.json")
|
|
37
34
|
.option(
|
|
38
|
-
"-A, --add-
|
|
39
|
-
"Add
|
|
35
|
+
"-A, --add-flags <flags>",
|
|
36
|
+
"Add custom flags to already defined flags from config file",
|
|
40
37
|
)
|
|
41
38
|
.option("-D, --dry-run", "Dry run - Display commands before execution")
|
|
42
39
|
.action((packages, options) => {
|
|
@@ -62,12 +59,12 @@ program
|
|
|
62
59
|
.command("list")
|
|
63
60
|
.alias("ls")
|
|
64
61
|
.description("List all packages from the config file")
|
|
65
|
-
.option("
|
|
62
|
+
.option("--desc", "Display packages description", false)
|
|
66
63
|
.action((options) => {
|
|
67
64
|
getConfigKeys(options);
|
|
68
65
|
});
|
|
69
66
|
|
|
70
|
-
//
|
|
67
|
+
//Display a config description
|
|
71
68
|
program
|
|
72
69
|
.command("describe <package>")
|
|
73
70
|
.alias("desc")
|
package/src/orchestrator.ts
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
buildInstallCommands,
|
|
3
|
+
buildUninstallCommands,
|
|
4
|
+
} from "./build_command.js";
|
|
2
5
|
import { getConfigObject } from "./config_reader.js";
|
|
3
6
|
import { display } from "./display.js";
|
|
4
|
-
import {
|
|
7
|
+
import { runCommands } from "./run_commands.js";
|
|
5
8
|
import type { ConfigType } from "./types/index.js";
|
|
6
9
|
import { outro } from "@clack/prompts";
|
|
7
10
|
|
|
8
|
-
//
|
|
9
|
-
function isConfigTypeArray(value: unknown): value is ConfigType[] {
|
|
10
|
-
return (
|
|
11
|
-
Array.isArray(value) &&
|
|
12
|
-
value.every(
|
|
13
|
-
(item) =>
|
|
14
|
-
typeof item === "object" &&
|
|
15
|
-
item !== null &&
|
|
16
|
-
"packages" in item &&
|
|
17
|
-
Array.isArray((item as any).packages),
|
|
18
|
-
)
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
11
|
+
//Controls installation and uninstallation of packages
|
|
22
12
|
export const orchestrator = (
|
|
23
13
|
command: string,
|
|
24
14
|
packages: string[],
|
|
@@ -26,28 +16,23 @@ export const orchestrator = (
|
|
|
26
16
|
) => {
|
|
27
17
|
if (command === "install") {
|
|
28
18
|
display(
|
|
29
|
-
`Installing packages... ${
|
|
19
|
+
`Installing packages... ${(packages as string[]).join(", ")}`,
|
|
30
20
|
"info",
|
|
31
21
|
);
|
|
32
|
-
|
|
22
|
+
const start = performance.now();
|
|
33
23
|
getConfigObject(packages, options).then(async (config) => {
|
|
34
24
|
if (config.length === 0) {
|
|
35
25
|
display("No configuration found", "error");
|
|
36
26
|
return;
|
|
37
27
|
}
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
const commands = buildCommands(config);
|
|
41
|
-
|
|
42
|
-
await install(commands);
|
|
43
|
-
outro("Done!");
|
|
29
|
+
const commands = buildInstallCommands(config);
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
31
|
+
await runCommands(commands);
|
|
32
|
+
outro("Done!");
|
|
33
|
+
const end = performance.now();
|
|
34
|
+
display(`Installation took ${Math.round((end - start) / 1000)}s`, "info");
|
|
35
|
+
display("Packages installed successfully", "success");
|
|
51
36
|
});
|
|
52
37
|
} else {
|
|
53
38
|
display(
|
|
@@ -55,19 +40,19 @@ export const orchestrator = (
|
|
|
55
40
|
"info",
|
|
56
41
|
);
|
|
57
42
|
|
|
43
|
+
const start = performance.now();
|
|
58
44
|
getConfigObject(packages, options).then(async (config) => {
|
|
59
45
|
if (config.length === 0) {
|
|
60
46
|
display("No configuration found", "error");
|
|
61
47
|
return;
|
|
62
48
|
}
|
|
63
49
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
50
|
+
const commands = buildUninstallCommands(config);
|
|
51
|
+
await runCommands(commands);
|
|
52
|
+
outro("Done!");
|
|
53
|
+
const end = performance.now();
|
|
54
|
+
display(`Uninstallation took ${end - start}ms`, "info");
|
|
55
|
+
display("Packages uninstalled successfully", "success");
|
|
71
56
|
});
|
|
72
57
|
}
|
|
73
58
|
};
|
|
@@ -26,13 +26,13 @@ async function runCommand(command: string, interactive: boolean = false) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Run all commands
|
|
30
30
|
*/
|
|
31
|
-
export async function
|
|
31
|
+
export async function runCommands(commands: CommandResult[]) {
|
|
32
32
|
try {
|
|
33
33
|
for (const command of commands) {
|
|
34
34
|
// Wait for all interactive commands to finish first
|
|
35
|
-
if (command.interactive) {
|
|
35
|
+
if (command.interactive.length > 0) {
|
|
36
36
|
for (const interactiveCommand of command.interactive) {
|
|
37
37
|
display(`Running interactive command: ${interactiveCommand}`, "info");
|
|
38
38
|
await runCommand(interactiveCommand, true);
|
package/src/types/index.ts
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
export interface ConfigType {
|
|
2
|
-
|
|
2
|
+
presetName: string;
|
|
3
3
|
description?: string;
|
|
4
4
|
packageManager: string;
|
|
5
|
-
packages: {
|
|
5
|
+
packages: {
|
|
6
|
+
command: string;
|
|
7
|
+
interactive: boolean;
|
|
8
|
+
dev?: boolean;
|
|
9
|
+
flags?: string[];
|
|
10
|
+
version?: string;
|
|
11
|
+
}[];
|
|
6
12
|
}
|
|
7
13
|
|
|
8
14
|
export interface PackageType {
|
|
9
15
|
command: string;
|
|
10
16
|
interactive: boolean;
|
|
17
|
+
dev?: boolean;
|
|
18
|
+
flags?: string[];
|
|
19
|
+
version?: string;
|
|
11
20
|
}
|
|
12
21
|
|
|
13
22
|
export interface CommandResult {
|
|
14
|
-
|
|
23
|
+
presetName: string;
|
|
15
24
|
interactive: string[];
|
|
16
25
|
nonInteractive: string[];
|
|
17
26
|
}
|