isaacscript 1.2.2 → 1.2.5

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 (63) hide show
  1. package/dist/package.json +5 -5
  2. package/dist/src/commands/copy/copy.js +12 -10
  3. package/dist/src/commands/copy/copy.js.map +1 -1
  4. package/dist/src/commands/init/checkIfProjectPathExists.js +2 -2
  5. package/dist/src/commands/init/checkIfProjectPathExists.js.map +1 -1
  6. package/dist/src/commands/init/checkModTargetDirectory.js +2 -2
  7. package/dist/src/commands/init/checkModTargetDirectory.js.map +1 -1
  8. package/dist/src/commands/init/createMod.js +65 -44
  9. package/dist/src/commands/init/createMod.js.map +1 -1
  10. package/dist/src/commands/init/init.js +10 -8
  11. package/dist/src/commands/init/init.js.map +1 -1
  12. package/dist/src/commands/init/installVSCodeExtensions.js +3 -2
  13. package/dist/src/commands/init/installVSCodeExtensions.js.map +1 -1
  14. package/dist/src/commands/init/promptVSCode.js +7 -7
  15. package/dist/src/commands/init/promptVSCode.js.map +1 -1
  16. package/dist/src/commands/monitor/copyWatcherMod.js +7 -7
  17. package/dist/src/commands/monitor/copyWatcherMod.js.map +1 -1
  18. package/dist/src/commands/monitor/monitor.js +4 -3
  19. package/dist/src/commands/monitor/monitor.js.map +1 -1
  20. package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js +1 -1
  21. package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js.map +1 -1
  22. package/dist/src/commands/monitor/touchWatcherSaveDatFiles.js +3 -3
  23. package/dist/src/commands/monitor/touchWatcherSaveDatFiles.js.map +1 -1
  24. package/dist/src/commands/publish/publish.js +48 -46
  25. package/dist/src/commands/publish/publish.js.map +1 -1
  26. package/dist/src/configFile.js +4 -3
  27. package/dist/src/configFile.js.map +1 -1
  28. package/dist/src/exec.js +79 -0
  29. package/dist/src/exec.js.map +1 -0
  30. package/dist/src/file.js +35 -5
  31. package/dist/src/file.js.map +1 -1
  32. package/dist/src/main.js +1 -1
  33. package/dist/src/main.js.map +1 -1
  34. package/dist/src/monkeyPatch.js +4 -4
  35. package/dist/src/monkeyPatch.js.map +1 -1
  36. package/dist/src/parseArgs.js +20 -1
  37. package/dist/src/parseArgs.js.map +1 -1
  38. package/dist/src/util.js +22 -57
  39. package/dist/src/util.js.map +1 -1
  40. package/dist/src/validateNodeVersion.js +6 -24
  41. package/dist/src/validateNodeVersion.js.map +1 -1
  42. package/file-templates/static/build.sh +1 -1
  43. package/package.json +5 -5
  44. package/src/commands/copy/copy.ts +19 -10
  45. package/src/commands/init/checkIfProjectPathExists.ts +2 -1
  46. package/src/commands/init/checkModTargetDirectory.ts +2 -1
  47. package/src/commands/init/createMod.ts +108 -50
  48. package/src/commands/init/init.ts +15 -7
  49. package/src/commands/init/installVSCodeExtensions.ts +4 -2
  50. package/src/commands/init/promptVSCode.ts +12 -7
  51. package/src/commands/monitor/copyWatcherMod.ts +10 -7
  52. package/src/commands/monitor/monitor.ts +5 -3
  53. package/src/commands/monitor/saveDatWriter/saveDatWriter.ts +1 -1
  54. package/src/commands/monitor/touchWatcherSaveDatFiles.ts +6 -3
  55. package/src/commands/publish/publish.ts +66 -55
  56. package/src/configFile.ts +9 -3
  57. package/src/exec.ts +102 -0
  58. package/src/file.ts +48 -5
  59. package/src/main.ts +1 -1
  60. package/src/monkeyPatch.ts +4 -2
  61. package/src/parseArgs.ts +22 -1
  62. package/src/util.ts +29 -79
  63. package/src/validateNodeVersion.ts +7 -39
@@ -13,15 +13,18 @@ import { promptSaveSlot } from "./promptSaveSlot";
13
13
  import { promptVSCode } from "./promptVSCode";
14
14
 
15
15
  export async function init(argv: Record<string, unknown>): Promise<void> {
16
+ const vscode = argv.vscode === true;
17
+ const skipNPMInstall = argv.skipNpmInstall === true;
18
+ const verbose = argv.verbose === true;
19
+
16
20
  // Prompt the end-user for some information (and validate it as we go)
17
21
  const [projectPath, createNewDir] = await getProjectPath(argv);
18
- await checkIfProjectPathExists(projectPath);
22
+ await checkIfProjectPathExists(projectPath, verbose);
19
23
  const modsDirectory = await getModsDir(argv);
20
24
  checkModSubdirectory(projectPath, modsDirectory);
21
25
  const projectName = path.basename(projectPath);
22
- await checkModTargetDirectory(modsDirectory, projectName);
26
+ await checkModTargetDirectory(modsDirectory, projectName, verbose);
23
27
  const saveSlot = await promptSaveSlot(argv);
24
- const skipNPMInstall = argv.skipNpmInstall === true;
25
28
 
26
29
  await createMod(
27
30
  projectName,
@@ -30,12 +33,17 @@ export async function init(argv: Record<string, unknown>): Promise<void> {
30
33
  modsDirectory,
31
34
  saveSlot,
32
35
  skipNPMInstall,
36
+ verbose,
33
37
  );
34
- await openVSCode(projectPath, argv);
38
+ await openVSCode(projectPath, vscode, verbose);
35
39
  printFinishMessage(projectPath, projectName);
36
40
  }
37
41
 
38
- async function openVSCode(projectPath: string, argv: Record<string, unknown>) {
42
+ async function openVSCode(
43
+ projectPath: string,
44
+ vscode: boolean,
45
+ verbose: boolean,
46
+ ) {
39
47
  const VSCodeCommand = getVSCodeCommand();
40
48
  if (VSCodeCommand === null) {
41
49
  console.log(
@@ -44,8 +52,8 @@ async function openVSCode(projectPath: string, argv: Record<string, unknown>) {
44
52
  return;
45
53
  }
46
54
 
47
- installVSCodeExtensions(projectPath, VSCodeCommand);
48
- await promptVSCode(projectPath, argv, VSCodeCommand);
55
+ installVSCodeExtensions(projectPath, VSCodeCommand, verbose);
56
+ await promptVSCode(projectPath, VSCodeCommand, vscode, verbose);
49
57
  }
50
58
 
51
59
  function getVSCodeCommand() {
@@ -1,16 +1,18 @@
1
1
  import chalk from "chalk";
2
2
  import * as JSONC from "jsonc-parser";
3
3
  import path from "path";
4
+ import { execShell } from "../../exec";
4
5
  import * as file from "../../file";
5
- import { error, execShell } from "../../util";
6
+ import { error } from "../../util";
6
7
 
7
8
  export function installVSCodeExtensions(
8
9
  projectPath: string,
9
10
  VSCodeCommand: string,
11
+ verbose: boolean,
10
12
  ): void {
11
13
  const extensions = getExtensionsFromJSON(projectPath);
12
14
  for (const extensionName of extensions) {
13
- execShell(VSCodeCommand, ["--install-extension", extensionName]);
15
+ execShell(VSCodeCommand, ["--install-extension", extensionName], verbose);
14
16
  }
15
17
  }
16
18
 
@@ -1,17 +1,18 @@
1
1
  import path from "path";
2
2
  import { MAIN_TS } from "../../constants";
3
+ import { execShell } from "../../exec";
3
4
  import { getInputYesNo } from "../../prompt";
4
- import { execShell } from "../../util";
5
5
 
6
6
  export async function promptVSCode(
7
7
  projectPath: string,
8
- argv: Record<string, unknown>,
9
8
  VSCodeCommand: string,
9
+ vscode: boolean,
10
+ verbose: boolean,
10
11
  ): Promise<void> {
11
- if (argv.vscode !== undefined) {
12
+ if (vscode) {
12
13
  // They supplied the "--vscode" command-line flag,
13
14
  // so there is no need to prompt the user
14
- openVSCode(projectPath, VSCodeCommand);
15
+ openVSCode(projectPath, VSCodeCommand, verbose);
15
16
  return;
16
17
  }
17
18
 
@@ -19,11 +20,15 @@ export async function promptVSCode(
19
20
  "Do you want to open your new project in VSCode now?",
20
21
  );
21
22
  if (shouldOpenVSCode) {
22
- openVSCode(projectPath, VSCodeCommand);
23
+ openVSCode(projectPath, VSCodeCommand, verbose);
23
24
  }
24
25
  }
25
26
 
26
- function openVSCode(projectPath: string, VSCodeCommand: string) {
27
+ function openVSCode(
28
+ projectPath: string,
29
+ VSCodeCommand: string,
30
+ verbose: boolean,
31
+ ) {
27
32
  const MAIN_TS_PATH = path.join(projectPath, "src", MAIN_TS);
28
- execShell(VSCodeCommand, [projectPath, MAIN_TS_PATH]);
33
+ execShell(VSCodeCommand, [projectPath, MAIN_TS_PATH], verbose);
29
34
  }
@@ -8,7 +8,7 @@ import {
8
8
  import * as file from "../../file";
9
9
  import { Config } from "../../types/Config";
10
10
 
11
- export function copyWatcherMod(config: Config): void {
11
+ export function copyWatcherMod(config: Config, verbose: boolean): void {
12
12
  // Check to see if this mod was disabled
13
13
  const watcherModPath = path.join(config.modsDirectory, WATCHER_MOD_NAME);
14
14
  const disableItPath = path.join(watcherModPath, DISABLE_IT_FILE);
@@ -17,21 +17,21 @@ export function copyWatcherMod(config: Config): void {
17
17
  // Delete and re-copy the watcher mod every time IsaacScript starts
18
18
  // This ensures that it is always the latest version
19
19
  if (file.exists(watcherModPath)) {
20
- file.deleteFileOrDirectory(watcherModPath);
20
+ file.deleteFileOrDirectory(watcherModPath, verbose);
21
21
  }
22
22
 
23
- file.copy(WATCHER_MOD_SOURCE_PATH, watcherModPath);
23
+ file.copy(WATCHER_MOD_SOURCE_PATH, watcherModPath, verbose);
24
24
 
25
25
  if (watcherModDisabled) {
26
26
  // Since we deleted the directory, the "disable.it" file was deleted
27
27
  // Restore it
28
- file.write(disableItPath, "");
28
+ file.write(disableItPath, "", verbose);
29
29
  }
30
30
 
31
31
  // By default, the IsaacScript watcher mod automatically restarts the game,
32
32
  // so we only need to disable it if the config option is explicitly set to false
33
33
  if (config.enableIsaacScriptWatcherAutoRestart === false) {
34
- disableIsaacScriptWatcherAutomaticRestart(watcherModPath);
34
+ disableIsaacScriptWatcherAutomaticRestart(watcherModPath, verbose);
35
35
  }
36
36
 
37
37
  // If we copied a new version of the watcher mod into place,
@@ -40,7 +40,10 @@ export function copyWatcherMod(config: Config): void {
40
40
  // so there is no automated solution for this
41
41
  }
42
42
 
43
- function disableIsaacScriptWatcherAutomaticRestart(watcherModPath: string) {
43
+ function disableIsaacScriptWatcherAutomaticRestart(
44
+ watcherModPath: string,
45
+ verbose: boolean,
46
+ ) {
44
47
  const mainLuaPath = path.join(watcherModPath, MAIN_LUA);
45
48
  const mainLua = file.read(mainLuaPath);
46
49
 
@@ -49,5 +52,5 @@ function disableIsaacScriptWatcherAutomaticRestart(watcherModPath: string) {
49
52
  "local RESTART_GAME_ON_RECOMPILATION = false",
50
53
  );
51
54
 
52
- file.write(mainLuaPath, modifiedMainLua);
55
+ file.write(mainLuaPath, modifiedMainLua, verbose);
53
56
  }
@@ -19,6 +19,8 @@ import { spawnSaveDatWriter } from "./spawnSaveDatWriter";
19
19
  import { touchWatcherSaveDatFiles } from "./touchWatcherSaveDatFiles";
20
20
 
21
21
  export function monitor(argv: Record<string, unknown>, config: Config): void {
22
+ const verbose = argv.verbose === true;
23
+
22
24
  // If they specified some command-line flags, override the values found in the config file
23
25
  if (argv.modsDirectory !== undefined) {
24
26
  config.modsDirectory = argv.modsDirectory as string; // eslint-disable-line no-param-reassign
@@ -34,13 +36,13 @@ export function monitor(argv: Record<string, unknown>, config: Config): void {
34
36
  const modTargetPath = path.join(config.modsDirectory, modTargetDirectoryName);
35
37
 
36
38
  // Prepare the IsaacScript watcher mod
37
- copyWatcherMod(config);
38
- touchWatcherSaveDatFiles(config);
39
+ copyWatcherMod(config, verbose);
40
+ touchWatcherSaveDatFiles(config, verbose);
39
41
 
40
42
  // Delete and re-copy the mod every time IsaacScript starts
41
43
  // This ensures that it is always the latest version
42
44
  if (file.exists(modTargetPath)) {
43
- file.deleteFileOrDirectory(modTargetPath);
45
+ file.deleteFileOrDirectory(modTargetPath, true);
44
46
  }
45
47
 
46
48
  // Subprocess #1 - The "save#.dat" file writer
@@ -27,7 +27,7 @@ function init() {
27
27
  // Check to see if the data directory exists
28
28
  const watcherModDataPath = path.dirname(saveDatPath);
29
29
  if (!file.exists(watcherModDataPath)) {
30
- file.makeDir(watcherModDataPath);
30
+ file.makeDir(watcherModDataPath, false);
31
31
  }
32
32
 
33
33
  // Listen for messages from the parent process
@@ -3,15 +3,18 @@ import { WATCHER_MOD_NAME } from "../../constants";
3
3
  import * as file from "../../file";
4
4
  import { Config } from "../../types/Config";
5
5
 
6
- export function touchWatcherSaveDatFiles(config: Config): void {
6
+ export function touchWatcherSaveDatFiles(
7
+ config: Config,
8
+ verbose: boolean,
9
+ ): void {
7
10
  const modsDataPath = path.join(config.modsDirectory, "..", "data");
8
11
  const watcherModDataPath = path.join(modsDataPath, WATCHER_MOD_NAME);
9
12
  if (!file.exists(watcherModDataPath)) {
10
- file.makeDir(watcherModDataPath);
13
+ file.makeDir(watcherModDataPath, verbose);
11
14
  }
12
15
  const saveDatFileName = `save${config.saveSlot}.dat`;
13
16
  const saveDatPath = path.join(watcherModDataPath, saveDatFileName);
14
17
  if (!file.exists(saveDatPath)) {
15
- file.touch(saveDatPath);
18
+ file.touch(saveDatPath, verbose);
16
19
  }
17
20
  }
@@ -12,15 +12,10 @@ import {
12
12
  PUBLISH_PRE_COPY_PY_PATH,
13
13
  VERSION_TXT_PATH,
14
14
  } from "../../constants";
15
+ import { execExe, execShell } from "../../exec";
15
16
  import * as file from "../../file";
16
17
  import { Config } from "../../types/Config";
17
- import {
18
- error,
19
- execExe,
20
- execShell,
21
- getModTargetDirectoryName,
22
- parseIntSafe,
23
- } from "../../util";
18
+ import { error, getModTargetDirectoryName, parseIntSafe } from "../../util";
24
19
  import { compileAndCopy } from "../copy/copy";
25
20
 
26
21
  const UPDATE_SCRIPT_NAME = "update.sh";
@@ -30,6 +25,7 @@ export function publish(argv: Record<string, unknown>, config: Config): void {
30
25
  const setVersion = argv.setVersion as string | undefined;
31
26
  const dryRun = argv.dryRun === true;
32
27
  const onlyUpload = argv.onlyUpload === true;
28
+ const verbose = argv.verbose === true;
33
29
 
34
30
  const modTargetDirectoryName = getModTargetDirectoryName(config);
35
31
  const modTargetPath = path.join(config.modsDirectory, modTargetDirectoryName);
@@ -43,7 +39,7 @@ export function publish(argv: Record<string, unknown>, config: Config): void {
43
39
  }
44
40
 
45
41
  if (onlyUpload) {
46
- uploadMod(modTargetPath, config.steamCmdPath);
42
+ uploadMod(modTargetPath, config.steamCmdPath, verbose);
47
43
  return;
48
44
  }
49
45
 
@@ -54,6 +50,7 @@ export function publish(argv: Record<string, unknown>, config: Config): void {
54
50
  setVersion,
55
51
  config.steamCmdPath,
56
52
  dryRun,
53
+ verbose,
57
54
  );
58
55
  }
59
56
 
@@ -64,42 +61,43 @@ function startPublish(
64
61
  setVersion: string | undefined,
65
62
  steamCmdPath: string | undefined,
66
63
  dryRun: boolean,
64
+ verbose: boolean,
67
65
  ) {
68
- updateDeps();
66
+ updateDeps(verbose);
69
67
 
70
68
  let version =
71
69
  setVersion === undefined ? getVersionFromPackageJSON() : setVersion;
72
70
  if (!skipVersionIncrement && setVersion === undefined) {
73
- version = bumpVersionInPackageJSON(version);
71
+ version = bumpVersionInPackageJSON(version, verbose);
74
72
  } else if (setVersion !== undefined) {
75
- writeVersionInPackageJSON(version);
73
+ writeVersionInPackageJSON(version, verbose);
76
74
  }
77
75
 
78
- writeVersionToConstantsTS(version);
79
- writeVersionToMetadataXML(version);
80
- writeVersionToVersionTXT(version);
81
- runReleaseScriptPreCopy();
82
- compileAndCopy(modSourcePath, modTargetPath);
83
- purgeRoomXMLs(modTargetPath);
84
- runReleaseScriptPostCopy();
76
+ writeVersionToConstantsTS(version, verbose);
77
+ writeVersionToMetadataXML(version, verbose);
78
+ writeVersionToVersionTXT(version, verbose);
79
+ runReleaseScriptPreCopy(verbose);
80
+ compileAndCopy(modSourcePath, modTargetPath, verbose);
81
+ purgeRoomXMLs(modTargetPath, verbose);
82
+ runReleaseScriptPostCopy(verbose);
85
83
 
86
84
  if (!dryRun) {
87
- gitCommitIfChanges(version);
88
- uploadMod(modTargetPath, steamCmdPath);
85
+ gitCommitIfChanges(version, verbose);
86
+ uploadMod(modTargetPath, steamCmdPath, verbose);
89
87
  }
90
88
 
91
89
  const dryRunSuffix = dryRun ? " (dry run)" : "";
92
90
  console.log(`\nPublished version ${version} successfully${dryRunSuffix}.`);
93
91
  }
94
92
 
95
- function updateDeps() {
93
+ function updateDeps(verbose: boolean) {
96
94
  if (!file.exists(UPDATE_SCRIPT_NAME)) {
97
95
  error(
98
96
  `The "${UPDATE_SCRIPT_NAME}" script does not exist in the current working directory.`,
99
97
  );
100
98
  }
101
99
 
102
- execShell("bash", [UPDATE_SCRIPT_NAME]);
100
+ execShell("bash", [UPDATE_SCRIPT_NAME], verbose);
103
101
  }
104
102
 
105
103
  function getVersionFromPackageJSON() {
@@ -138,7 +136,7 @@ function getVersionFromPackageJSON() {
138
136
  return packageJSON.version;
139
137
  }
140
138
 
141
- function bumpVersionInPackageJSON(version: string): string {
139
+ function bumpVersionInPackageJSON(version: string, verbose: boolean): string {
142
140
  // Get the patch version (i.e. the third number)
143
141
  const matches = /(\d+\.\d+\.)(\d+)/.exec(version);
144
142
  if (matches === null) {
@@ -168,7 +166,7 @@ function bumpVersionInPackageJSON(version: string): string {
168
166
  /"version": ".+",/,
169
167
  `"version": "${incrementedVersion}",`,
170
168
  );
171
- file.write(PACKAGE_JSON_PATH, newPackageJSON);
169
+ file.write(PACKAGE_JSON_PATH, newPackageJSON, verbose);
172
170
 
173
171
  console.log(
174
172
  `The version of ${incrementedVersion} was written to: ${PACKAGE_JSON_PATH}`,
@@ -177,18 +175,18 @@ function bumpVersionInPackageJSON(version: string): string {
177
175
  return incrementedVersion;
178
176
  }
179
177
 
180
- function writeVersionInPackageJSON(version: string) {
178
+ function writeVersionInPackageJSON(version: string, verbose: boolean) {
181
179
  const packageJSON = file.read(PACKAGE_JSON_PATH);
182
180
  const newPackageJSON = packageJSON.replace(
183
181
  /"version": ".+",/,
184
182
  `"version": "${version}",`,
185
183
  );
186
- file.write(PACKAGE_JSON_PATH, newPackageJSON);
184
+ file.write(PACKAGE_JSON_PATH, newPackageJSON, verbose);
187
185
 
188
186
  console.log(`The version of ${version} was written to: ${PACKAGE_JSON_PATH}`);
189
187
  }
190
188
 
191
- function writeVersionToConstantsTS(version: string) {
189
+ function writeVersionToConstantsTS(version: string, verbose: boolean) {
192
190
  if (!file.exists(CONSTANTS_TS_PATH)) {
193
191
  console.log(
194
192
  'Skipping writing the version to "constants.ts" since it was not found.',
@@ -201,63 +199,64 @@ function writeVersionToConstantsTS(version: string) {
201
199
  /const VERSION = ".+"/,
202
200
  `const VERSION = "${version}"`,
203
201
  );
204
- file.write(CONSTANTS_TS_PATH, newConstantsTS);
202
+ file.write(CONSTANTS_TS_PATH, newConstantsTS, verbose);
205
203
 
206
204
  console.log(`The version of ${version} was written to: ${CONSTANTS_TS_PATH}`);
207
205
  }
208
206
 
209
- function writeVersionToMetadataXML(version: string) {
207
+ function writeVersionToMetadataXML(version: string, verbose: boolean) {
210
208
  const metadataXML = file.read(METADATA_XML_PATH);
211
209
  const newMetadataXML = metadataXML.replace(
212
210
  /<version>.+<\/version>/,
213
211
  `<version>${version}</version>`,
214
212
  );
215
- file.write(METADATA_XML_PATH, newMetadataXML);
213
+ file.write(METADATA_XML_PATH, newMetadataXML, verbose);
216
214
 
217
215
  console.log(`The version of ${version} was written to: ${METADATA_XML_PATH}`);
218
216
  }
219
217
 
220
- function writeVersionToVersionTXT(version: string) {
221
- file.write(VERSION_TXT_PATH, version);
218
+ function writeVersionToVersionTXT(version: string, verbose: boolean) {
219
+ file.write(VERSION_TXT_PATH, version, verbose);
222
220
 
223
221
  console.log(`The version of ${version} was written to: ${VERSION_TXT_PATH}`);
224
222
  }
225
223
 
226
- function runReleaseScriptPreCopy() {
224
+ function runReleaseScriptPreCopy(verbose: boolean) {
227
225
  if (!file.exists(PUBLISH_PRE_COPY_PY_PATH)) {
228
226
  return;
229
227
  }
230
228
 
231
229
  console.log(`Running the "${PUBLISH_PRE_COPY_PY_PATH}" script.`);
232
- let [, stdout] = execShell("python", [PUBLISH_PRE_COPY_PY_PATH]);
230
+ let [, stdout] = execShell("python", [PUBLISH_PRE_COPY_PY_PATH], verbose);
233
231
  stdout = stdout.trim();
234
232
  if (stdout.length > 0) {
235
233
  console.log(stdout);
236
234
  }
237
235
  }
238
236
 
239
- function runReleaseScriptPostCopy() {
237
+ function runReleaseScriptPostCopy(verbose: boolean) {
240
238
  if (!file.exists(PUBLISH_POST_COPY_PY_PATH)) {
241
239
  return;
242
240
  }
243
241
 
244
242
  console.log(`Running the "${PUBLISH_POST_COPY_PY_PATH}" script.`);
245
- let [, stdout] = execShell("python", [PUBLISH_POST_COPY_PY_PATH]);
243
+ let [, stdout] = execShell("python", [PUBLISH_POST_COPY_PY_PATH], verbose);
246
244
  stdout = stdout.trim();
247
245
  if (stdout.length > 0) {
248
246
  console.log(stdout);
249
247
  }
250
248
  }
251
249
 
252
- function gitCommitIfChanges(version: string) {
250
+ function gitCommitIfChanges(version: string, verbose: boolean) {
253
251
  // Throw an error if this is not a git repository
254
- execShell("git", ["status"]);
252
+ execShell("git", ["status"], verbose);
255
253
 
256
254
  // Check to see if there are any changes
257
255
  // https://stackoverflow.com/questions/3878624/how-do-i-programmatically-determine-if-there-are-uncommitted-changes
258
256
  const [exitCode] = execShell(
259
257
  "git",
260
258
  ["diff-index", "--quiet", "HEAD", "--"],
259
+ verbose,
261
260
  true,
262
261
  );
263
262
  if (exitCode === 0) {
@@ -267,16 +266,16 @@ function gitCommitIfChanges(version: string) {
267
266
  }
268
267
 
269
268
  const commitMessage = `v${version}`;
270
- execShell("git", ["add", "-A"]);
271
- execShell("git", ["commit", "-m", commitMessage]);
272
- execShell("git", ["push"]);
269
+ execShell("git", ["add", "-A"], verbose);
270
+ execShell("git", ["commit", "-m", commitMessage], verbose);
271
+ execShell("git", ["push"], verbose);
273
272
 
274
273
  console.log(
275
274
  `Committed and pushed to the git repository with a message of: ${commitMessage}`,
276
275
  );
277
276
  }
278
277
 
279
- function purgeRoomXMLs(modTargetPath: string) {
278
+ function purgeRoomXMLs(modTargetPath: string, verbose: boolean) {
280
279
  const roomsPath = path.join(modTargetPath, "resources", "rooms");
281
280
  if (!file.exists(roomsPath) || !file.isDir(roomsPath)) {
282
281
  return;
@@ -286,25 +285,33 @@ function purgeRoomXMLs(modTargetPath: string) {
286
285
  roomFileList.forEach((fileName: string) => {
287
286
  if (path.extname(fileName) === ".xml") {
288
287
  const roomFilePath = path.join(roomsPath, fileName);
289
- file.deleteFileOrDirectory(roomFilePath);
288
+ file.deleteFileOrDirectory(roomFilePath, verbose);
290
289
  }
291
290
  });
292
291
  }
293
292
 
294
- function uploadMod(modTargetPath: string, steamCmdPath: string | undefined) {
293
+ function uploadMod(
294
+ modTargetPath: string,
295
+ steamCmdPath: string | undefined,
296
+ verbose: boolean,
297
+ ) {
295
298
  if (steamCmdPath === undefined) {
296
299
  console.log(
297
300
  `The "steamCmdPath" property was not found in the "${chalk.green(
298
301
  CONFIG_FILE_NAME,
299
302
  )}" file; assuming that we want to use the ModUploader tool.`,
300
303
  );
301
- execExe(MOD_UPLOADER_PATH, modTargetPath);
304
+ execExe(MOD_UPLOADER_PATH, verbose, modTargetPath);
302
305
  } else {
303
- runSteamCmd(modTargetPath, steamCmdPath);
306
+ runSteamCmd(modTargetPath, steamCmdPath, verbose);
304
307
  }
305
308
  }
306
309
 
307
- function runSteamCmd(modTargetPath: string, steamCmdPath: string) {
310
+ function runSteamCmd(
311
+ modTargetPath: string,
312
+ steamCmdPath: string,
313
+ verbose: boolean,
314
+ ) {
308
315
  if (!file.exists(steamCmdPath)) {
309
316
  error(
310
317
  chalk.red(
@@ -347,14 +354,18 @@ function runSteamCmd(modTargetPath: string, steamCmdPath: string) {
347
354
 
348
355
  console.log("Uploading the mod to the Steam Workshop...");
349
356
 
350
- execShell(steamCmdPath, [
351
- "+login",
352
- username,
353
- password,
354
- "+workshop_build_item",
355
- metadataVDFPath,
356
- "+quit",
357
- ]);
357
+ execShell(
358
+ steamCmdPath,
359
+ [
360
+ "+login",
361
+ username,
362
+ password,
363
+ "+workshop_build_item",
364
+ metadataVDFPath,
365
+ "+quit",
366
+ ],
367
+ verbose,
368
+ );
358
369
 
359
370
  console.log("Mod uploaded successfully.");
360
371
  }
package/src/configFile.ts CHANGED
@@ -9,6 +9,8 @@ import { Config } from "./types/Config";
9
9
  import { error } from "./util";
10
10
 
11
11
  export async function get(argv: Record<string, unknown>): Promise<Config> {
12
+ const verbose = argv.verbose === true;
13
+
12
14
  const existingConfig = readExistingConfig();
13
15
  if (existingConfig !== null) {
14
16
  return existingConfig;
@@ -18,7 +20,7 @@ export async function get(argv: Record<string, unknown>): Promise<Config> {
18
20
  const modsDirectory = await getModsDir(argv);
19
21
  const saveSlot = await promptSaveSlot(argv);
20
22
  const config = createObject(modsDirectory, saveSlot);
21
- createFile(CWD, config);
23
+ createFile(CWD, config, verbose);
22
24
 
23
25
  return config;
24
26
  }
@@ -66,8 +68,12 @@ export function createObject(modsDirectory: string, saveSlot: number): Config {
66
68
  };
67
69
  }
68
70
 
69
- export function createFile(projectPath: string, config: Config): void {
71
+ export function createFile(
72
+ projectPath: string,
73
+ config: Config,
74
+ verbose: boolean,
75
+ ): void {
70
76
  const configFilePath = path.join(projectPath, CONFIG_FILE_NAME);
71
77
  const configContents = JSON.stringify(config, null, 2);
72
- file.write(configFilePath, configContents);
78
+ file.write(configFilePath, configContents, verbose);
73
79
  }
package/src/exec.ts ADDED
@@ -0,0 +1,102 @@
1
+ import chalk from "chalk";
2
+ import { execSync, spawnSync, SpawnSyncReturns } from "child_process";
3
+ import { CWD } from "./constants";
4
+ import { error } from "./util";
5
+
6
+ export function execExe(path: string, verbose = false, cwd = CWD): string {
7
+ if (verbose) {
8
+ console.log(`Executing binary: ${path}`);
9
+ }
10
+
11
+ let stdout: string;
12
+ try {
13
+ const buffer = execSync(`"${path}"`, {
14
+ cwd,
15
+ });
16
+ stdout = buffer.toString().trim();
17
+ } catch (err) {
18
+ error(`Failed to run "${chalk.green(path)}":`, err);
19
+ }
20
+
21
+ if (verbose) {
22
+ console.log(`Executed binary: ${path}`);
23
+ }
24
+
25
+ return stdout;
26
+ }
27
+
28
+ /** Returns an array of exit status and stdout. */
29
+ export function execShell(
30
+ command: string,
31
+ args: string[] = [],
32
+ verbose = false,
33
+ allowFailure = false,
34
+ cwd = CWD,
35
+ ): [number, string] {
36
+ // On Windows, "spawnSync()" will not account for spaces in arguments
37
+ // Thus, wrap everything in a double quote
38
+ // This will cause arguments that naturally have double quotes to fail
39
+ if (command.includes('"')) {
40
+ error(
41
+ "execShell cannot execute commands with double quotes in the command.",
42
+ );
43
+ }
44
+ for (let i = 0; i < args.length; i++) {
45
+ if (args[i].includes('"')) {
46
+ error(
47
+ "execShell cannot execute commands with double quotes in the arguments.",
48
+ );
49
+ }
50
+
51
+ args[i] = `"${args[i]}"`; // eslint-disable-line no-param-reassign
52
+ }
53
+
54
+ const commandDescription = `${command} ${args.join(" ")}`.trim();
55
+
56
+ if (verbose) {
57
+ console.log(`Executing command: ${commandDescription}`);
58
+ }
59
+
60
+ let spawnSyncReturns: SpawnSyncReturns<Buffer>;
61
+ try {
62
+ spawnSyncReturns = spawnSync(command, args, {
63
+ shell: true,
64
+ cwd,
65
+ });
66
+ } catch (err) {
67
+ error(
68
+ `Failed to run the "${chalk.green(commandDescription)}" command:`,
69
+ err,
70
+ );
71
+ }
72
+
73
+ if (verbose) {
74
+ console.log(`Executed command: ${commandDescription}`);
75
+ }
76
+
77
+ const exitStatus = spawnSyncReturns.status;
78
+ if (exitStatus === null) {
79
+ error(
80
+ `Failed to get the return status of th command: ${commandDescription}`,
81
+ );
82
+ }
83
+
84
+ const stdout = spawnSyncReturns.output.join("\n").trim();
85
+
86
+ if (exitStatus !== 0) {
87
+ if (allowFailure) {
88
+ return [exitStatus, stdout];
89
+ }
90
+
91
+ console.error(
92
+ `Failed to run the "${chalk.green(
93
+ commandDescription,
94
+ )}" command with an exit code of ${exitStatus}.`,
95
+ );
96
+ console.error("The output was as follows:");
97
+ console.error(stdout);
98
+ process.exit(1);
99
+ }
100
+
101
+ return [exitStatus, stdout];
102
+ }