@gamecrate/cli 2.4.0 → 2.5.0
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/gamecrate.js +41 -25
- package/dist/types/image/refs.d.ts +5 -1
- package/package.json +1 -1
package/dist/gamecrate.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { existsSync as existsSync16 } from "node:fs";
|
|
5
|
-
import { chown, cp, mkdir as mkdir7, readdir as readdir12, readFile as
|
|
5
|
+
import { chown, cp, mkdir as mkdir7, readdir as readdir12, readFile as readFile14, rm as rm6, rmdir, stat as stat6, writeFile as writeFile7 } from "node:fs/promises";
|
|
6
6
|
import { homedir as homedir7 } from "node:os";
|
|
7
7
|
import { basename as basename11, dirname as dirname14, join as join28 } from "node:path";
|
|
8
8
|
import { setTimeout as sleep8 } from "node:timers/promises";
|
|
@@ -1038,7 +1038,7 @@ function requireGame(args, config) {
|
|
|
1038
1038
|
|
|
1039
1039
|
// src/image/refs.ts
|
|
1040
1040
|
import { existsSync as existsSync8, readlinkSync } from "node:fs";
|
|
1041
|
-
import { mkdir as mkdir3, readdir as readdir7, rename, rm as rm3, symlink, unlink as unlink3 } from "node:fs/promises";
|
|
1041
|
+
import { mkdir as mkdir3, readFile as readFile6, readdir as readdir7, rename, rm as rm3, symlink, unlink as unlink3 } from "node:fs/promises";
|
|
1042
1042
|
import { dirname as dirname6, join as join11 } from "node:path";
|
|
1043
1043
|
|
|
1044
1044
|
// src/cli/output.ts
|
|
@@ -4558,8 +4558,24 @@ function byPath(index, raw, game) {
|
|
|
4558
4558
|
function refsRoot() {
|
|
4559
4559
|
return join11(cacheDir(), "refs");
|
|
4560
4560
|
}
|
|
4561
|
-
function refsLink(game) {
|
|
4562
|
-
|
|
4561
|
+
function refsLink(game, version) {
|
|
4562
|
+
if (version === undefined)
|
|
4563
|
+
return join11(refsRoot(), "current", game);
|
|
4564
|
+
return join11(refsRoot(), "version", game, version);
|
|
4565
|
+
}
|
|
4566
|
+
async function readVersion(dir) {
|
|
4567
|
+
const text = await readFile6(join11(dir, "Version.txt"), "utf8").catch(() => {
|
|
4568
|
+
return;
|
|
4569
|
+
});
|
|
4570
|
+
const hit = text === undefined ? null : /^(\d+\.\d+)/.exec(text.trim());
|
|
4571
|
+
return hit === null ? undefined : hit[1];
|
|
4572
|
+
}
|
|
4573
|
+
async function pointBoth(game, dir) {
|
|
4574
|
+
const version = await readVersion(dir);
|
|
4575
|
+
const link = await point(refsLink(game), dir);
|
|
4576
|
+
if (version !== undefined)
|
|
4577
|
+
await point(refsLink(game, version), dir);
|
|
4578
|
+
return { link, version };
|
|
4563
4579
|
}
|
|
4564
4580
|
function currentRefs(game) {
|
|
4565
4581
|
try {
|
|
@@ -4581,6 +4597,7 @@ function extractScript(candidates, container) {
|
|
|
4581
4597
|
' [ -f "$1" ] || continue',
|
|
4582
4598
|
` echo "${MARK2}$d"`,
|
|
4583
4599
|
' cp "$@" /out/',
|
|
4600
|
+
` cp '${join11(container, "Version.txt")}' /out/ 2>/dev/null || true`,
|
|
4584
4601
|
" exit 0",
|
|
4585
4602
|
"done",
|
|
4586
4603
|
"exit 3"
|
|
@@ -4598,9 +4615,8 @@ async function extractRefs(game, config) {
|
|
|
4598
4615
|
throw new GamecrateError(`${ref} is not present, so ${game} has no assemblies to extract`, Exit.Environment, `gamecrate steam build ${game}, or docker pull ${ref}`);
|
|
4599
4616
|
}
|
|
4600
4617
|
const dir = join11(refsRoot(), digest.replace(/[^A-Za-z0-9]/g, "-"));
|
|
4601
|
-
const link = refsLink(game);
|
|
4602
4618
|
if (existsSync8(dir)) {
|
|
4603
|
-
return { dir,
|
|
4619
|
+
return { dir, ...await pointBoth(game, dir), digest, source: "(cached)", count: await dllCount(dir) };
|
|
4604
4620
|
}
|
|
4605
4621
|
const partial = `${dir}.partial`;
|
|
4606
4622
|
await rm3(partial, { recursive: true, force: true });
|
|
@@ -4632,7 +4648,7 @@ async function extractRefs(game, config) {
|
|
|
4632
4648
|
throw new GamecrateError(`${ref} reported assemblies at ${source} but none arrived`, Exit.Environment, "the copy ran inside the image; check /out was writable by the calling uid");
|
|
4633
4649
|
}
|
|
4634
4650
|
await rename(partial, dir);
|
|
4635
|
-
return { dir,
|
|
4651
|
+
return { dir, ...await pointBoth(game, dir), digest, source, count };
|
|
4636
4652
|
}
|
|
4637
4653
|
async function dllCount(dir) {
|
|
4638
4654
|
const entries = await readdir7(dir).catch(() => []);
|
|
@@ -4720,11 +4736,11 @@ function profileRows(profile, spec, width, notes) {
|
|
|
4720
4736
|
|
|
4721
4737
|
// src/cli/mods.ts
|
|
4722
4738
|
import { existsSync as existsSync9 } from "node:fs";
|
|
4723
|
-
import { mkdir as mkdir4, readFile as
|
|
4739
|
+
import { mkdir as mkdir4, readFile as readFile9, readdir as readdir8, writeFile as writeFile4 } from "node:fs/promises";
|
|
4724
4740
|
import { dirname as dirname9, join as join14, relative as relative3, resolve as resolve6 } from "node:path";
|
|
4725
4741
|
|
|
4726
4742
|
// src/config/write.ts
|
|
4727
|
-
import { chmod, readFile as
|
|
4743
|
+
import { chmod, readFile as readFile7, realpath, rename as rename2, stat as stat3, writeFile as writeFile3 } from "node:fs/promises";
|
|
4728
4744
|
import { dirname as dirname7, extname as extname2, join as join12 } from "node:path";
|
|
4729
4745
|
import { applyEdits, modify } from "jsonc-parser";
|
|
4730
4746
|
import { isMap as isMap2, parseDocument as parseDocument2 } from "yaml";
|
|
@@ -4747,7 +4763,7 @@ async function writeConfig(file, edits) {
|
|
|
4747
4763
|
return;
|
|
4748
4764
|
const yaml = isYaml2(file);
|
|
4749
4765
|
const target = await realpath(file);
|
|
4750
|
-
const before = await
|
|
4766
|
+
const before = await readFile7(target, "utf8");
|
|
4751
4767
|
const after = yaml ? editYaml(before, edits) : editJson(before, edits);
|
|
4752
4768
|
const mode = (await stat3(target)).mode & 511;
|
|
4753
4769
|
const temp = join12(dirname7(target), `.gamecrate-write-${process.pid}.tmp`);
|
|
@@ -4789,7 +4805,7 @@ function editYaml(text, edits) {
|
|
|
4789
4805
|
}
|
|
4790
4806
|
|
|
4791
4807
|
// src/mods/workshopapi.ts
|
|
4792
|
-
import { readFile as
|
|
4808
|
+
import { readFile as readFile8, stat as stat4 } from "node:fs/promises";
|
|
4793
4809
|
import { basename as basename5, dirname as dirname8, join as join13 } from "node:path";
|
|
4794
4810
|
var ENDPOINT = "https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/";
|
|
4795
4811
|
var CHUNK = 100;
|
|
@@ -4903,7 +4919,7 @@ async function exists(dir) {
|
|
|
4903
4919
|
}
|
|
4904
4920
|
async function readText(path) {
|
|
4905
4921
|
try {
|
|
4906
|
-
return await
|
|
4922
|
+
return await readFile8(path, "utf8");
|
|
4907
4923
|
} catch {
|
|
4908
4924
|
return "";
|
|
4909
4925
|
}
|
|
@@ -5200,7 +5216,7 @@ async function walk2(root, manifestFile, plugin) {
|
|
|
5200
5216
|
return out;
|
|
5201
5217
|
}
|
|
5202
5218
|
async function readId(dir, manifestFile, plugin) {
|
|
5203
|
-
const text = await
|
|
5219
|
+
const text = await readFile9(join14(dir, manifestFile), "utf8").catch(() => {
|
|
5204
5220
|
return;
|
|
5205
5221
|
});
|
|
5206
5222
|
if (text === undefined)
|
|
@@ -5235,7 +5251,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
5235
5251
|
|
|
5236
5252
|
// src/image/build.ts
|
|
5237
5253
|
import { mkdirSync as mkdirSync4, mkdtempSync, rmSync as rmSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
5238
|
-
import { readFile as
|
|
5254
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
5239
5255
|
import { tmpdir } from "node:os";
|
|
5240
5256
|
import { join as join17 } from "node:path";
|
|
5241
5257
|
|
|
@@ -5673,7 +5689,7 @@ async function cell(input, opts, ctx) {
|
|
|
5673
5689
|
}
|
|
5674
5690
|
try {
|
|
5675
5691
|
const dir = await download(input, opts, ctx, say);
|
|
5676
|
-
const raw = await
|
|
5692
|
+
const raw = await readFile10(join17(dir, input.versionFile), "utf8");
|
|
5677
5693
|
const version = sanitizeVersion(raw, ctx.published ?? "unknown");
|
|
5678
5694
|
const tags = tagsFor({ ...tagInput, version });
|
|
5679
5695
|
const layers = join17(steamHome(opts.config.dataRoot), "layers");
|
|
@@ -6720,7 +6736,7 @@ function parseAtoms(stdout) {
|
|
|
6720
6736
|
}
|
|
6721
6737
|
|
|
6722
6738
|
// src/launch/generate.ts
|
|
6723
|
-
import { mkdir as mkdir5, readdir as readdir9, readFile as
|
|
6739
|
+
import { mkdir as mkdir5, readdir as readdir9, readFile as readFile11, writeFile as writeFile5 } from "node:fs/promises";
|
|
6724
6740
|
import { dirname as dirname12, join as join20 } from "node:path";
|
|
6725
6741
|
async function readInstallVersion(game, plugin) {
|
|
6726
6742
|
const raw = await installVersionText(game);
|
|
@@ -6737,7 +6753,7 @@ async function installVersionText(game) {
|
|
|
6737
6753
|
if (host === undefined)
|
|
6738
6754
|
return null;
|
|
6739
6755
|
try {
|
|
6740
|
-
return await
|
|
6756
|
+
return await readFile11(join20(expandHome(host), game.version.file), "utf8");
|
|
6741
6757
|
} catch {
|
|
6742
6758
|
return null;
|
|
6743
6759
|
}
|
|
@@ -6762,7 +6778,7 @@ async function readKnownExpansions(game, plugin, warnings) {
|
|
|
6762
6778
|
continue;
|
|
6763
6779
|
let id = null;
|
|
6764
6780
|
try {
|
|
6765
|
-
id = plugin.parseManifest(await
|
|
6781
|
+
id = plugin.parseManifest(await readFile11(join20(dataDir, entry.name, game.manifest.file), "utf8"))?.packageId ?? null;
|
|
6766
6782
|
} catch {
|
|
6767
6783
|
continue;
|
|
6768
6784
|
}
|
|
@@ -6833,7 +6849,7 @@ async function mergePrefs(plan) {
|
|
|
6833
6849
|
await mkdir5(dirname12(target), { recursive: true });
|
|
6834
6850
|
let existing = null;
|
|
6835
6851
|
try {
|
|
6836
|
-
existing = await
|
|
6852
|
+
existing = await readFile11(target, "utf8");
|
|
6837
6853
|
} catch (error) {
|
|
6838
6854
|
if (error.code !== "ENOENT")
|
|
6839
6855
|
throw error;
|
|
@@ -6922,7 +6938,7 @@ async function offerRebuild(input) {
|
|
|
6922
6938
|
|
|
6923
6939
|
// src/launch/supervisor.ts
|
|
6924
6940
|
import { existsSync as existsSync14 } from "node:fs";
|
|
6925
|
-
import { readFile as
|
|
6941
|
+
import { readFile as readFile12, readlink, rm as rm4, writeFile as writeFile6 } from "node:fs/promises";
|
|
6926
6942
|
import { basename as basename8, join as join22 } from "node:path";
|
|
6927
6943
|
import { setTimeout as sleep7 } from "node:timers/promises";
|
|
6928
6944
|
async function forkSupervisor(plan, argv) {
|
|
@@ -6989,7 +7005,7 @@ async function writeExit(instanceDir, record) {
|
|
|
6989
7005
|
`);
|
|
6990
7006
|
}
|
|
6991
7007
|
async function lastExit(instanceDir) {
|
|
6992
|
-
const text = await
|
|
7008
|
+
const text = await readFile12(join22(instanceDir, ".gamecrate", "last-exit.json"), "utf8").catch(() => {
|
|
6993
7009
|
return;
|
|
6994
7010
|
});
|
|
6995
7011
|
if (text === undefined)
|
|
@@ -7650,7 +7666,7 @@ async function detectForeignOwnership(dir, uid, limit = 100) {
|
|
|
7650
7666
|
|
|
7651
7667
|
// src/mods/workshop.ts
|
|
7652
7668
|
import { existsSync as existsSync15 } from "node:fs";
|
|
7653
|
-
import { readFile as
|
|
7669
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
7654
7670
|
import { join as join27, resolve as resolvePath2 } from "node:path";
|
|
7655
7671
|
var ROUNDS = 5;
|
|
7656
7672
|
async function prepareWorkshop(game, profileName, args, config, allowFetch, plugin, sources) {
|
|
@@ -7713,7 +7729,7 @@ async function manifestAt(dir, game, plugin, problems) {
|
|
|
7713
7729
|
if (!existsSync15(file))
|
|
7714
7730
|
return null;
|
|
7715
7731
|
try {
|
|
7716
|
-
return plugin.parseManifest(await
|
|
7732
|
+
return plugin.parseManifest(await readFile13(file, "utf8"));
|
|
7717
7733
|
} catch (error) {
|
|
7718
7734
|
problems.push({ where: file, message: error instanceof Error ? error.message : String(error) });
|
|
7719
7735
|
return null;
|
|
@@ -7785,7 +7801,7 @@ function published2(value) {
|
|
|
7785
7801
|
}
|
|
7786
7802
|
|
|
7787
7803
|
// src/index.ts
|
|
7788
|
-
var VERSION = "2.
|
|
7804
|
+
var VERSION = "2.5.0";
|
|
7789
7805
|
async function main(argv) {
|
|
7790
7806
|
const supervised = supervisedDir(argv);
|
|
7791
7807
|
try {
|
|
@@ -8365,7 +8381,7 @@ async function logs(args, config, defaults) {
|
|
|
8365
8381
|
}
|
|
8366
8382
|
status(runDir);
|
|
8367
8383
|
for (const name of files) {
|
|
8368
|
-
const text = await
|
|
8384
|
+
const text = await readFile14(join28(runDir, name), "utf8").catch(() => "");
|
|
8369
8385
|
for (const line of text.split(`
|
|
8370
8386
|
`)) {
|
|
8371
8387
|
if (line.length > 0)
|
|
@@ -8,9 +8,13 @@ export interface ManagedRefs {
|
|
|
8
8
|
digest: string;
|
|
9
9
|
/** Container path they were found at. */
|
|
10
10
|
source: string;
|
|
11
|
+
/** `1.6` from the game's own Version.txt, absent when the image does not ship one. */
|
|
12
|
+
version?: string;
|
|
11
13
|
count: number;
|
|
12
14
|
}
|
|
13
|
-
export declare function refsLink(game: string): string;
|
|
15
|
+
export declare function refsLink(game: string, version?: string): string;
|
|
16
|
+
/** `1.6.4633 rev1254` in the file, `1.6` as the folder a mod builds into. */
|
|
17
|
+
export declare function readVersion(dir: string): Promise<string | undefined>;
|
|
14
18
|
/** What `current` points at, for a failure message. A build that broke on the wrong game
|
|
15
19
|
* generation says nothing about refs on its own. */
|
|
16
20
|
export declare function currentRefs(game: string): string | undefined;
|