isaacscript 1.2.28 → 1.2.31
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/dist/package.json +2 -2
- package/dist/src/checkForWindowsTerminalBugs.js +7 -7
- package/dist/src/checkForWindowsTerminalBugs.js.map +1 -1
- package/dist/src/commands/copy/copy.js +1 -1
- package/dist/src/commands/copy/copy.js.map +1 -1
- package/dist/src/commands/init/checkIfProjectPathExists.js +14 -8
- package/dist/src/commands/init/checkIfProjectPathExists.js.map +1 -1
- package/dist/src/commands/init/checkModSubdirectory.js +2 -2
- package/dist/src/commands/init/checkModSubdirectory.js.map +1 -1
- package/dist/src/commands/init/checkModTargetDirectory.js +13 -7
- package/dist/src/commands/init/checkModTargetDirectory.js.map +1 -1
- package/dist/src/commands/init/createMod.js +27 -24
- package/dist/src/commands/init/createMod.js.map +1 -1
- package/dist/src/commands/init/getModsDir.js +5 -4
- package/dist/src/commands/init/getModsDir.js.map +1 -1
- package/dist/src/commands/init/getProjectPath.js +16 -12
- package/dist/src/commands/init/getProjectPath.js.map +1 -1
- package/dist/src/commands/init/git.js +22 -13
- package/dist/src/commands/init/git.js.map +1 -1
- package/dist/src/commands/init/init.js +10 -7
- package/dist/src/commands/init/init.js.map +1 -1
- package/dist/src/commands/init/installVSCodeExtensions.js +4 -4
- package/dist/src/commands/init/installVSCodeExtensions.js.map +1 -1
- package/dist/src/commands/init/promptSaveSlot.js +4 -1
- package/dist/src/commands/init/promptSaveSlot.js.map +1 -1
- package/dist/src/commands/monitor/copyWatcherMod.js +3 -3
- package/dist/src/commands/monitor/copyWatcherMod.js.map +1 -1
- package/dist/src/commands/monitor/getTSConfigInclude.js +2 -2
- package/dist/src/commands/monitor/getTSConfigInclude.js.map +1 -1
- package/dist/src/commands/monitor/monitor.js +2 -2
- package/dist/src/commands/monitor/monitor.js.map +1 -1
- package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js +13 -12
- package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js.map +1 -1
- package/dist/src/commands/monitor/touchWatcherSaveDatFiles.js +2 -2
- package/dist/src/commands/monitor/touchWatcherSaveDatFiles.js.map +1 -1
- package/dist/src/commands/publish/publish.js +16 -16
- package/dist/src/commands/publish/publish.js.map +1 -1
- package/dist/src/configFile.js +7 -6
- package/dist/src/configFile.js.map +1 -1
- package/dist/src/exec.js +2 -2
- package/dist/src/exec.js.map +1 -1
- package/dist/src/file.js +37 -7
- package/dist/src/file.js.map +1 -1
- package/dist/src/main.js +5 -4
- package/dist/src/main.js.map +1 -1
- package/dist/src/parseArgs.js +5 -0
- package/dist/src/parseArgs.js.map +1 -1
- package/dist/src/utils.js +7 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/src/validateInIsaacScriptProject.js +3 -2
- package/dist/src/validateInIsaacScriptProject.js.map +1 -1
- package/package.json +2 -2
- package/src/checkForWindowsTerminalBugs.ts +9 -7
- package/src/commands/copy/copy.ts +1 -1
- package/src/commands/init/checkIfProjectPathExists.ts +19 -12
- package/src/commands/init/checkModSubdirectory.ts +2 -2
- package/src/commands/init/checkModTargetDirectory.ts +18 -12
- package/src/commands/init/createMod.ts +47 -37
- package/src/commands/init/getModsDir.ts +7 -3
- package/src/commands/init/getProjectPath.ts +19 -12
- package/src/commands/init/git.ts +34 -18
- package/src/commands/init/init.ts +14 -6
- package/src/commands/init/installVSCodeExtensions.ts +4 -4
- package/src/commands/init/promptSaveSlot.ts +5 -0
- package/src/commands/monitor/copyWatcherMod.ts +3 -3
- package/src/commands/monitor/getTSConfigInclude.ts +2 -2
- package/src/commands/monitor/monitor.ts +2 -2
- package/src/commands/monitor/saveDatWriter/saveDatWriter.ts +14 -12
- package/src/commands/monitor/touchWatcherSaveDatFiles.ts +2 -2
- package/src/commands/publish/publish.ts +16 -16
- package/src/configFile.ts +7 -6
- package/src/exec.ts +2 -4
- package/src/file.ts +51 -7
- package/src/main.ts +5 -4
- package/src/parseArgs.ts +6 -0
- package/src/utils.ts +8 -0
- package/src/validateInIsaacScriptProject.ts +5 -2
|
@@ -2,7 +2,7 @@ import chalk from "chalk";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { CURRENT_DIRECTORY_NAME, CWD } from "../../constants";
|
|
4
4
|
import { getInputString, getInputYesNo } from "../../prompt";
|
|
5
|
-
import { hasWhiteSpace } from "../../utils";
|
|
5
|
+
import { error, hasWhiteSpace, isKebabCase } from "../../utils";
|
|
6
6
|
|
|
7
7
|
// From: https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3
|
|
8
8
|
const ILLEGAL_CHARACTERS_FOR_WINDOWS_FILENAMES = [
|
|
@@ -19,11 +19,13 @@ const ILLEGAL_CHARACTERS_FOR_WINDOWS_FILENAMES = [
|
|
|
19
19
|
|
|
20
20
|
export async function getProjectPath(
|
|
21
21
|
argv: Record<string, unknown>,
|
|
22
|
+
useCurrentDir: boolean,
|
|
23
|
+
yes: boolean,
|
|
22
24
|
): Promise<[string, boolean]> {
|
|
23
25
|
let projectName = getProjectNameFromCommandLineArgument(argv);
|
|
24
26
|
let projectPath: string;
|
|
25
27
|
let createNewDir: boolean;
|
|
26
|
-
if (
|
|
28
|
+
if (useCurrentDir) {
|
|
27
29
|
// The "--use-current-dir" command-line flag was specified,
|
|
28
30
|
// so there is no need to prompt the user
|
|
29
31
|
projectName = CURRENT_DIRECTORY_NAME;
|
|
@@ -33,14 +35,18 @@ export async function getProjectPath(
|
|
|
33
35
|
// The project name was specified on the command-line
|
|
34
36
|
projectPath = path.join(CWD, projectName);
|
|
35
37
|
createNewDir = true;
|
|
38
|
+
} else if (yes) {
|
|
39
|
+
// The "--yes" command-line flag was specified and the project name was not specified on the
|
|
40
|
+
// command-line, so default to using the current directory
|
|
41
|
+
projectName = CURRENT_DIRECTORY_NAME;
|
|
42
|
+
projectPath = CWD;
|
|
43
|
+
createNewDir = false;
|
|
36
44
|
} else {
|
|
37
45
|
// The project name was not specified on the command-line, so prompt the user for it
|
|
38
46
|
[projectName, projectPath, createNewDir] = await getNewProjectName();
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
49
|
+
validateProjectName(projectName);
|
|
44
50
|
|
|
45
51
|
console.log(`Using a project name of: ${chalk.green(projectName)}`);
|
|
46
52
|
return [projectPath, createNewDir];
|
|
@@ -74,27 +80,28 @@ async function getNewProjectName(): Promise<[string, string, boolean]> {
|
|
|
74
80
|
|
|
75
81
|
function validateProjectName(projectName: string) {
|
|
76
82
|
if (projectName === "") {
|
|
77
|
-
|
|
78
|
-
return false;
|
|
83
|
+
error("Error: You cannot have a blank project name.");
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
if (process.platform === "win32") {
|
|
82
87
|
for (const character of ILLEGAL_CHARACTERS_FOR_WINDOWS_FILENAMES) {
|
|
83
88
|
if (projectName.includes(character)) {
|
|
84
|
-
|
|
89
|
+
error(
|
|
85
90
|
`Error: The "${character}" character is not allowed in a Windows file name.`,
|
|
86
91
|
);
|
|
87
|
-
return false;
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
if (hasWhiteSpace(projectName)) {
|
|
93
|
-
|
|
97
|
+
error(
|
|
94
98
|
'Error: The project name has whitespace in it, which is not allowed. Use kebab-case for your project name. (e.g. "green-candle")',
|
|
95
99
|
);
|
|
96
|
-
return false;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
if (!isKebabCase(projectName)) {
|
|
103
|
+
error(
|
|
104
|
+
"Error: The project name is not in kebab-case. (Kebab-case is the style of using all lowercase letters, with words separated by hyphens.) Project names must use kebab-case to match GitHub repository standards.",
|
|
105
|
+
);
|
|
106
|
+
}
|
|
100
107
|
}
|
package/src/commands/init/git.ts
CHANGED
|
@@ -14,6 +14,7 @@ const REQUIRED_GIT_MINOR_VERSION = 30;
|
|
|
14
14
|
|
|
15
15
|
export async function promptGitHubRepoOrGitRemoteURL(
|
|
16
16
|
projectName: string,
|
|
17
|
+
yes: boolean,
|
|
17
18
|
verbose: boolean,
|
|
18
19
|
): Promise<string | undefined> {
|
|
19
20
|
// We do not need to prompt the user if they do not have Git installed
|
|
@@ -26,7 +27,7 @@ export async function promptGitHubRepoOrGitRemoteURL(
|
|
|
26
27
|
|
|
27
28
|
validateNewGitVersion(verbose);
|
|
28
29
|
|
|
29
|
-
const gitHubUsername = getGitHubUsername();
|
|
30
|
+
const gitHubUsername = getGitHubUsername(verbose);
|
|
30
31
|
if (gitHubUsername !== undefined) {
|
|
31
32
|
const [exitStatus] = execShell(
|
|
32
33
|
"gh",
|
|
@@ -42,6 +43,14 @@ export async function promptGitHubRepoOrGitRemoteURL(
|
|
|
42
43
|
`Detected an existing GitHub repository at: ${chalk.green(url)}`,
|
|
43
44
|
);
|
|
44
45
|
const guessedRemoteURL = getGitRemoteURL(projectName, gitHubUsername);
|
|
46
|
+
|
|
47
|
+
if (yes) {
|
|
48
|
+
console.log(
|
|
49
|
+
`Using a Git remote URL of: ${chalk.green(guessedRemoteURL)}`,
|
|
50
|
+
);
|
|
51
|
+
return guessedRemoteURL;
|
|
52
|
+
}
|
|
53
|
+
|
|
45
54
|
const shouldUseGuessedURL = await getInputYesNo(
|
|
46
55
|
`Do you want to use a Git remote URL of: ${chalk.green(
|
|
47
56
|
guessedRemoteURL,
|
|
@@ -52,23 +61,29 @@ export async function promptGitHubRepoOrGitRemoteURL(
|
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
// Assume that since they do not want to connect this project to the existing GitHub
|
|
55
|
-
// repository, they do not want to initialize Git
|
|
64
|
+
// repository, they do not want to initialize a remote Git URL at all
|
|
56
65
|
return undefined;
|
|
57
66
|
}
|
|
58
67
|
|
|
68
|
+
if (yes) {
|
|
69
|
+
execShell("gh", ["repo", "create", projectName, "--public"]);
|
|
70
|
+
console.log(`Created a new GitHub repository at: ${chalk.green(url)}`);
|
|
71
|
+
return getGitRemoteURL(projectName, gitHubUsername);
|
|
72
|
+
}
|
|
73
|
+
|
|
59
74
|
const createNewGitHubRepo = await getInputYesNo(
|
|
60
75
|
`Would you like to create a new GitHub repository at: ${chalk.green(
|
|
61
76
|
url,
|
|
62
77
|
)}`,
|
|
63
78
|
);
|
|
64
79
|
if (createNewGitHubRepo) {
|
|
65
|
-
execShell("gh", ["repo", "create",
|
|
80
|
+
execShell("gh", ["repo", "create", projectName, "--public"]);
|
|
66
81
|
console.log("Successfully created a new GitHub repository.");
|
|
67
82
|
return getGitRemoteURL(projectName, gitHubUsername);
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
// Assume that since they do not want to create a new GitHub repository, they do not want to
|
|
71
|
-
// initialize Git
|
|
86
|
+
// initialize a remote Git URL at all
|
|
72
87
|
return undefined;
|
|
73
88
|
}
|
|
74
89
|
|
|
@@ -116,7 +131,7 @@ function validateNewGitVersion(verbose: boolean) {
|
|
|
116
131
|
process.exit(1);
|
|
117
132
|
}
|
|
118
133
|
|
|
119
|
-
function getGitHubUsername() {
|
|
134
|
+
function getGitHubUsername(verbose: boolean) {
|
|
120
135
|
// If the GitHub CLI is installed, we can derive the user's GitHub username
|
|
121
136
|
if (
|
|
122
137
|
!commandExists.sync("gh") ||
|
|
@@ -131,11 +146,11 @@ function getGitHubUsername() {
|
|
|
131
146
|
"GitHub CLI",
|
|
132
147
|
"hosts.yml",
|
|
133
148
|
);
|
|
134
|
-
if (!file.exists(githubCLIHostsPath)) {
|
|
149
|
+
if (!file.exists(githubCLIHostsPath, verbose)) {
|
|
135
150
|
return undefined;
|
|
136
151
|
}
|
|
137
152
|
|
|
138
|
-
const configYAMLRaw = file.read(githubCLIHostsPath);
|
|
153
|
+
const configYAMLRaw = file.read(githubCLIHostsPath, verbose);
|
|
139
154
|
const configYAML = yaml.parse(configYAMLRaw) as GitHubCLIHostsYAML;
|
|
140
155
|
|
|
141
156
|
const githubCom = configYAML["github.com"];
|
|
@@ -144,7 +159,7 @@ function getGitHubUsername() {
|
|
|
144
159
|
}
|
|
145
160
|
|
|
146
161
|
const { user } = githubCom;
|
|
147
|
-
if (user === "") {
|
|
162
|
+
if (user === undefined || user === "") {
|
|
148
163
|
return undefined;
|
|
149
164
|
}
|
|
150
165
|
|
|
@@ -160,21 +175,12 @@ export function initGitRepository(
|
|
|
160
175
|
gitRemoteURL: string | undefined,
|
|
161
176
|
verbose: boolean,
|
|
162
177
|
): void {
|
|
163
|
-
|
|
164
|
-
// process
|
|
165
|
-
if (gitRemoteURL === undefined) {
|
|
178
|
+
if (!commandExists.sync("git")) {
|
|
166
179
|
return;
|
|
167
180
|
}
|
|
168
181
|
|
|
169
182
|
execShell("git", ["init"], verbose, false, projectPath);
|
|
170
183
|
execShell("git", ["branch", "-M", "main"], verbose, false, projectPath);
|
|
171
|
-
execShell(
|
|
172
|
-
"git",
|
|
173
|
-
["remote", "add", "origin", gitRemoteURL],
|
|
174
|
-
verbose,
|
|
175
|
-
false,
|
|
176
|
-
projectPath,
|
|
177
|
-
);
|
|
178
184
|
|
|
179
185
|
if (isGitNameAndEmailConfigured(verbose)) {
|
|
180
186
|
execShell("git", ["add", "--all"], verbose, false, projectPath);
|
|
@@ -186,6 +192,16 @@ export function initGitRepository(
|
|
|
186
192
|
projectPath,
|
|
187
193
|
);
|
|
188
194
|
}
|
|
195
|
+
|
|
196
|
+
if (gitRemoteURL !== undefined) {
|
|
197
|
+
execShell(
|
|
198
|
+
"git",
|
|
199
|
+
["remote", "add", "origin", gitRemoteURL],
|
|
200
|
+
verbose,
|
|
201
|
+
false,
|
|
202
|
+
projectPath,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
189
205
|
}
|
|
190
206
|
|
|
191
207
|
function isGitNameAndEmailConfigured(verbose: boolean) {
|
|
@@ -14,23 +14,31 @@ import { promptSaveSlot } from "./promptSaveSlot";
|
|
|
14
14
|
import { promptVSCode } from "./promptVSCode";
|
|
15
15
|
|
|
16
16
|
export async function init(argv: Record<string, unknown>): Promise<void> {
|
|
17
|
-
const vscode = argv.vscode === true;
|
|
18
17
|
const skipNPMInstall = argv.skipNpmInstall === true;
|
|
18
|
+
const useCurrentDir = argv.useCurrentDir === true;
|
|
19
19
|
const verbose = argv.verbose === true;
|
|
20
|
+
const vscode = argv.vscode === true;
|
|
21
|
+
const yes = argv.yes === true;
|
|
20
22
|
|
|
21
23
|
// Prompt the end-user for some information (and validate it as we go)
|
|
22
|
-
const [projectPath, createNewDir] = await getProjectPath(
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
const [projectPath, createNewDir] = await getProjectPath(
|
|
25
|
+
argv,
|
|
26
|
+
useCurrentDir,
|
|
27
|
+
yes,
|
|
28
|
+
);
|
|
29
|
+
await checkIfProjectPathExists(projectPath, yes, verbose);
|
|
30
|
+
const modsDirectory = await getModsDir(argv, verbose);
|
|
25
31
|
checkModSubdirectory(projectPath, modsDirectory);
|
|
26
32
|
const projectName = path.basename(projectPath);
|
|
27
|
-
await checkModTargetDirectory(modsDirectory, projectName, verbose);
|
|
28
|
-
const saveSlot = await promptSaveSlot(argv);
|
|
33
|
+
await checkModTargetDirectory(modsDirectory, projectName, yes, verbose);
|
|
34
|
+
const saveSlot = await promptSaveSlot(argv, yes);
|
|
29
35
|
const gitRemoteURL = await promptGitHubRepoOrGitRemoteURL(
|
|
30
36
|
projectName,
|
|
37
|
+
yes,
|
|
31
38
|
verbose,
|
|
32
39
|
);
|
|
33
40
|
|
|
41
|
+
// Now that we have asked the user all of the questions we need, we can create the project
|
|
34
42
|
createMod(
|
|
35
43
|
projectName,
|
|
36
44
|
projectPath,
|
|
@@ -10,7 +10,7 @@ export function installVSCodeExtensions(
|
|
|
10
10
|
VSCodeCommand: string,
|
|
11
11
|
verbose: boolean,
|
|
12
12
|
): void {
|
|
13
|
-
const extensions = getExtensionsFromJSON(projectPath);
|
|
13
|
+
const extensions = getExtensionsFromJSON(projectPath, verbose);
|
|
14
14
|
for (const extensionName of extensions) {
|
|
15
15
|
execShell(VSCodeCommand, ["--install-extension", extensionName], verbose);
|
|
16
16
|
}
|
|
@@ -20,18 +20,18 @@ interface ExtensionsJSON {
|
|
|
20
20
|
recommendations: string[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function getExtensionsFromJSON(projectPath: string) {
|
|
23
|
+
function getExtensionsFromJSON(projectPath: string, verbose: boolean) {
|
|
24
24
|
const extensionsJSONPath = path.join(
|
|
25
25
|
projectPath,
|
|
26
26
|
".vscode",
|
|
27
27
|
"extensions.json",
|
|
28
28
|
);
|
|
29
29
|
|
|
30
|
-
if (!file.exists(extensionsJSONPath)) {
|
|
30
|
+
if (!file.exists(extensionsJSONPath, verbose)) {
|
|
31
31
|
return [];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const extensionsJSONRaw = file.read(extensionsJSONPath);
|
|
34
|
+
const extensionsJSONRaw = file.read(extensionsJSONPath, verbose);
|
|
35
35
|
|
|
36
36
|
let extensionsJSON: ExtensionsJSON;
|
|
37
37
|
try {
|
|
@@ -3,6 +3,7 @@ import { error } from "../../utils";
|
|
|
3
3
|
|
|
4
4
|
export async function promptSaveSlot(
|
|
5
5
|
argv: Record<string, unknown>,
|
|
6
|
+
yes: boolean,
|
|
6
7
|
): Promise<number> {
|
|
7
8
|
if (argv.saveSlot !== undefined) {
|
|
8
9
|
// They specified the "--save-slot" command-line flag,
|
|
@@ -10,6 +11,10 @@ export async function promptSaveSlot(
|
|
|
10
11
|
return argv.saveSlot as number;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
if (yes) {
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
const saveSlot = await getInputInt(
|
|
14
19
|
"In-game, will you test your mod on save slot 1, 2, or 3?",
|
|
15
20
|
);
|
|
@@ -12,11 +12,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);
|
|
15
|
-
const watcherModDisabled = file.exists(disableItPath);
|
|
15
|
+
const watcherModDisabled = file.exists(disableItPath, verbose);
|
|
16
16
|
|
|
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
|
-
if (file.exists(watcherModPath)) {
|
|
19
|
+
if (file.exists(watcherModPath, verbose)) {
|
|
20
20
|
file.deleteFileOrDirectory(watcherModPath, verbose);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -45,7 +45,7 @@ function disableIsaacScriptWatcherAutomaticRestart(
|
|
|
45
45
|
verbose: boolean,
|
|
46
46
|
) {
|
|
47
47
|
const mainLuaPath = path.join(watcherModPath, MAIN_LUA);
|
|
48
|
-
const mainLua = file.read(mainLuaPath);
|
|
48
|
+
const mainLua = file.read(mainLuaPath, verbose);
|
|
49
49
|
|
|
50
50
|
const modifiedMainLua = mainLua.replace(
|
|
51
51
|
"local RESTART_GAME_ON_RECOMPILATION = true",
|
|
@@ -4,8 +4,8 @@ import { TSCONFIG_PATH } from "../../constants";
|
|
|
4
4
|
import * as file from "../../file";
|
|
5
5
|
import { error } from "../../utils";
|
|
6
6
|
|
|
7
|
-
export function getTSConfigInclude(): string {
|
|
8
|
-
const tsConfigRaw = file.read(TSCONFIG_PATH);
|
|
7
|
+
export function getTSConfigInclude(verbose: boolean): string {
|
|
8
|
+
const tsConfigRaw = file.read(TSCONFIG_PATH, verbose);
|
|
9
9
|
let tsConfig: Record<string, string[]>;
|
|
10
10
|
try {
|
|
11
11
|
tsConfig = JSONC.parse(tsConfigRaw) as Record<string, string[]>;
|
|
@@ -29,7 +29,7 @@ export function monitor(argv: Record<string, unknown>, config: Config): void {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Read the "tsconfig.json" file
|
|
32
|
-
const tsConfigInclude = getTSConfigInclude();
|
|
32
|
+
const tsConfigInclude = getTSConfigInclude(verbose);
|
|
33
33
|
const resolvedIncludePath = path.resolve(CWD, tsConfigInclude);
|
|
34
34
|
const modTargetDirectoryName = getModTargetDirectoryName(config);
|
|
35
35
|
const modTargetPath = path.join(config.modsDirectory, modTargetDirectoryName);
|
|
@@ -40,7 +40,7 @@ export function monitor(argv: Record<string, unknown>, config: Config): void {
|
|
|
40
40
|
|
|
41
41
|
// Delete and re-copy the mod every time IsaacScript starts
|
|
42
42
|
// This ensures that it is always the latest version
|
|
43
|
-
if (file.exists(modTargetPath)) {
|
|
43
|
+
if (file.exists(modTargetPath, verbose)) {
|
|
44
44
|
file.deleteFileOrDirectory(modTargetPath, true);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -7,14 +7,15 @@ import { ensureAllCases, error } from "../../../utils";
|
|
|
7
7
|
import { SaveDatMessage, SaveDatMessageType } from "./types";
|
|
8
8
|
|
|
9
9
|
const MAX_MESSAGES = 100;
|
|
10
|
+
const VERBOSE = false;
|
|
10
11
|
|
|
11
12
|
let saveDatPath: string;
|
|
12
13
|
let saveDatFileName: string;
|
|
13
14
|
|
|
14
|
-
init();
|
|
15
|
+
init(VERBOSE);
|
|
15
16
|
|
|
16
|
-
function init() {
|
|
17
|
-
const numArgs =
|
|
17
|
+
function init(verbose: boolean) {
|
|
18
|
+
const numArgs = 2;
|
|
18
19
|
if (process.argv.length !== 2 + numArgs) {
|
|
19
20
|
throw new Error(
|
|
20
21
|
"The Save.dat writer process did not get the right amount of arguments.",
|
|
@@ -26,8 +27,8 @@ function init() {
|
|
|
26
27
|
|
|
27
28
|
// Check to see if the data directory exists
|
|
28
29
|
const watcherModDataPath = path.dirname(saveDatPath);
|
|
29
|
-
if (!file.exists(watcherModDataPath)) {
|
|
30
|
-
file.makeDir(watcherModDataPath,
|
|
30
|
+
if (!file.exists(watcherModDataPath, verbose)) {
|
|
31
|
+
file.makeDir(watcherModDataPath, verbose);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// Listen for messages from the parent process
|
|
@@ -37,7 +38,7 @@ function init() {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
function onMessage(type: SaveDatMessageType, data: string, numRetries = 0) {
|
|
40
|
-
const saveDat = readSaveDatFromDisk();
|
|
41
|
+
const saveDat = readSaveDatFromDisk(VERBOSE);
|
|
41
42
|
if (saveDat.length > MAX_MESSAGES) {
|
|
42
43
|
// If IsaacScript is running and
|
|
43
44
|
// 1) the game is not open
|
|
@@ -50,13 +51,13 @@ function onMessage(type: SaveDatMessageType, data: string, numRetries = 0) {
|
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
addMessageToSaveDat(type, saveDat, data); // Mutates saveDat
|
|
53
|
-
writeSaveDatToDisk(type, data, saveDat, numRetries);
|
|
54
|
+
writeSaveDatToDisk(type, data, saveDat, numRetries, VERBOSE);
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function readSaveDatFromDisk() {
|
|
57
|
+
function readSaveDatFromDisk(verbose: boolean) {
|
|
57
58
|
let saveDat: SaveDatMessage[];
|
|
58
|
-
if (file.exists(saveDatPath)) {
|
|
59
|
-
const saveDatRaw = file.read(saveDatPath);
|
|
59
|
+
if (file.exists(saveDatPath, verbose)) {
|
|
60
|
+
const saveDatRaw = file.read(saveDatPath, verbose);
|
|
60
61
|
try {
|
|
61
62
|
saveDat = JSONC.parse(saveDatRaw) as SaveDatMessage[];
|
|
62
63
|
} catch (err) {
|
|
@@ -111,11 +112,12 @@ function writeSaveDatToDisk(
|
|
|
111
112
|
type: SaveDatMessageType,
|
|
112
113
|
data: string,
|
|
113
114
|
saveDat: SaveDatMessage[],
|
|
114
|
-
numRetries
|
|
115
|
+
numRetries: number,
|
|
116
|
+
verbose: boolean,
|
|
115
117
|
) {
|
|
116
118
|
const saveDatRaw = JSON.stringify(saveDat, null, 2);
|
|
117
119
|
try {
|
|
118
|
-
file.writeTry(saveDatPath, saveDatRaw);
|
|
120
|
+
file.writeTry(saveDatPath, saveDatRaw, verbose);
|
|
119
121
|
} catch (err) {
|
|
120
122
|
if (numRetries > 4) {
|
|
121
123
|
console.error(
|
|
@@ -9,12 +9,12 @@ export function touchWatcherSaveDatFiles(
|
|
|
9
9
|
): void {
|
|
10
10
|
const modsDataPath = path.join(config.modsDirectory, "..", "data");
|
|
11
11
|
const watcherModDataPath = path.join(modsDataPath, WATCHER_MOD_NAME);
|
|
12
|
-
if (!file.exists(watcherModDataPath)) {
|
|
12
|
+
if (!file.exists(watcherModDataPath, verbose)) {
|
|
13
13
|
file.makeDir(watcherModDataPath, verbose);
|
|
14
14
|
}
|
|
15
15
|
const saveDatFileName = `save${config.saveSlot}.dat`;
|
|
16
16
|
const saveDatPath = path.join(watcherModDataPath, saveDatFileName);
|
|
17
|
-
if (!file.exists(saveDatPath)) {
|
|
17
|
+
if (!file.exists(saveDatPath, verbose)) {
|
|
18
18
|
file.touch(saveDatPath, verbose);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -109,7 +109,7 @@ function startPublish(
|
|
|
109
109
|
updateDeps(verbose);
|
|
110
110
|
|
|
111
111
|
let version =
|
|
112
|
-
setVersion === undefined ? getVersionFromPackageJSON() : setVersion;
|
|
112
|
+
setVersion === undefined ? getVersionFromPackageJSON(verbose) : setVersion;
|
|
113
113
|
if (!skipVersionIncrement && setVersion === undefined) {
|
|
114
114
|
version = bumpVersionInPackageJSON(version, verbose);
|
|
115
115
|
} else if (setVersion !== undefined) {
|
|
@@ -134,7 +134,7 @@ function startPublish(
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function updateDeps(verbose: boolean) {
|
|
137
|
-
if (!file.exists(UPDATE_SCRIPT_NAME)) {
|
|
137
|
+
if (!file.exists(UPDATE_SCRIPT_NAME, verbose)) {
|
|
138
138
|
error(
|
|
139
139
|
`The "${UPDATE_SCRIPT_NAME}" script does not exist in the current working directory.`,
|
|
140
140
|
);
|
|
@@ -143,8 +143,8 @@ function updateDeps(verbose: boolean) {
|
|
|
143
143
|
execShell("bash", [UPDATE_SCRIPT_NAME], verbose);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
function getVersionFromPackageJSON() {
|
|
147
|
-
if (!file.exists(PACKAGE_JSON_PATH)) {
|
|
146
|
+
function getVersionFromPackageJSON(verbose: boolean) {
|
|
147
|
+
if (!file.exists(PACKAGE_JSON_PATH, verbose)) {
|
|
148
148
|
error(
|
|
149
149
|
chalk.red(
|
|
150
150
|
`A "${PACKAGE_JSON_PATH}" was not found in the current directory.`,
|
|
@@ -152,7 +152,7 @@ function getVersionFromPackageJSON() {
|
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
const packageJSONRaw = file.read(PACKAGE_JSON_PATH);
|
|
155
|
+
const packageJSONRaw = file.read(PACKAGE_JSON_PATH, verbose);
|
|
156
156
|
let packageJSON: Record<string, unknown>;
|
|
157
157
|
try {
|
|
158
158
|
packageJSON = JSON.parse(packageJSONRaw) as Record<string, unknown>;
|
|
@@ -204,7 +204,7 @@ function bumpVersionInPackageJSON(version: string, verbose: boolean): string {
|
|
|
204
204
|
const incrementedPatchVersion = patchVersion + 1;
|
|
205
205
|
const incrementedVersion = `${versionPrefix}${incrementedPatchVersion}`;
|
|
206
206
|
|
|
207
|
-
const packageJSON = file.read(PACKAGE_JSON_PATH);
|
|
207
|
+
const packageJSON = file.read(PACKAGE_JSON_PATH, verbose);
|
|
208
208
|
const newPackageJSON = packageJSON.replace(
|
|
209
209
|
/"version": ".+",/,
|
|
210
210
|
`"version": "${incrementedVersion}",`,
|
|
@@ -219,7 +219,7 @@ function bumpVersionInPackageJSON(version: string, verbose: boolean): string {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
function writeVersionInPackageJSON(version: string, verbose: boolean) {
|
|
222
|
-
const packageJSON = file.read(PACKAGE_JSON_PATH);
|
|
222
|
+
const packageJSON = file.read(PACKAGE_JSON_PATH, verbose);
|
|
223
223
|
const newPackageJSON = packageJSON.replace(
|
|
224
224
|
/"version": ".+",/,
|
|
225
225
|
`"version": "${version}",`,
|
|
@@ -230,14 +230,14 @@ function writeVersionInPackageJSON(version: string, verbose: boolean) {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
function writeVersionToConstantsTS(version: string, verbose: boolean) {
|
|
233
|
-
if (!file.exists(CONSTANTS_TS_PATH)) {
|
|
233
|
+
if (!file.exists(CONSTANTS_TS_PATH, verbose)) {
|
|
234
234
|
console.log(
|
|
235
235
|
'Skipping writing the version to "constants.ts" since it was not found.',
|
|
236
236
|
);
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
const constantsTS = file.read(CONSTANTS_TS_PATH);
|
|
240
|
+
const constantsTS = file.read(CONSTANTS_TS_PATH, verbose);
|
|
241
241
|
const newConstantsTS = constantsTS.replace(
|
|
242
242
|
/const VERSION = ".+"/,
|
|
243
243
|
`const VERSION = "${version}"`,
|
|
@@ -248,7 +248,7 @@ function writeVersionToConstantsTS(version: string, verbose: boolean) {
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
function writeVersionToMetadataXML(version: string, verbose: boolean) {
|
|
251
|
-
const metadataXML = file.read(METADATA_XML_PATH);
|
|
251
|
+
const metadataXML = file.read(METADATA_XML_PATH, verbose);
|
|
252
252
|
const newMetadataXML = metadataXML.replace(
|
|
253
253
|
/<version>.+<\/version>/,
|
|
254
254
|
`<version>${version}</version>`,
|
|
@@ -265,7 +265,7 @@ function writeVersionToVersionTXT(version: string, verbose: boolean) {
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
function runReleaseScriptPreCopy(verbose: boolean) {
|
|
268
|
-
if (!file.exists(PUBLISH_PRE_COPY_PY_PATH)) {
|
|
268
|
+
if (!file.exists(PUBLISH_PRE_COPY_PY_PATH, verbose)) {
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -278,7 +278,7 @@ function runReleaseScriptPreCopy(verbose: boolean) {
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
function runReleaseScriptPostCopy(verbose: boolean) {
|
|
281
|
-
if (!file.exists(PUBLISH_POST_COPY_PY_PATH)) {
|
|
281
|
+
if (!file.exists(PUBLISH_POST_COPY_PY_PATH, verbose)) {
|
|
282
282
|
return;
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -292,11 +292,11 @@ function runReleaseScriptPostCopy(verbose: boolean) {
|
|
|
292
292
|
|
|
293
293
|
function purgeRoomXMLs(modTargetPath: string, verbose: boolean) {
|
|
294
294
|
const roomsPath = path.join(modTargetPath, "resources", "rooms");
|
|
295
|
-
if (!file.exists(roomsPath) || !file.isDir(roomsPath)) {
|
|
295
|
+
if (!file.exists(roomsPath, verbose) || !file.isDir(roomsPath, verbose)) {
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
const roomFileList = file.getDirList(roomsPath);
|
|
299
|
+
const roomFileList = file.getDirList(roomsPath, verbose);
|
|
300
300
|
roomFileList.forEach((fileName: string) => {
|
|
301
301
|
if (path.extname(fileName) === ".xml") {
|
|
302
302
|
const roomFilePath = path.join(roomsPath, fileName);
|
|
@@ -327,7 +327,7 @@ function runSteamCmd(
|
|
|
327
327
|
steamCmdPath: string,
|
|
328
328
|
verbose: boolean,
|
|
329
329
|
) {
|
|
330
|
-
if (!file.exists(steamCmdPath)) {
|
|
330
|
+
if (!file.exists(steamCmdPath, verbose)) {
|
|
331
331
|
error(
|
|
332
332
|
chalk.red(
|
|
333
333
|
`The path provided for "steamCmdPath" is "${steamCmdPath}", but that does not exist.`,
|
|
@@ -336,7 +336,7 @@ function runSteamCmd(
|
|
|
336
336
|
}
|
|
337
337
|
|
|
338
338
|
const metadataVDFPath = path.join(modTargetPath, "metadata.vdf");
|
|
339
|
-
if (!file.exists(metadataVDFPath)) {
|
|
339
|
+
if (!file.exists(metadataVDFPath, verbose)) {
|
|
340
340
|
console.error(
|
|
341
341
|
chalk.red(
|
|
342
342
|
`A "metadata.vdf" file was not found in your mod directory. You must create this file in order for "steamcmd.exe" to work. Please see the ${PROJECT_NAME} docs:`,
|
package/src/configFile.ts
CHANGED
|
@@ -10,27 +10,28 @@ import { error } from "./utils";
|
|
|
10
10
|
|
|
11
11
|
export async function get(argv: Record<string, unknown>): Promise<Config> {
|
|
12
12
|
const verbose = argv.verbose === true;
|
|
13
|
+
const yes = argv.yes === true;
|
|
13
14
|
|
|
14
|
-
const existingConfig = readExistingConfig();
|
|
15
|
+
const existingConfig = readExistingConfig(verbose);
|
|
15
16
|
if (existingConfig !== undefined) {
|
|
16
17
|
return existingConfig;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
// No config file exists, so prompt the user for some information and create one
|
|
20
|
-
const modsDirectory = await getModsDir(argv);
|
|
21
|
-
const saveSlot = await promptSaveSlot(argv);
|
|
21
|
+
const modsDirectory = await getModsDir(argv, verbose);
|
|
22
|
+
const saveSlot = await promptSaveSlot(argv, yes);
|
|
22
23
|
const config = createObject(modsDirectory, saveSlot);
|
|
23
24
|
createFile(CWD, config, verbose);
|
|
24
25
|
|
|
25
26
|
return config;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
function readExistingConfig(): Config | undefined {
|
|
29
|
-
if (!file.exists(CONFIG_FILE_PATH)) {
|
|
29
|
+
function readExistingConfig(verbose: boolean): Config | undefined {
|
|
30
|
+
if (!file.exists(CONFIG_FILE_PATH, verbose)) {
|
|
30
31
|
return undefined;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
const configRaw = file.read(CONFIG_FILE_PATH);
|
|
34
|
+
const configRaw = file.read(CONFIG_FILE_PATH, verbose);
|
|
34
35
|
let config: Config;
|
|
35
36
|
try {
|
|
36
37
|
config = JSONC.parse(configRaw) as Config;
|
package/src/exec.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { execSync, spawnSync, SpawnSyncReturns } from "child_process";
|
|
|
3
3
|
import { CWD } from "./constants";
|
|
4
4
|
import { error } from "./utils";
|
|
5
5
|
|
|
6
|
-
export function execExe(path: string, verbose
|
|
6
|
+
export function execExe(path: string, verbose: boolean, cwd = CWD): string {
|
|
7
7
|
if (verbose) {
|
|
8
8
|
console.log(`Executing binary: ${path}`);
|
|
9
9
|
}
|
|
@@ -103,9 +103,7 @@ export function execShell(
|
|
|
103
103
|
|
|
104
104
|
const exitStatus = spawnSyncReturns.status;
|
|
105
105
|
if (exitStatus === null) {
|
|
106
|
-
error(
|
|
107
|
-
`Failed to get the return status of th command: ${commandDescription}`,
|
|
108
|
-
);
|
|
106
|
+
error(`Failed to get the return status of command: ${commandDescription}`);
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
const stdout = spawnSyncReturns.output.join("\n").trim();
|