pm-auto 1.0.0 → 1.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 +257 -141
- package/dist/config_reader.d.ts.map +1 -1
- package/dist/config_reader.js +7 -3
- package/dist/config_reader.js.map +1 -1
- package/dist/display.d.ts +4 -7
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +18 -6
- package/dist/display.js.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +26 -8
- package/dist/install.js.map +1 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +8 -4
- package/dist/orchestrator.js.map +1 -1
- package/nodemon.json +6 -6
- package/package.json +8 -7
- package/src/build_command.ts +119 -119
- package/src/config_path.ts +54 -54
- package/src/config_reader.ts +11 -3
- package/src/display.ts +23 -19
- package/src/index.ts +20 -5
- package/src/install.ts +20 -8
- package/src/orchestrator.ts +8 -7
- package/src/types/index.ts +16 -16
- package/test.json +94 -83
package/src/config_reader.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as fsd from "fs";
|
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import type { CommandResult, ConfigType } from "./types/index.js";
|
|
7
7
|
import { display } from "./display.js";
|
|
8
|
-
import { confirm } from "@
|
|
8
|
+
import { confirm, isCancel, cancel } from "@clack/prompts";
|
|
9
9
|
|
|
10
10
|
type PackageManager = "npm" | "yarn" | "pnpm";
|
|
11
11
|
|
|
@@ -49,7 +49,10 @@ export const getConfigObject = async (
|
|
|
49
49
|
try {
|
|
50
50
|
configContent = await fs.readFile(configPath as string, "utf8");
|
|
51
51
|
} catch (error) {
|
|
52
|
-
display(
|
|
52
|
+
display(
|
|
53
|
+
`File not found ${error} Try updating the config file path`,
|
|
54
|
+
"error",
|
|
55
|
+
);
|
|
53
56
|
}
|
|
54
57
|
const configObject = JSON.parse(configContent);
|
|
55
58
|
let result: ConfigType[] = Object.values(configObject);
|
|
@@ -91,9 +94,14 @@ export const getConfigObject = async (
|
|
|
91
94
|
});
|
|
92
95
|
const continueWithInstall = await confirm({
|
|
93
96
|
message: "Continue with installation?",
|
|
94
|
-
|
|
97
|
+
initialValue: true,
|
|
95
98
|
});
|
|
96
99
|
|
|
100
|
+
if (isCancel(continueWithInstall)) {
|
|
101
|
+
cancel("Operation cancelled.");
|
|
102
|
+
process.exit(0);
|
|
103
|
+
}
|
|
104
|
+
|
|
97
105
|
if (!continueWithInstall) {
|
|
98
106
|
display("Installation cancelled ", "success");
|
|
99
107
|
}
|
package/src/display.ts
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
* Display a message with a specified type.
|
|
3
|
-
*
|
|
4
|
-
* @param text - The message to display.
|
|
5
|
-
* @param type - The type of message to display to determine the color.
|
|
6
|
-
*/
|
|
7
|
-
|
|
1
|
+
import { log, spinner } from "@clack/prompts";
|
|
8
2
|
import chalk from "chalk";
|
|
9
3
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
)
|
|
4
|
+
type DisplayType = "error" | "success" | "warning" | "info" | "loading" | "";
|
|
5
|
+
|
|
6
|
+
export const stopSpinner = (s: any, text: string, code: number = 0) => {
|
|
7
|
+
if (!s || typeof s.stop !== "function") return;
|
|
8
|
+
s.stop(code === 0 ? chalk.green(text) : chalk.red(text));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const display = (text: string, type: DisplayType) => {
|
|
14
12
|
switch (type) {
|
|
15
13
|
case "error":
|
|
16
|
-
|
|
14
|
+
log.error(chalk.red(text));
|
|
17
15
|
process.exit(1);
|
|
16
|
+
|
|
18
17
|
case "success":
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
log.success(chalk.green(text)); // Use log.success instead
|
|
19
|
+
break;
|
|
20
|
+
|
|
21
21
|
case "warning":
|
|
22
|
-
|
|
22
|
+
log.warn(chalk.yellow(text));
|
|
23
23
|
break;
|
|
24
|
+
|
|
24
25
|
case "info":
|
|
25
|
-
|
|
26
|
+
log.info(chalk.blue(text));
|
|
26
27
|
break;
|
|
28
|
+
|
|
27
29
|
case "loading":
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
const s = spinner();
|
|
31
|
+
s.start(text);
|
|
32
|
+
return s; // Return spinner so it can be stopped later
|
|
33
|
+
|
|
30
34
|
default:
|
|
31
|
-
|
|
35
|
+
log.message(text);
|
|
32
36
|
}
|
|
33
37
|
};
|
package/src/index.ts
CHANGED
|
@@ -2,25 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { saveConfigPath } from "./config_path.js";
|
|
5
|
+
import { intro } from "@clack/prompts";
|
|
5
6
|
import { orchestrator } from "./orchestrator.js";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
|
|
9
|
+
intro(chalk.inverse(" pm-auto "));
|
|
6
10
|
|
|
7
11
|
const program = new Command();
|
|
8
12
|
|
|
9
13
|
program
|
|
10
14
|
.name("pm-auto")
|
|
11
|
-
.version("1.0.
|
|
12
|
-
.description(
|
|
15
|
+
.version("1.0.1")
|
|
16
|
+
.description(
|
|
17
|
+
"A CLI tool to define and install your tech stack presets with one command.",
|
|
18
|
+
);
|
|
13
19
|
|
|
14
20
|
program
|
|
15
21
|
.command("config <path>")
|
|
16
|
-
.description("Set the
|
|
22
|
+
.description("Set the path to the configuration file")
|
|
17
23
|
.action((path) => {
|
|
18
24
|
saveConfigPath(path);
|
|
19
25
|
});
|
|
20
26
|
|
|
21
27
|
program
|
|
22
28
|
.command("install [packages...]")
|
|
23
|
-
.
|
|
29
|
+
.alias("add")
|
|
30
|
+
.alias("i")
|
|
31
|
+
.description(
|
|
32
|
+
"Install packages using the detected package manager (Aliases: add, i)",
|
|
33
|
+
)
|
|
24
34
|
.option("-p, --pkg-json", "Install packages from package.json")
|
|
25
35
|
.option(
|
|
26
36
|
"-A, --add-command <command>",
|
|
@@ -33,7 +43,12 @@ program
|
|
|
33
43
|
|
|
34
44
|
program
|
|
35
45
|
.command("uninstall <packages...>")
|
|
36
|
-
.
|
|
46
|
+
.alias("remove")
|
|
47
|
+
.alias("u")
|
|
48
|
+
.alias("un")
|
|
49
|
+
.description(
|
|
50
|
+
"Remove packages using the detected package manager (Aliases: remove, u, un)",
|
|
51
|
+
)
|
|
37
52
|
.option(
|
|
38
53
|
"-A, --add-command <command>",
|
|
39
54
|
"Add a custom command to all installation commands from config file",
|
package/src/install.ts
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import { execa } from "execa";
|
|
2
2
|
import type { CommandResult } from "./types/index.js";
|
|
3
|
-
import { display } from "./display.js";
|
|
3
|
+
import { display, stopSpinner } from "./display.js";
|
|
4
4
|
|
|
5
|
-
async function runCommand(command: string) {
|
|
5
|
+
async function runCommand(command: string, interactive: boolean = false) {
|
|
6
6
|
try {
|
|
7
7
|
const [commandName, ...args] = command.split(" ");
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
if (interactive) {
|
|
10
|
+
// Stop spinner before interactive command
|
|
11
|
+
stopSpinner("Starting interactive command...", 0);
|
|
12
|
+
await execa(commandName as string, args, {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
await execa(commandName as string, args, {
|
|
17
|
+
stdio: "inherit",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
12
20
|
} catch (error: any) {
|
|
21
|
+
// If pipe failed, we should show the output
|
|
22
|
+
if (error.stdout) display(error.stdout, "");
|
|
23
|
+
if (error.stderr) display(error.stderr, "error");
|
|
13
24
|
display(`Error:, ${error.message}`, "error");
|
|
14
25
|
}
|
|
15
26
|
}
|
|
@@ -23,15 +34,16 @@ export async function install(commands: CommandResult[]) {
|
|
|
23
34
|
// Wait for all interactive commands to finish first
|
|
24
35
|
if (command.interactive) {
|
|
25
36
|
for (const interactiveCommand of command.interactive) {
|
|
26
|
-
display(`Running command: ${interactiveCommand}`, "
|
|
27
|
-
await runCommand(interactiveCommand);
|
|
37
|
+
display(`Running interactive command: ${interactiveCommand}`, "info");
|
|
38
|
+
await runCommand(interactiveCommand, true);
|
|
28
39
|
}
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
// Then run non-interactive
|
|
32
43
|
if (command.nonInteractive) {
|
|
44
|
+
// For non-interactive, we show a spinner
|
|
33
45
|
display(`Running command: ${command.nonInteractive[0]}`, "loading");
|
|
34
|
-
await runCommand(command.nonInteractive[0] as string);
|
|
46
|
+
await runCommand(command.nonInteractive[0] as string, false);
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
} catch (error: any) {
|
package/src/orchestrator.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { buildCommands, buildUninstallCommands } from "./build_command.js";
|
|
2
2
|
import { getConfigObject } from "./config_reader.js";
|
|
3
|
-
import { display } from "./display.js";
|
|
3
|
+
import { display, stopSpinner } from "./display.js";
|
|
4
4
|
import { install } from "./install.js";
|
|
5
5
|
import type { ConfigType } from "./types/index.js";
|
|
6
|
+
import { outro } from "@clack/prompts";
|
|
6
7
|
|
|
7
8
|
//Check if the value is an array of ConfigType objects
|
|
8
9
|
function isConfigTypeArray(value: unknown): value is ConfigType[] {
|
|
@@ -38,15 +39,14 @@ export const orchestrator = (
|
|
|
38
39
|
if (isConfigTypeArray(config)) {
|
|
39
40
|
const commands = buildCommands(config);
|
|
40
41
|
await install(commands);
|
|
41
|
-
|
|
42
|
+
stopSpinner("Packages installed successfully");
|
|
42
43
|
process.stdout.write("\x07");
|
|
44
|
+
outro("Done!");
|
|
43
45
|
} else {
|
|
44
46
|
await install(config);
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"success",
|
|
49
|
-
);
|
|
48
|
+
stopSpinner("Packages from package.json installed successfully");
|
|
49
|
+
outro("Done!");
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
} else {
|
|
@@ -64,7 +64,8 @@ export const orchestrator = (
|
|
|
64
64
|
if (isConfigTypeArray(config)) {
|
|
65
65
|
const commands = buildUninstallCommands(config);
|
|
66
66
|
await install(commands);
|
|
67
|
-
|
|
67
|
+
stopSpinner("Packages uninstalled successfully");
|
|
68
|
+
outro("Done!");
|
|
68
69
|
}
|
|
69
70
|
});
|
|
70
71
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
export interface ConfigType {
|
|
2
|
-
name: string;
|
|
3
|
-
packageManager: string;
|
|
4
|
-
packages: { command: string; interactive: boolean }[];
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface PackageType {
|
|
8
|
-
command: string;
|
|
9
|
-
interactive: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface CommandResult {
|
|
13
|
-
name: string;
|
|
14
|
-
interactive: string[];
|
|
15
|
-
nonInteractive: string[];
|
|
16
|
-
}
|
|
1
|
+
export interface ConfigType {
|
|
2
|
+
name: string;
|
|
3
|
+
packageManager: string;
|
|
4
|
+
packages: { command: string; interactive: boolean }[];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface PackageType {
|
|
8
|
+
command: string;
|
|
9
|
+
interactive: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CommandResult {
|
|
13
|
+
name: string;
|
|
14
|
+
interactive: string[];
|
|
15
|
+
nonInteractive: string[];
|
|
16
|
+
}
|
package/test.json
CHANGED
|
@@ -1,83 +1,94 @@
|
|
|
1
|
-
{
|
|
2
|
-
"
|
|
3
|
-
"name": "
|
|
4
|
-
"packageManager": "npm",
|
|
5
|
-
"packages": [
|
|
6
|
-
{
|
|
7
|
-
"command": "
|
|
8
|
-
"interactive": false
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
"command": "
|
|
31
|
-
"interactive":
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"sample": {
|
|
3
|
+
"name": "sample",
|
|
4
|
+
"packageManager": "npm",
|
|
5
|
+
"packages": [
|
|
6
|
+
{
|
|
7
|
+
"command": "gsap",
|
|
8
|
+
"interactive": false
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
"vite": {
|
|
14
|
+
"name": "vite",
|
|
15
|
+
"packageManager": "npm",
|
|
16
|
+
"packages": [
|
|
17
|
+
{
|
|
18
|
+
"command": "@types/three --save-dev",
|
|
19
|
+
"interactive": false
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"command": "@react-three/fiber",
|
|
23
|
+
"interactive": false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"command": "gsap",
|
|
27
|
+
"interactive": false
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"command": "create-vite@latest my-app",
|
|
31
|
+
"interactive": true
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
"next": {
|
|
37
|
+
"name": "next",
|
|
38
|
+
"packageManager": "pnpm",
|
|
39
|
+
"packages": [
|
|
40
|
+
{
|
|
41
|
+
"command": "three --save-dev",
|
|
42
|
+
"interactive": false
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"command": "@react-three/drei",
|
|
46
|
+
"interactive": false
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"command": "framer-motion",
|
|
50
|
+
"interactive": false
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"command": "create-next-app@latest my-app",
|
|
54
|
+
"interactive": true
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"test": {
|
|
59
|
+
"name": "test",
|
|
60
|
+
"packageManager": "npm",
|
|
61
|
+
"packages": [
|
|
62
|
+
{
|
|
63
|
+
"command": "three",
|
|
64
|
+
"interactive": false
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"command": "gsap",
|
|
68
|
+
"interactive": false
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"command": "@react-three/fiber",
|
|
72
|
+
"interactive": false
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"test2": {
|
|
77
|
+
"name": "test2",
|
|
78
|
+
"packageManager": "npm",
|
|
79
|
+
"packages": [
|
|
80
|
+
{
|
|
81
|
+
"command": "@react-three/drei",
|
|
82
|
+
"interactive": false
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"command": "framer-motion",
|
|
86
|
+
"interactive": false
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"command": "@react-three/postprocessing",
|
|
90
|
+
"interactive": false
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
}
|