hackmud-script-manager 0.20.3 → 0.20.4-03d5600
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 +5 -1
- package/bin/hsm.js +172 -234
- package/env.d.ts +709 -1293
- package/generateTypeDeclaration.js +2 -1
- package/index.js +1 -0
- package/package.json +6 -2
- package/processScript/index.js +1 -1
- package/processScript/minify.js +18 -21
- package/processScript/postprocess.d.ts +1 -1
- package/processScript/postprocess.js +3 -3
- package/processScript/transform.js +53 -40
- package/push.d.ts +9 -1
- package/push.js +33 -11
- package/syncMacros.js +1 -1
- package/watch.js +1 -0
package/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Hackmud Script Manager
|
2
|
-
Command made for [
|
2
|
+
Command made for [Hackmud Scripting Environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
|
3
|
+
|
4
|
+
[](https://ko-fi.com/R6R0XN5CX)
|
5
|
+
|
6
|
+
You can read about how HSM works [in my blog post](https://samual.uk/blog/js-code-transformation-niche-environment/).
|
3
7
|
|
4
8
|
## Install
|
5
9
|
1. [Install Node.js](https://nodejs.org/en/download)
|
package/bin/hsm.js
CHANGED
@@ -5,14 +5,15 @@ import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
|
5
5
|
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
6
6
|
import { writeFile, readFile } from "fs/promises"
|
7
7
|
import { homedir } from "os"
|
8
|
-
import { extname, basename,
|
8
|
+
import { resolve, extname, basename, dirname, relative } from "path"
|
9
9
|
import { supportedExtensions } from "../constants.js"
|
10
10
|
import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
|
11
11
|
import { pull } from "../pull.js"
|
12
12
|
import { syncMacros } from "../syncMacros.js"
|
13
13
|
import "@samual/lib/readDirectoryWithStats"
|
14
|
+
import "path/posix"
|
14
15
|
import "@samual/lib/copyFilePersistent"
|
15
|
-
const version = "0.20.
|
16
|
+
const version = "0.20.4-03d5600",
|
16
17
|
options = new Map(),
|
17
18
|
commands = [],
|
18
19
|
userColours = new Cache(user => {
|
@@ -36,10 +37,6 @@ for (const argument of process.argv.slice(2))
|
|
36
37
|
if ("-" == argument[1]) options.set(key.slice(2), value)
|
37
38
|
else for (const option of key.slice(1)) options.set(option, value)
|
38
39
|
} else commands.push(argument)
|
39
|
-
if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
|
40
|
-
console.log(version)
|
41
|
-
process.exit()
|
42
|
-
}
|
43
40
|
const pushModule = import("../push.js"),
|
44
41
|
processScriptModule = import("../processScript/index.js"),
|
45
42
|
watchModule = import("../watch.js"),
|
@@ -57,153 +54,163 @@ const pushModule = import("../push.js"),
|
|
57
54
|
colourS = chalk.rgb(122, 178, 244),
|
58
55
|
colourV = chalk.rgb(255, 0, 236),
|
59
56
|
colourW = chalk.rgb(255, 150, 224)
|
60
|
-
if (
|
57
|
+
if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
|
58
|
+
console.log(version)
|
59
|
+
process.exit()
|
60
|
+
}
|
61
|
+
if (popOption("help", "h")?.value) {
|
61
62
|
logHelp()
|
62
63
|
process.exit()
|
63
64
|
}
|
64
65
|
let autoExit = !0
|
65
66
|
switch (commands[0]) {
|
66
67
|
case "push":
|
68
|
+
case "dev":
|
69
|
+
case "watch":
|
70
|
+
case "golf":
|
71
|
+
case "minify":
|
67
72
|
{
|
68
|
-
const
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
break
|
74
|
-
}
|
75
|
-
const scripts = commands.slice(2)
|
76
|
-
if (scripts.length) {
|
77
|
-
const invalidScript = scripts.find(
|
78
|
-
script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script)
|
79
|
-
)
|
80
|
-
if (invalidScript) {
|
81
|
-
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`)
|
82
|
-
logHelp()
|
83
|
-
break
|
84
|
-
}
|
85
|
-
} else scripts.push("*.*")
|
86
|
-
const optionsHasNoMinify = options.has("no-minify")
|
87
|
-
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
73
|
+
const noMinifyOption = popOption("no-minify", "skip-minify"),
|
74
|
+
mangleNamesOption = popOption("mangle-names"),
|
75
|
+
forceQuineCheatsOption = popOption("force-quine-cheats"),
|
76
|
+
noMinifyIncompatibleOption = mangleNamesOption || forceQuineCheatsOption
|
77
|
+
if (noMinifyOption && noMinifyIncompatibleOption) {
|
88
78
|
logError(
|
89
|
-
`Options ${colourN(
|
79
|
+
`Options ${colourN(noMinifyOption.name)} and ${colourN(noMinifyIncompatibleOption.name)} are incompatible\n`
|
90
80
|
)
|
91
81
|
logHelp()
|
92
|
-
|
82
|
+
process.exit(1)
|
93
83
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
84
|
+
noMinifyOption && assertOptionIsBoolean(noMinifyOption)
|
85
|
+
mangleNamesOption && assertOptionIsBoolean(mangleNamesOption)
|
86
|
+
forceQuineCheatsOption && assertOptionIsBoolean(forceQuineCheatsOption)
|
87
|
+
if ("golf" == commands[0] || "minify" == commands[0]) {
|
88
|
+
const watchOption = popOption("watch"),
|
89
|
+
target = commands[1]
|
90
|
+
if (!target) {
|
91
|
+
logError("Must provide target\n")
|
92
|
+
logHelp()
|
93
|
+
process.exit(1)
|
94
|
+
}
|
95
|
+
const fileExtension = extname(target)
|
96
|
+
if (!supportedExtensions.includes(fileExtension)) {
|
98
97
|
logError(
|
99
|
-
`
|
98
|
+
`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join('", "')}"`
|
100
99
|
)
|
101
|
-
|
102
|
-
break
|
100
|
+
process.exit(1)
|
103
101
|
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
if (
|
150
|
-
|
102
|
+
const { processScript } = await processScriptModule,
|
103
|
+
fileBaseName = basename(target, fileExtension),
|
104
|
+
fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
|
105
|
+
scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
|
106
|
+
scriptUser =
|
107
|
+
(
|
108
|
+
"scripts" == basename(resolve(target, "..")) &&
|
109
|
+
"hackmud" == basename(resolve(target, "../../.."))
|
110
|
+
) ?
|
111
|
+
basename(resolve(target, "../.."))
|
112
|
+
: void 0
|
113
|
+
let outputPath =
|
114
|
+
commands[2] ||
|
115
|
+
resolve(
|
116
|
+
dirname(target),
|
117
|
+
fileBaseNameEndsWithDotSrc ? scriptName + ".js"
|
118
|
+
: ".js" == fileExtension ? fileBaseName + ".min.js"
|
119
|
+
: fileBaseName + ".js"
|
120
|
+
)
|
121
|
+
const golfFile = () =>
|
122
|
+
readFile(target, { encoding: "utf8" }).then(async source => {
|
123
|
+
const timeStart = performance.now(),
|
124
|
+
{ script, warnings } = await processScript(source, {
|
125
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
126
|
+
scriptUser,
|
127
|
+
scriptName,
|
128
|
+
filePath: target,
|
129
|
+
mangleNames: mangleNamesOption?.value,
|
130
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
131
|
+
}),
|
132
|
+
timeTook = performance.now() - timeStart
|
133
|
+
for (const { message, line } of warnings)
|
134
|
+
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
135
|
+
await writeFilePersistent(outputPath, script)
|
136
|
+
.catch(error => {
|
137
|
+
if (!commands[2] || "EISDIR" != error.code) throw error
|
138
|
+
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
139
|
+
return writeFilePersistent(outputPath, script)
|
140
|
+
})
|
141
|
+
.then(() =>
|
142
|
+
log(
|
143
|
+
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
144
|
+
)
|
145
|
+
)
|
146
|
+
})
|
147
|
+
if (watchOption) {
|
148
|
+
const { watch: watchFile } = await chokidarModule
|
149
|
+
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
150
|
+
.on("ready", () => log("Watching " + target))
|
151
|
+
.on("change", golfFile)
|
152
|
+
autoExit = !1
|
153
|
+
} else await golfFile()
|
154
|
+
} else {
|
155
|
+
const hackmudPath = getHackmudPath(),
|
156
|
+
sourcePath = commands[1]
|
157
|
+
if (!sourcePath) {
|
158
|
+
logError(`Must provide the directory to ${"push" == commands[0] ? "push from" : "watch"}\n`)
|
151
159
|
logHelp()
|
152
|
-
|
160
|
+
process.exit(1)
|
153
161
|
}
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
159
|
-
)
|
160
|
-
logHelp()
|
161
|
-
break
|
162
|
-
}
|
163
|
-
const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
|
164
|
-
let shouldMinify
|
165
|
-
if (null != shouldSkipMinify) {
|
166
|
-
if ("boolean" != typeof shouldSkipMinify) {
|
167
|
-
logError(
|
168
|
-
`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
162
|
+
const scripts = commands.slice(2)
|
163
|
+
if (scripts.length) {
|
164
|
+
const invalidScript = scripts.find(
|
165
|
+
script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script)
|
169
166
|
)
|
170
|
-
|
171
|
-
|
167
|
+
if (invalidScript) {
|
168
|
+
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`)
|
169
|
+
logHelp()
|
170
|
+
process.exit(1)
|
171
|
+
}
|
172
|
+
} else scripts.push("*.*")
|
173
|
+
if ("push" == commands[0]) {
|
174
|
+
const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } =
|
175
|
+
await pushModule,
|
176
|
+
infos = await push(sourcePath, hackmudPath, {
|
177
|
+
scripts,
|
178
|
+
onPush: info => logInfo(info, hackmudPath),
|
179
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
180
|
+
mangleNames: mangleNamesOption?.value,
|
181
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
182
|
+
})
|
183
|
+
if (infos instanceof Error) {
|
184
|
+
logError(infos.message)
|
185
|
+
if (infos instanceof MissingSourceFolderError || infos instanceof NoUsersError) {
|
186
|
+
console.log()
|
187
|
+
logHelp()
|
188
|
+
} else
|
189
|
+
infos instanceof MissingHackmudFolderError &&
|
190
|
+
log(
|
191
|
+
`If this is not where your hackmud folder is, you can specify it with the\n${colourN("--hackmud-path")}=${colourB("<path>")} option or ${colourN("HSM_HACKMUD_PATH")} environment variable`
|
192
|
+
)
|
193
|
+
} else infos.length || logError("Could not find any scripts to push")
|
194
|
+
} else {
|
195
|
+
const typeDeclarationPathOption = popOption(
|
196
|
+
"type-declaration-path",
|
197
|
+
"type-declaration",
|
198
|
+
"dts",
|
199
|
+
"gen-types"
|
200
|
+
),
|
201
|
+
{ watch } = await watchModule
|
202
|
+
watch(sourcePath, hackmudPath, {
|
203
|
+
scripts,
|
204
|
+
onPush: info => logInfo(info, hackmudPath),
|
205
|
+
typeDeclarationPath: typeDeclarationPathOption?.value.toString(),
|
206
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
207
|
+
mangleNames: mangleNamesOption?.value,
|
208
|
+
onReady: () => log("Watching"),
|
209
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
210
|
+
})
|
211
|
+
autoExit = !1
|
172
212
|
}
|
173
|
-
shouldMinify = !shouldSkipMinify
|
174
213
|
}
|
175
|
-
const shouldMangleNames = options.get("mangle-names")
|
176
|
-
if (null != shouldMangleNames && "boolean" != typeof shouldMangleNames) {
|
177
|
-
logError(
|
178
|
-
`The value for ${colourN("--mangle-names")} must be ${colourV("true")} or ${colourV("false")}\n`
|
179
|
-
)
|
180
|
-
logHelp()
|
181
|
-
break
|
182
|
-
}
|
183
|
-
const shouldforceQuineCheats = options.get("force-quine-cheats")
|
184
|
-
if (null != shouldforceQuineCheats && "boolean" != typeof shouldforceQuineCheats) {
|
185
|
-
logError(
|
186
|
-
`The value for ${colourN("--force-quine-cheats")} must be ${colourV("true")} or ${colourV("false")}\n`
|
187
|
-
)
|
188
|
-
logHelp()
|
189
|
-
break
|
190
|
-
}
|
191
|
-
const { watch } = await watchModule
|
192
|
-
watch(sourcePath, hackmudPath, {
|
193
|
-
scripts,
|
194
|
-
onPush: info => logInfo(info, hackmudPath),
|
195
|
-
typeDeclarationPath: (
|
196
|
-
options.get("type-declaration-path") ||
|
197
|
-
options.get("type-declaration") ||
|
198
|
-
options.get("dts") ||
|
199
|
-
options.get("gen-types")
|
200
|
-
)?.toString(),
|
201
|
-
minify: shouldMinify,
|
202
|
-
mangleNames: shouldMangleNames,
|
203
|
-
onReady: () => log("Watching"),
|
204
|
-
forceQuineCheats: shouldforceQuineCheats
|
205
|
-
})
|
206
|
-
autoExit = !1
|
207
214
|
}
|
208
215
|
break
|
209
216
|
case "pull":
|
@@ -213,7 +220,7 @@ switch (commands[0]) {
|
|
213
220
|
if (!script) {
|
214
221
|
logError("Must provide the script to pull\n")
|
215
222
|
logHelp()
|
216
|
-
|
223
|
+
process.exit(1)
|
217
224
|
}
|
218
225
|
const sourcePath = commands[2] || "."
|
219
226
|
await pull(sourcePath, hackmudPath, script).catch(error => {
|
@@ -234,18 +241,19 @@ switch (commands[0]) {
|
|
234
241
|
case "gen-dts":
|
235
242
|
case "gen-types":
|
236
243
|
{
|
237
|
-
const
|
244
|
+
const hackmudPath = getHackmudPath(),
|
245
|
+
target = commands[1]
|
238
246
|
if (!target) {
|
239
247
|
logError("Must provide target directory\n")
|
240
248
|
logHelp()
|
241
|
-
|
249
|
+
process.exit(1)
|
242
250
|
}
|
243
251
|
const sourcePath = resolve(target),
|
244
252
|
outputPath = commands[2] || "./player.d.ts",
|
245
|
-
typeDeclaration = await generateTypeDeclaration(sourcePath,
|
253
|
+
typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
|
246
254
|
let typeDeclarationPath = resolve(outputPath)
|
247
255
|
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
248
|
-
assert(error instanceof Error, "src/bin/hsm.ts:
|
256
|
+
assert(error instanceof Error, "src/bin/hsm.ts:321:35")
|
249
257
|
if ("EISDIR" != error.code) throw error
|
250
258
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
251
259
|
return writeFile(typeDeclarationPath, typeDeclaration)
|
@@ -257,99 +265,6 @@ switch (commands[0]) {
|
|
257
265
|
case "h":
|
258
266
|
logHelp()
|
259
267
|
break
|
260
|
-
case "golf":
|
261
|
-
case "minify":
|
262
|
-
{
|
263
|
-
const target = commands[1]
|
264
|
-
if (!target) {
|
265
|
-
logError("Must provide target\n")
|
266
|
-
logHelp()
|
267
|
-
break
|
268
|
-
}
|
269
|
-
const fileExtension = extname(target)
|
270
|
-
if (!supportedExtensions.includes(fileExtension)) {
|
271
|
-
logError(
|
272
|
-
`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join('", "')}"`
|
273
|
-
)
|
274
|
-
break
|
275
|
-
}
|
276
|
-
const { processScript } = await processScriptModule,
|
277
|
-
fileBaseName = basename(target, fileExtension),
|
278
|
-
fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
|
279
|
-
scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
|
280
|
-
scriptUser =
|
281
|
-
"scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
|
282
|
-
basename(resolve(target, "../.."))
|
283
|
-
: void 0,
|
284
|
-
optionsHasNoMinify = options.has("no-minify")
|
285
|
-
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
286
|
-
logError(
|
287
|
-
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
288
|
-
)
|
289
|
-
logHelp()
|
290
|
-
break
|
291
|
-
}
|
292
|
-
const mangleNames_ = options.get("mangle-names")
|
293
|
-
if (null != mangleNames_ && "boolean" != typeof mangleNames_) {
|
294
|
-
logError(
|
295
|
-
`The value for ${colourN("--mangle-names")} must be ${colourV("true")} or ${colourV("false")}\n`
|
296
|
-
)
|
297
|
-
logHelp()
|
298
|
-
break
|
299
|
-
}
|
300
|
-
const mangleNames = mangleNames_,
|
301
|
-
forceQuineCheats_ = options.get("force-quine-cheats")
|
302
|
-
if (null != forceQuineCheats_ && "boolean" != typeof forceQuineCheats_) {
|
303
|
-
logError(
|
304
|
-
`the value for ${colourN("--force-quine-cheats")} must be ${colourV("true")} or ${colourV("false")}\n`
|
305
|
-
)
|
306
|
-
logHelp()
|
307
|
-
break
|
308
|
-
}
|
309
|
-
const forceQuineCheats = forceQuineCheats_
|
310
|
-
let outputPath =
|
311
|
-
commands[2] ||
|
312
|
-
resolve(
|
313
|
-
dirname(target),
|
314
|
-
fileBaseNameEndsWithDotSrc ? scriptName + ".js"
|
315
|
-
: ".js" == fileExtension ? fileBaseName + ".min.js"
|
316
|
-
: fileBaseName + ".js"
|
317
|
-
)
|
318
|
-
const golfFile = () =>
|
319
|
-
readFile(target, { encoding: "utf8" }).then(async source => {
|
320
|
-
const timeStart = performance.now(),
|
321
|
-
{ script, warnings } = await processScript(source, {
|
322
|
-
minify: !(options.get("no-minify") || options.get("skip-minify")),
|
323
|
-
scriptUser,
|
324
|
-
scriptName,
|
325
|
-
filePath: target,
|
326
|
-
mangleNames,
|
327
|
-
forceQuineCheats
|
328
|
-
}),
|
329
|
-
timeTook = performance.now() - timeStart
|
330
|
-
for (const { message, line } of warnings)
|
331
|
-
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
332
|
-
await writeFilePersistent(outputPath, script)
|
333
|
-
.catch(error => {
|
334
|
-
if (!commands[2] || "EISDIR" != error.code) throw error
|
335
|
-
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
336
|
-
return writeFilePersistent(outputPath, script)
|
337
|
-
})
|
338
|
-
.then(() =>
|
339
|
-
log(
|
340
|
-
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
341
|
-
)
|
342
|
-
)
|
343
|
-
})
|
344
|
-
if (options.get("watch")) {
|
345
|
-
const { watch: watchFile } = await chokidarModule
|
346
|
-
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
347
|
-
.on("ready", () => log("Watching " + target))
|
348
|
-
.on("change", golfFile)
|
349
|
-
autoExit = !1
|
350
|
-
} else await golfFile()
|
351
|
-
}
|
352
|
-
break
|
353
268
|
default:
|
354
269
|
commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
|
355
270
|
logHelp()
|
@@ -366,7 +281,7 @@ function logHelp() {
|
|
366
281
|
case "push":
|
367
282
|
console.log(
|
368
283
|
colourS(
|
369
|
-
`\n${colourJ("push" == commands[0] ? pushCommandDescription : "Watch a directory and push a script when modified")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB('<directory> ["<script user>.<script name>"...]')}\n\n${colourA("Arguments:")}\n${colourB("<directory>")}\n The source directory containing your scripts\n${colourB("<script user>")}\n A user to push script(s) to. Can be set to wild card (${colourV("*")}) which will try\n and discover users to push to\n${colourB("<script name>")}\n Name of a script to push. Can be set to wild card (${colourV("*")}) to find all scripts\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${hackmudPathOption}\n${"push" == commands[0] ? "" : `${colourN("--type-declaration-path")}=${colourB("<path>")}\n Path to generate a type declaration file for the scripts\n`}\n${colourA("Examples:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")}\n
|
284
|
+
`\n${colourJ("push" == commands[0] ? pushCommandDescription : "Watch a directory and push a script when modified")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB('<directory> ["<script user>.<script name>"...]')}\n\n${colourA("Arguments:")}\n${colourB("<directory>")}\n The source directory containing your scripts\n${colourB("<script user>")}\n A user to push script(s) to. Can be set to wild card (${colourV("*")}) which will try\n and discover users to push to\n${colourB("<script name>")}\n Name of a script to push. Can be set to wild card (${colourV("*")}) to find all scripts\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${hackmudPathOption}\n${"push" == commands[0] ? "" : `${colourN("--type-declaration-path")}=${colourB("<path>")}\n Path to generate a type declaration file for the scripts\n`}\n${colourA("Examples:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")}\n Pushes all scripts found in ${colourV("src")} folder to all users\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")}\n Pushes a script named ${colourL("bar")} found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")} ${colourC("baz")}${colourV(".")}${colourL("qux")}\n Multiple can be specified\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("*")}\n Pushes all scripts found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("foo")}\n Pushes all scripts named ${colourL("foo")} found in ${colourV("src")} folder to all user\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("*")}\n Pushes all scripts found in ${colourV("src")} folder to all users`
|
370
285
|
)
|
371
286
|
)
|
372
287
|
break
|
@@ -423,7 +338,7 @@ function logError(message) {
|
|
423
338
|
process.exitCode = 1
|
424
339
|
}
|
425
340
|
function getHackmudPath() {
|
426
|
-
const hackmudPathOption =
|
341
|
+
const hackmudPathOption = popOption("hackmud-path")
|
427
342
|
if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
|
428
343
|
logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
|
429
344
|
logHelp()
|
@@ -435,3 +350,26 @@ function getHackmudPath() {
|
|
435
350
|
("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
|
436
351
|
)
|
437
352
|
}
|
353
|
+
function assertOptionIsBoolean(option) {
|
354
|
+
if ("boolean" != typeof option.value) {
|
355
|
+
logError(`The value for ${colourN(option.name)} must be ${colourV("true")} or ${colourV("false")}\n`)
|
356
|
+
logHelp()
|
357
|
+
process.exit(1)
|
358
|
+
}
|
359
|
+
}
|
360
|
+
function popOption(...names) {
|
361
|
+
const presentOptionNames = names.filter(name => options.has(name))
|
362
|
+
if (!presentOptionNames.length) return
|
363
|
+
const presentOptionNamesWithDashDash = presentOptionNames.map(name =>
|
364
|
+
colourN(`-${1 == name.length ? "" : "-"}${name}`)
|
365
|
+
)
|
366
|
+
if (presentOptionNames.length > 1) {
|
367
|
+
logError(
|
368
|
+
`The options ${presentOptionNamesWithDashDash.join(", ")} are aliases for each other. Please only specify one`
|
369
|
+
)
|
370
|
+
process.exit(1)
|
371
|
+
}
|
372
|
+
const value = options.get(presentOptionNames[0])
|
373
|
+
options.delete(presentOptionNames[0])
|
374
|
+
return { name: presentOptionNamesWithDashDash[0], value }
|
375
|
+
}
|