pm-auto 1.0.5 → 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.
Files changed (46) hide show
  1. package/README.md +6 -3
  2. package/config.json +45 -0
  3. package/dist/build_command.d.ts +6 -1
  4. package/dist/build_command.d.ts.map +1 -1
  5. package/dist/build_command.js +66 -13
  6. package/dist/build_command.js.map +1 -1
  7. package/dist/config_path.d.ts +1 -0
  8. package/dist/config_path.d.ts.map +1 -1
  9. package/dist/config_path.js +60 -2
  10. package/dist/config_path.js.map +1 -1
  11. package/dist/config_reader.d.ts +2 -12
  12. package/dist/config_reader.d.ts.map +1 -1
  13. package/dist/config_reader.js +76 -92
  14. package/dist/config_reader.js.map +1 -1
  15. package/dist/display.d.ts +5 -0
  16. package/dist/display.d.ts.map +1 -1
  17. package/dist/display.js +2 -1
  18. package/dist/display.js.map +1 -1
  19. package/dist/index.js +6 -7
  20. package/dist/index.js.map +1 -1
  21. package/dist/orchestrator.d.ts.map +1 -1
  22. package/dist/orchestrator.js +18 -28
  23. package/dist/orchestrator.js.map +1 -1
  24. package/dist/run_commands.d.ts +6 -0
  25. package/dist/run_commands.d.ts.map +1 -0
  26. package/dist/{install.js → run_commands.js} +10 -7
  27. package/dist/run_commands.js.map +1 -0
  28. package/dist/types/index.d.ts +8 -2
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/package.json +4 -2
  31. package/src/build_command.ts +78 -13
  32. package/src/config_path.ts +63 -2
  33. package/src/config_reader.ts +90 -110
  34. package/src/display.ts +2 -2
  35. package/src/index.ts +8 -13
  36. package/src/orchestrator.ts +21 -34
  37. package/src/{install.ts → run_commands.ts} +10 -6
  38. package/src/types/index.ts +12 -3
  39. package/tests/build_command.test.ts +240 -30
  40. package/tests/config_reader.test.ts +51 -92
  41. package/tests/display.test.ts +42 -34
  42. package/tests/{install.test.ts → run_command.test.ts} +23 -23
  43. package/dist/install.d.ts +0 -6
  44. package/dist/install.d.ts.map +0 -1
  45. package/dist/install.js.map +0 -1
  46. package/test.json +0 -87
package/dist/index.js CHANGED
@@ -10,8 +10,8 @@ intro(chalk.inverse(" pm-auto "));
10
10
  const program = new Command();
11
11
  program
12
12
  .name("pm-auto")
13
- .version("1.0.5")
14
- .description("A CLI tool to define and install your tech stack presets with one command.");
13
+ .version("1.0.7")
14
+ .description("Automate your project setup with one command");
15
15
  program
16
16
  .command("config <path>")
17
17
  .description("Set the path to the configuration file")
@@ -23,8 +23,7 @@ program
23
23
  .alias("add")
24
24
  .alias("i")
25
25
  .description("Install packages using the detected package manager (Aliases: add, i)")
26
- .option("-p, --pkg-json", "Install packages from package.json")
27
- .option("-A, --add-command <command>", "Add a custom command to all installation commands from config file")
26
+ .option("-A, --add-flags <flags>", "Add custom flags to already defined flags from config file")
28
27
  .option("-D, --dry-run", "Dry run - Display commands before execution")
29
28
  .action((packages, options) => {
30
29
  orchestrator("install", packages, options);
@@ -35,7 +34,7 @@ program
35
34
  .alias("u")
36
35
  .alias("un")
37
36
  .description("Remove packages using the detected package manager (Aliases: remove, u, un)")
38
- .option("-A, --add-command <command>", "Add a custom command to all installation commands from config file")
37
+ .option("-D, --dry-run", "Dry run - Display commands before execution")
39
38
  .action((packages, options) => {
40
39
  orchestrator("uninstall", packages, options);
41
40
  });
@@ -44,11 +43,11 @@ program
44
43
  .command("list")
45
44
  .alias("ls")
46
45
  .description("List all packages from the config file")
47
- .option("-D, --desc", "Display packages description", false)
46
+ .option("--desc", "Display packages description", false)
48
47
  .action((options) => {
49
48
  getConfigKeys(options);
50
49
  });
51
- //Displaying config details
50
+ //Display a config description
52
51
  program
53
52
  .command("describe <package>")
54
53
  .alias("desc")
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AAElC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CACV,4EAA4E,CAC7E,CAAC;AAEJ,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACf,cAAc,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,uBAAuB,CAAC;KAChC,KAAK,CAAC,KAAK,CAAC;KACZ,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CACV,uEAAuE,CACxE;KACA,MAAM,CAAC,gBAAgB,EAAE,oCAAoC,CAAC;KAC9D,MAAM,CACL,6BAA6B,EAC7B,oEAAoE,CACrE;KACA,MAAM,CAAC,eAAe,EAAE,6CAA6C,CAAC;KACtE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;IAC5B,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,yBAAyB,CAAC;KAClC,KAAK,CAAC,QAAQ,CAAC;KACf,KAAK,CAAC,GAAG,CAAC;KACV,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CACV,6EAA6E,CAC9E;KACA,MAAM,CACL,6BAA6B,EAC7B,oEAAoE,CACrE;KACA,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;IAC5B,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEL,yBAAyB;AACzB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,8BAA8B,EAAE,KAAK,CAAC;KAC3D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,aAAa,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,2BAA2B;AAC3B,OAAO;KACJ,OAAO,CAAC,oBAAoB,CAAC;KAC7B,KAAK,CAAC,MAAM,CAAC;KACb,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;IACnB,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEL,iBAAiB;AACjB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,OAAO,CAAC,gBAAgB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AAElC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,8CAA8C,CAAC,CAAC;AAE/D,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACf,cAAc,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,uBAAuB,CAAC;KAChC,KAAK,CAAC,KAAK,CAAC;KACZ,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CACV,uEAAuE,CACxE;KACA,MAAM,CACL,yBAAyB,EACzB,4DAA4D,CAC7D;KACA,MAAM,CAAC,eAAe,EAAE,6CAA6C,CAAC;KACtE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;IAC5B,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,yBAAyB,CAAC;KAClC,KAAK,CAAC,QAAQ,CAAC;KACf,KAAK,CAAC,GAAG,CAAC;KACV,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CACV,6EAA6E,CAC9E;KACA,MAAM,CAAC,eAAe,EAAE,6CAA6C,CAAC;KAEtE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;IAC5B,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEL,yBAAyB;AACzB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,QAAQ,EAAE,8BAA8B,EAAE,KAAK,CAAC;KACvD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,aAAa,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,8BAA8B;AAC9B,OAAO;KACJ,OAAO,CAAC,oBAAoB,CAAC;KAC7B,KAAK,CAAC,MAAM,CAAC;KACb,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;IACnB,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEL,iBAAiB;AACjB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,OAAO,CAAC,gBAAgB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,UAAU,MAAM,EAAE,EAClB,UAAU,GAAG,SA8Cd,CAAC"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,UAAU,MAAM,EAAE,EAClB,UAAU,GAAG,SA2Cd,CAAC"}
@@ -1,50 +1,40 @@
1
- import { buildCommands, buildUninstallCommands } from "./build_command.js";
1
+ import { buildInstallCommands, buildUninstallCommands, } from "./build_command.js";
2
2
  import { getConfigObject } from "./config_reader.js";
3
3
  import { display } from "./display.js";
4
- import { install } from "./install.js";
4
+ import { runCommands } from "./run_commands.js";
5
5
  import { outro } from "@clack/prompts";
6
- //Check if the value is an array of ConfigType objects
7
- function isConfigTypeArray(value) {
8
- return (Array.isArray(value) &&
9
- value.every((item) => typeof item === "object" &&
10
- item !== null &&
11
- "packages" in item &&
12
- Array.isArray(item.packages)));
13
- }
6
+ //Controls installation and uninstallation of packages
14
7
  export const orchestrator = (command, packages, options) => {
15
8
  if (command === "install") {
16
- display(`Installing packages... ${options.pkgJson ? "from package.json" : packages.join(", ")}`, "info");
9
+ display(`Installing packages... ${packages.join(", ")}`, "info");
10
+ const start = performance.now();
17
11
  getConfigObject(packages, options).then(async (config) => {
18
12
  if (config.length === 0) {
19
13
  display("No configuration found", "error");
20
14
  return;
21
15
  }
22
- if (isConfigTypeArray(config)) {
23
- const commands = buildCommands(config);
24
- await install(commands);
25
- display("Packages installed successfully", "success");
26
- outro("Done!");
27
- }
28
- else {
29
- await install(config);
30
- display("Packages from package.json installed successfully", "success");
31
- outro("Done!");
32
- }
16
+ const commands = buildInstallCommands(config);
17
+ await runCommands(commands);
18
+ outro("Done!");
19
+ const end = performance.now();
20
+ display(`Installation took ${Math.round((end - start) / 1000)}s`, "info");
21
+ display("Packages installed successfully", "success");
33
22
  });
34
23
  }
35
24
  else {
36
25
  display(`Uninstalling packages... ${packages.join(", ")}`, "info");
26
+ const start = performance.now();
37
27
  getConfigObject(packages, options).then(async (config) => {
38
28
  if (config.length === 0) {
39
29
  display("No configuration found", "error");
40
30
  return;
41
31
  }
42
- if (isConfigTypeArray(config)) {
43
- const commands = buildUninstallCommands(config);
44
- await install(commands);
45
- display("Packages uninstalled successfully", "success");
46
- outro("Done!");
47
- }
32
+ const commands = buildUninstallCommands(config);
33
+ await runCommands(commands);
34
+ outro("Done!");
35
+ const end = performance.now();
36
+ display(`Uninstallation took ${end - start}ms`, "info");
37
+ display("Packages uninstalled successfully", "success");
48
38
  });
49
39
  }
50
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,sDAAsD;AACtD,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,KAAK,CAAC,KAAK,CACT,CAAC,IAAI,EAAE,EAAE,CACP,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,UAAU,IAAI,IAAI;YAClB,KAAK,CAAC,OAAO,CAAE,IAAY,CAAC,QAAQ,CAAC,CACxC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,QAAkB,EAClB,OAAa,EACb,EAAE;IACF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,CACL,0BAA0B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAE,QAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACrG,MAAM,CACP,CAAC;QAEF,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;gBAEvC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO,CAAC,iCAAiC,EAAE,SAAS,CAAC,CAAC;gBACtD,KAAK,CAAC,OAAO,CAAC,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO,CAAC,mDAAmD,EAAE,SAAS,CAAC,CAAC;gBACxE,KAAK,CAAC,OAAO,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CACL,4BAA6B,QAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC/D,MAAM,CACP,CAAC;QAEF,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,QAAQ,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO,CAAC,mCAAmC,EAAE,SAAS,CAAC,CAAC;gBACxD,KAAK,CAAC,OAAO,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,sDAAsD;AACtD,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,QAAkB,EAClB,OAAa,EACb,EAAE;IACF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,CACL,0BAA2B,QAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC7D,MAAM,CACP,CAAC;QACF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAE9C,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC5B,KAAK,CAAC,OAAO,CAAC,CAAC;YACf,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO,CAAC,qBAAqB,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1E,OAAO,CAAC,iCAAiC,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CACL,4BAA6B,QAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC/D,MAAM,CACP,CAAC;QAEF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC5B,KAAK,CAAC,OAAO,CAAC,CAAC;YACf,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO,CAAC,uBAAuB,GAAG,GAAG,KAAK,IAAI,EAAE,MAAM,CAAC,CAAC;YACxD,OAAO,CAAC,mCAAmC,EAAE,SAAS,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { CommandResult } from "./types/index.js";
2
+ /**
3
+ * Run all commands
4
+ */
5
+ export declare function runCommands(commands: CommandResult[]): Promise<void>;
6
+ //# sourceMappingURL=run_commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run_commands.d.ts","sourceRoot":"","sources":["../src/run_commands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA0BtD;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,iBAuB1D"}
@@ -1,5 +1,5 @@
1
1
  import { execa } from "execa";
2
- import { display } from "./display.js";
2
+ import { display, s } from "./display.js";
3
3
  async function runCommand(command, interactive = false) {
4
4
  try {
5
5
  const [commandName, ...args] = command.split(" ");
@@ -9,6 +9,7 @@ async function runCommand(command, interactive = false) {
9
9
  });
10
10
  }
11
11
  else {
12
+ s.stop();
12
13
  await execa(commandName, args, {
13
14
  stdio: "inherit",
14
15
  });
@@ -24,13 +25,13 @@ async function runCommand(command, interactive = false) {
24
25
  }
25
26
  }
26
27
  /**
27
- * Install all commands
28
+ * Run all commands
28
29
  */
29
- export async function install(commands) {
30
+ export async function runCommands(commands) {
30
31
  try {
31
32
  for (const command of commands) {
32
33
  // Wait for all interactive commands to finish first
33
- if (command.interactive) {
34
+ if (command.interactive.length > 0) {
34
35
  for (const interactiveCommand of command.interactive) {
35
36
  display(`Running interactive command: ${interactiveCommand}`, "info");
36
37
  await runCommand(interactiveCommand, true);
@@ -39,8 +40,10 @@ export async function install(commands) {
39
40
  // Then run non-interactive
40
41
  if (command.nonInteractive.length > 0) {
41
42
  // For non-interactive, we show a spinner
42
- display(`Running command: ${command.nonInteractive[0]}`, "loading");
43
- await runCommand(command.nonInteractive[0], false);
43
+ for (let i = 0; i < command.nonInteractive.length; i++) {
44
+ display(`Running command: ${command.nonInteractive[i]}`, "loading");
45
+ await runCommand(command.nonInteractive[i], false);
46
+ }
44
47
  }
45
48
  }
46
49
  }
@@ -48,4 +51,4 @@ export async function install(commands) {
48
51
  display(`Error: ${error.message}`, "error");
49
52
  }
50
53
  }
51
- //# sourceMappingURL=install.js.map
54
+ //# sourceMappingURL=run_commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run_commands.js","sourceRoot":"","sources":["../src/run_commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAE1C,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,cAAuB,KAAK;IACrE,IAAI,CAAC;QACH,MAAM,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAElD,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,KAAK,CAAC,WAAqB,EAAE,IAAI,EAAE;gBACvC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,CAAC,CAAC,IAAI,EAAE,CAAC;YAET,MAAM,KAAK,CAAC,WAAqB,EAAE,IAAI,EAAE;gBACvC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,4CAA4C;QAC5C,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,CAAC,WAAW,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAyB;IACzD,IAAI,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,oDAAoD;YACpD,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,KAAK,MAAM,kBAAkB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBACrD,OAAO,CAAC,gCAAgC,kBAAkB,EAAE,EAAE,MAAM,CAAC,CAAC;oBACtE,MAAM,UAAU,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,2BAA2B;YAC3B,IAAI,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,yCAAyC;gBACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvD,OAAO,CAAC,oBAAoB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;oBACpE,MAAM,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAW,EAAE,KAAK,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
@@ -1,18 +1,24 @@
1
1
  export interface ConfigType {
2
- name: string;
2
+ presetName: string;
3
3
  description?: string;
4
4
  packageManager: string;
5
5
  packages: {
6
6
  command: string;
7
7
  interactive: boolean;
8
+ dev?: boolean;
9
+ flags?: string[];
10
+ version?: string;
8
11
  }[];
9
12
  }
10
13
  export interface PackageType {
11
14
  command: string;
12
15
  interactive: boolean;
16
+ dev?: boolean;
17
+ flags?: string[];
18
+ version?: string;
13
19
  }
14
20
  export interface CommandResult {
15
- name: string;
21
+ presetName: string;
16
22
  interactive: string[];
17
23
  nonInteractive: string[];
18
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-auto",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "A CLI tool to define and install your tech stack presets with one command.",
5
5
  "keywords": [
6
6
  "pm-auto",
@@ -20,12 +20,14 @@
20
20
  "dev": "nodemon --exec tsx src/index.ts",
21
21
  "start": "node dist/index.js",
22
22
  "prepublishOnly": "npm run build",
23
- "test": "vitest run"
23
+ "test": "vitest"
24
24
  },
25
25
  "dependencies": {
26
26
  "@clack/prompts": "^0.11.0",
27
27
  "chalk": "^5.6.2",
28
28
  "commander": "^14.0.2",
29
+ "desc": "^1.0.0",
30
+ "example": "^0.0.0",
29
31
  "execa": "^9.6.0"
30
32
  },
31
33
  "devDependencies": {
@@ -4,7 +4,30 @@ import type { ConfigType, PackageType, CommandResult } from "./types/index.js";
4
4
  * Build commands from project configurations.
5
5
  */
6
6
 
7
- export function buildCommands(projects: ConfigType[]) {
7
+ /**
8
+ * Extracts the package name from a raw command string
9
+ * Removes version and any flags (starts with -)
10
+ */
11
+
12
+ export function cleanCommand(rawCommand: string): string {
13
+ // Split by spaces and pick first segment that doesn't start with "-"
14
+ const parts = rawCommand.trim().split(" ");
15
+ for (const part of parts) {
16
+ if (!part.startsWith("-")) {
17
+ // Remove version if exists
18
+
19
+ const atIndex = part.indexOf("@");
20
+ if (atIndex > 0) {
21
+ return part.slice(0, atIndex).trim();
22
+ } else {
23
+ return part.trim();
24
+ }
25
+ }
26
+ }
27
+ return ""; // fallback
28
+ }
29
+
30
+ export function buildInstallCommands(projects: ConfigType[]) {
8
31
  // Initialize arrays properly
9
32
 
10
33
  const commandArray: CommandResult[] = [];
@@ -15,14 +38,22 @@ export function buildCommands(projects: ConfigType[]) {
15
38
  npm: {
16
39
  install: "npm install",
17
40
  run: "npx",
41
+ dev: "-D",
18
42
  },
19
43
  pnpm: {
20
44
  install: "pnpm add",
21
45
  run: "pnpm dlx",
46
+ dev: "-D",
22
47
  },
23
48
  yarn: {
24
49
  install: "yarn add",
25
50
  run: "yarn dlx",
51
+ dev: "-D",
52
+ },
53
+ bun: {
54
+ install: "bun add",
55
+ run: "bunx",
56
+ dev: "-d",
26
57
  },
27
58
  };
28
59
 
@@ -31,7 +62,7 @@ export function buildCommands(projects: ConfigType[]) {
31
62
  commandPrefixes.npm;
32
63
 
33
64
  const result: CommandResult = {
34
- name: project.name,
65
+ presetName: project.presetName,
35
66
  interactive: [],
36
67
  nonInteractive: [],
37
68
  };
@@ -52,13 +83,43 @@ export function buildCommands(projects: ConfigType[]) {
52
83
 
53
84
  // Add interactive packages as separate commands (sequential)
54
85
  interactive.forEach((pkg) => {
55
- result.interactive.push(`${manager.run} ${pkg.command}`);
86
+ result.interactive.push(
87
+ `${manager.run} ${cleanCommand(pkg.command)}${pkg.version ? `@${pkg.version}` : ""} ${pkg.flags?.join(" ") || ""}`.trim(),
88
+ );
56
89
  });
57
90
 
58
- // Batch all non-interactive packages into ONE command
91
+ // Batch all non-interactive packages
59
92
  if (nonInteractive.length > 0) {
60
- const packageNames = nonInteractive.map((pkg) => pkg.command).join(" ");
61
- result.nonInteractive.push(`${manager.install} ${packageNames}`);
93
+ const batchPackages: string[] = [];
94
+
95
+ nonInteractive.forEach((pkg) => {
96
+ const base = cleanCommand(pkg.command); // package name or full command
97
+ let cmd = base;
98
+
99
+ // Append version if present
100
+ if (pkg.version) {
101
+ cmd += `@${pkg.version}`;
102
+ }
103
+
104
+ // Append dev flag if true (mapped per manager)
105
+ if (pkg.dev) {
106
+ cmd += ` ${manager.dev}`;
107
+ }
108
+
109
+ // Append any extra flags
110
+ if (pkg.flags?.length) {
111
+ cmd += ` ${pkg.flags.join(" ")}`;
112
+ }
113
+
114
+ batchPackages.push(cmd);
115
+ });
116
+
117
+ // Push a single install command for all batchable packages
118
+ if (batchPackages.length > 0) {
119
+ result.nonInteractive.push(
120
+ `${manager.install} ${batchPackages.join(" ")}`,
121
+ );
122
+ }
62
123
  }
63
124
 
64
125
  commandArray.push(result);
@@ -74,13 +135,16 @@ export function buildUninstallCommands(projects: ConfigType[]) {
74
135
 
75
136
  const commandPrefixes = {
76
137
  npm: {
77
- install: "npm uninstall",
138
+ uninstall: "npm uninstall",
78
139
  },
79
140
  pnpm: {
80
- install: "pnpm uninstall",
141
+ uninstall: "pnpm remove",
81
142
  },
82
143
  yarn: {
83
- install: "yarn remove",
144
+ uninstall: "yarn remove",
145
+ },
146
+ bun: {
147
+ uninstall: "bun remove",
84
148
  },
85
149
  };
86
150
 
@@ -89,14 +153,13 @@ export function buildUninstallCommands(projects: ConfigType[]) {
89
153
  commandPrefixes.npm;
90
154
 
91
155
  const result: CommandResult = {
92
- name: project.name,
156
+ presetName: project.presetName,
93
157
  interactive: [],
94
158
  nonInteractive: [],
95
159
  };
96
160
 
97
161
  // Separate interactive from non-interactive packages
98
162
  const nonInteractive: PackageType[] = [];
99
- // const interactive: PackageType[] = [];
100
163
 
101
164
  if (packages) {
102
165
  packages.forEach((pkg) => {
@@ -108,8 +171,10 @@ export function buildUninstallCommands(projects: ConfigType[]) {
108
171
 
109
172
  // Batch all non-interactive packages into ONE command
110
173
  if (nonInteractive.length > 0) {
111
- const packageNames = nonInteractive.map((pkg) => pkg.command).join(" ");
112
- result.nonInteractive.push(`${manager.install} ${packageNames}`);
174
+ const packageNames = nonInteractive
175
+ .map((pkg) => cleanCommand(pkg.command))
176
+ .join(" ");
177
+ result.nonInteractive.push(`${manager.uninstall} ${packageNames}`);
113
178
  }
114
179
 
115
180
  commandArray.push(result);
@@ -5,24 +5,85 @@ import { display } from "./display.js";
5
5
 
6
6
  const SETTINGS_DIR = path.join(os.homedir(), ".pm-auto");
7
7
  const SETTINGS_FILE = path.join(SETTINGS_DIR, "settings.json");
8
+ const EXAMPLE_CONFIG_TEXT = `{
9
+ "example": {
10
+ "presetName": "example",
11
+ "description": "A sample configuration demonstrating all options for PM-Auto",
12
+ "packageManager": "bun",
13
+ "packages": [
14
+ {
15
+ "command": "create-next-app",
16
+ "interactive": true,
17
+ "dev": false,
18
+ "version": "latest",
19
+ "flags": ["."]
20
+ },
21
+ {
22
+ "command": "shadcn",
23
+ "interactive": true,
24
+ "dev": false,
25
+ "version": "latest",
26
+ "flags": ["init"]
27
+ },
28
+ {
29
+ "command": "gsap",
30
+ "interactive": false,
31
+ "dev": false,
32
+ "version": "3.11.4",
33
+ "flags": ["--peer-deps"]
34
+ },
35
+ {
36
+ "command": "@react-three/fiber",
37
+ "interactive": false,
38
+ "dev": false
39
+ },
40
+ {
41
+ "command": "clsx",
42
+ "interactive": false,
43
+ "dev": false
44
+ },
45
+ {
46
+ "command": "@types/three",
47
+ "interactive": false,
48
+ "dev": true
49
+ }
50
+ ]
51
+ }
52
+ }
53
+ `;
8
54
 
9
55
  interface Settings {
10
56
  configPath?: string;
11
57
  }
12
58
 
59
+ export function prependToFile(filePath: string, text: string) {
60
+ display(`Prepending to example to file: ${filePath}`, "info");
61
+
62
+ // Read old content if file exists
63
+ const oldContent = fs.existsSync(filePath)
64
+ ? fs.readFileSync(filePath, "utf8")
65
+ : "";
66
+
67
+ // Write new content at the top
68
+ if (!oldContent.includes(text)) {
69
+ fs.writeFileSync(filePath, text + oldContent, "utf8");
70
+ }
71
+ display(`Example prepended successfully: ${filePath}`, "success");
72
+ }
73
+
13
74
  export function saveConfigPath(configPath: string): void {
14
75
  // Create directory if it doesn't exist
15
76
  if (!fs.existsSync(SETTINGS_DIR)) {
16
77
  fs.mkdirSync(SETTINGS_DIR, { recursive: true });
17
78
  }
18
79
 
19
- //check if file exists
20
80
  try {
21
81
  const real = fs.realpathSync(configPath);
22
82
  const settings: Settings = { configPath: real };
23
83
  fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2));
24
84
 
25
- display(`Config file path saved: ${configPath}`, "success");
85
+ display(`Config file path saved: ${configPath}`, "info");
86
+ prependToFile(real, EXAMPLE_CONFIG_TEXT);
26
87
  } catch (err: any) {
27
88
  display(`Error saving config file: ${err.message}`, "error");
28
89
  }