gdharness 1.3.44 → 1.3.45
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/build/cli.js +300 -291
- package/build/godot/addons/gdharness_editor/setting_reads.gd +42 -1
- package/build/godot/addons/gdharness_runtime/runtime_values.gd +13 -0
- package/build/godot/operations/dependencies.gd +103 -69
- package/build/godot/operations/gdscript_analysis.gd +45 -8
- package/build/godot/operations/patterns.gd +6 -0
- package/build/godot/operations/project_validation.gd +3 -4
- package/build/godot/operations/setting_reads.gd +42 -1
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -11818,6 +11818,16 @@ var init_engine_launch = __esm(() => {
|
|
|
11818
11818
|
MEMORY_PER_ENGINE = 1.5 * 1024 ** 3;
|
|
11819
11819
|
});
|
|
11820
11820
|
|
|
11821
|
+
// src/cache-home.ts
|
|
11822
|
+
import { homedir as homedir2 } from "node:os";
|
|
11823
|
+
import { join as join8 } from "node:path";
|
|
11824
|
+
function cacheHome(env = process.env, platform = process.platform, home = homedir2()) {
|
|
11825
|
+
const set = (name) => env[name] === "" ? undefined : env[name];
|
|
11826
|
+
const local = platform === "win32" ? set("LOCALAPPDATA") : undefined;
|
|
11827
|
+
return join8(set("XDG_CACHE_HOME") ?? local ?? join8(home, ".cache"), "gdharness");
|
|
11828
|
+
}
|
|
11829
|
+
var init_cache_home = () => {};
|
|
11830
|
+
|
|
11821
11831
|
// src/call-signal.ts
|
|
11822
11832
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11823
11833
|
function stillGoingSaid(tool, op, elapsedMs) {
|
|
@@ -11889,8 +11899,8 @@ import {
|
|
|
11889
11899
|
watch,
|
|
11890
11900
|
writeSync as writeSync3
|
|
11891
11901
|
} from "node:fs";
|
|
11892
|
-
import { availableParallelism as availableParallelism2, homedir as
|
|
11893
|
-
import { join as
|
|
11902
|
+
import { availableParallelism as availableParallelism2, homedir as homedir3 } from "node:os";
|
|
11903
|
+
import { join as join9, resolve as resolve4 } from "node:path";
|
|
11894
11904
|
import process7 from "node:process";
|
|
11895
11905
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
11896
11906
|
function machineSlots(asked = {
|
|
@@ -11900,15 +11910,13 @@ function machineSlots(asked = {
|
|
|
11900
11910
|
env: process7.env,
|
|
11901
11911
|
platform: process7.platform,
|
|
11902
11912
|
processors: availableParallelism2(),
|
|
11903
|
-
home:
|
|
11913
|
+
home: homedir3(),
|
|
11904
11914
|
cwd: process7.cwd()
|
|
11905
11915
|
}) {
|
|
11906
11916
|
const { env } = machine;
|
|
11907
11917
|
const named = nonEmpty(env[SLOTS_VARIABLE]);
|
|
11908
|
-
const
|
|
11909
|
-
const
|
|
11910
|
-
const cache = join8(xdg ?? local ?? join8(machine.home, ".cache"), "gdharness");
|
|
11911
|
-
const directory = asked.directory ?? (named === undefined ? join8(cache, "slots") : resolve4(machine.cwd, named));
|
|
11918
|
+
const cache = cacheHome(env, machine.platform, machine.home);
|
|
11919
|
+
const directory = asked.directory ?? (named === undefined ? join9(cache, "slots") : resolve4(machine.cwd, named));
|
|
11912
11920
|
const counted = nonEmpty(env[SLOT_COUNT_VARIABLE]);
|
|
11913
11921
|
let count = asked.count;
|
|
11914
11922
|
if (count === null && counted !== undefined) {
|
|
@@ -12056,7 +12064,7 @@ class EngineSlots {
|
|
|
12056
12064
|
async takeFree() {
|
|
12057
12065
|
mkdirSync3(this.directory, { recursive: true });
|
|
12058
12066
|
for (let slot = 0;slot < this.count; slot += 1) {
|
|
12059
|
-
const lock =
|
|
12067
|
+
const lock = join9(this.directory, `${String(slot)}.lock`);
|
|
12060
12068
|
if (this.made(lock) || await this.takenOver(lock)) {
|
|
12061
12069
|
this.held.add(lock);
|
|
12062
12070
|
return lock;
|
|
@@ -12065,9 +12073,9 @@ class EngineSlots {
|
|
|
12065
12073
|
return null;
|
|
12066
12074
|
}
|
|
12067
12075
|
waitMarked() {
|
|
12068
|
-
const marks =
|
|
12076
|
+
const marks = join9(this.directory, WAITING_FOLDER);
|
|
12069
12077
|
waitsMarked += 1;
|
|
12070
|
-
const mark =
|
|
12078
|
+
const mark = join9(marks, `${String(this.holder.pid)}-${String(waitsMarked)}.json`);
|
|
12071
12079
|
try {
|
|
12072
12080
|
mkdirSync3(marks, { recursive: true });
|
|
12073
12081
|
} catch {
|
|
@@ -12083,7 +12091,7 @@ class EngineSlots {
|
|
|
12083
12091
|
const found = [];
|
|
12084
12092
|
for (let slot = 0;slot < this.count; slot += 1) {
|
|
12085
12093
|
try {
|
|
12086
|
-
const holder = holderOf(readFileSync8(
|
|
12094
|
+
const holder = holderOf(readFileSync8(join9(this.directory, `${String(slot)}.lock`), "utf8"));
|
|
12087
12095
|
if (holder !== null) {
|
|
12088
12096
|
found.push(holder);
|
|
12089
12097
|
}
|
|
@@ -12257,6 +12265,7 @@ async function inASlot(body) {
|
|
|
12257
12265
|
var SLOTS_VARIABLE = "GODOT_ENGINE_SLOTS", SLOT_COUNT_VARIABLE = "GODOT_ENGINE_SLOT_COUNT", PROCESSORS_A_SLOT = 2, START_TOLERANCE_MS = 2000, UNWRITTEN_MS = 1e4, SLOT_LOOK_MS = 1000, SLOT_SETTLE_MS = 50, WAIT_SAID_MS = 20000, COMMAND_WAIT_SAID_MS = 2000, START_READ_MS = 1e4, WAITING_FOLDER = "waiting", waitsMarked = 0, ours, saidTo, takenBy;
|
|
12258
12266
|
var init_engine_slots = __esm(() => {
|
|
12259
12267
|
init_alive();
|
|
12268
|
+
init_cache_home();
|
|
12260
12269
|
init_call_signal();
|
|
12261
12270
|
init_engine_launch();
|
|
12262
12271
|
init_process_children();
|
|
@@ -12265,11 +12274,11 @@ var init_engine_slots = __esm(() => {
|
|
|
12265
12274
|
|
|
12266
12275
|
// src/detection.ts
|
|
12267
12276
|
import { existsSync as existsSync6, readdirSync as readdirSync4, statSync as statSync7 } from "node:fs";
|
|
12268
|
-
import { homedir as
|
|
12269
|
-
import { join as
|
|
12277
|
+
import { homedir as homedir4 } from "node:os";
|
|
12278
|
+
import { join as join10 } from "node:path";
|
|
12270
12279
|
function resolveHomeDirectory() {
|
|
12271
12280
|
try {
|
|
12272
|
-
return
|
|
12281
|
+
return homedir4();
|
|
12273
12282
|
} catch {
|
|
12274
12283
|
return "";
|
|
12275
12284
|
}
|
|
@@ -12290,7 +12299,7 @@ function scanDirectoryForGodotBinaries(directory, platform) {
|
|
|
12290
12299
|
if (!pattern.test(name)) {
|
|
12291
12300
|
continue;
|
|
12292
12301
|
}
|
|
12293
|
-
const fullPath =
|
|
12302
|
+
const fullPath = join10(directory, name);
|
|
12294
12303
|
try {
|
|
12295
12304
|
const stat = statSync7(fullPath);
|
|
12296
12305
|
if (stat.isFile()) {
|
|
@@ -12299,7 +12308,7 @@ function scanDirectoryForGodotBinaries(directory, platform) {
|
|
|
12299
12308
|
} catch {}
|
|
12300
12309
|
}
|
|
12301
12310
|
matches.sort((a, b) => b.mtime - a.mtime);
|
|
12302
|
-
return matches.map((m) =>
|
|
12311
|
+
return matches.map((m) => join10(directory, m.name));
|
|
12303
12312
|
}
|
|
12304
12313
|
function conventionalPaths(platform, home) {
|
|
12305
12314
|
const paths = ["godot"];
|
|
@@ -12954,26 +12963,26 @@ var init_engine_run = __esm(() => {
|
|
|
12954
12963
|
|
|
12955
12964
|
// src/doc-cache.ts
|
|
12956
12965
|
import { existsSync as existsSync8, readdirSync as readdirSync5, statSync as statSync8 } from "node:fs";
|
|
12957
|
-
import { homedir as
|
|
12958
|
-
import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute5, join as
|
|
12966
|
+
import { homedir as homedir5 } from "node:os";
|
|
12967
|
+
import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute5, join as join11 } from "node:path";
|
|
12959
12968
|
import process9 from "node:process";
|
|
12960
|
-
function editorCacheDirectory(godotPath, platform = process9.platform, env = process9.env, home =
|
|
12969
|
+
function editorCacheDirectory(godotPath, platform = process9.platform, env = process9.env, home = homedir5()) {
|
|
12961
12970
|
const beside = dirname5(godotPath);
|
|
12962
12971
|
const bundle = platform === "darwin" && basename4(beside) === "MacOS" && basename4(dirname5(beside)) === "Contents" ? dirname5(dirname5(dirname5(beside))) : null;
|
|
12963
12972
|
for (const folder of bundle === null ? [beside] : [beside, bundle]) {
|
|
12964
|
-
if (existsSync8(
|
|
12965
|
-
return
|
|
12973
|
+
if (existsSync8(join11(folder, "._sc_")) || existsSync8(join11(folder, "_sc_"))) {
|
|
12974
|
+
return join11(folder, "editor_data", "cache");
|
|
12966
12975
|
}
|
|
12967
12976
|
}
|
|
12968
12977
|
if (platform === "win32") {
|
|
12969
12978
|
const set = (name) => env[name] === "" ? undefined : env[name];
|
|
12970
|
-
return
|
|
12979
|
+
return join11(set("LOCALAPPDATA") ?? set("TEMP") ?? join11(home, "AppData", "Local"), "Godot");
|
|
12971
12980
|
}
|
|
12972
12981
|
if (platform === "darwin") {
|
|
12973
|
-
return
|
|
12982
|
+
return join11(home, "Library", "Caches", "Godot");
|
|
12974
12983
|
}
|
|
12975
12984
|
const xdg = env["XDG_CACHE_HOME"];
|
|
12976
|
-
return
|
|
12985
|
+
return join11(xdg !== undefined && isAbsolute5(xdg) ? xdg : join11(home, ".cache"), "godot");
|
|
12977
12986
|
}
|
|
12978
12987
|
function docCachesWritten(directory) {
|
|
12979
12988
|
const written = new Map;
|
|
@@ -12985,7 +12994,7 @@ function docCachesWritten(directory) {
|
|
|
12985
12994
|
}
|
|
12986
12995
|
for (const name of names.filter((one) => CACHE_FILE.test(one))) {
|
|
12987
12996
|
try {
|
|
12988
|
-
written.set(
|
|
12997
|
+
written.set(join11(directory, name), statSync8(join11(directory, name)).mtimeMs);
|
|
12989
12998
|
} catch {}
|
|
12990
12999
|
}
|
|
12991
13000
|
return written;
|
|
@@ -13010,7 +13019,7 @@ var init_doc_cache = __esm(() => {
|
|
|
13010
13019
|
|
|
13011
13020
|
// src/project-scan.ts
|
|
13012
13021
|
import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync9, statSync as statSync9 } from "node:fs";
|
|
13013
|
-
import { basename as basename5, extname, join as
|
|
13022
|
+
import { basename as basename5, extname, join as join12, relative as relative4, sep as sep3 } from "node:path";
|
|
13014
13023
|
function skipped(name) {
|
|
13015
13024
|
return name.startsWith(".") || SKIPPED.has(name);
|
|
13016
13025
|
}
|
|
@@ -13018,10 +13027,10 @@ function steppedOver(directory) {
|
|
|
13018
13027
|
return gdignored(directory) || installedByUs(directory);
|
|
13019
13028
|
}
|
|
13020
13029
|
function gdignored(directory) {
|
|
13021
|
-
return existsSync9(
|
|
13030
|
+
return existsSync9(join12(directory, ".gdignore"));
|
|
13022
13031
|
}
|
|
13023
13032
|
function installedByUs(directory) {
|
|
13024
|
-
return existsSync9(
|
|
13033
|
+
return existsSync9(join12(directory, VERSION_MARKER));
|
|
13025
13034
|
}
|
|
13026
13035
|
function projectStructure(projectPath) {
|
|
13027
13036
|
const structure = { scenes: 0, scripts: 0, assets: 0, other: 0 };
|
|
@@ -13034,7 +13043,7 @@ function projectStructure(projectPath) {
|
|
|
13034
13043
|
continue;
|
|
13035
13044
|
}
|
|
13036
13045
|
if (entry.isDirectory()) {
|
|
13037
|
-
visit(
|
|
13046
|
+
visit(join12(directory, entry.name));
|
|
13038
13047
|
} else if (entry.isFile()) {
|
|
13039
13048
|
const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
|
|
13040
13049
|
if (SIDECAR_EXTENSIONS.has(extension)) {
|
|
@@ -13064,7 +13073,7 @@ function folderFiles(directory, extensions) {
|
|
|
13064
13073
|
function underGdignore(projectPath, relative) {
|
|
13065
13074
|
const folders = relative.split("/").slice(0, -1);
|
|
13066
13075
|
for (let depth = 1;depth <= folders.length; depth += 1) {
|
|
13067
|
-
if (gdignored(
|
|
13076
|
+
if (gdignored(join12(projectPath, ...folders.slice(0, depth)))) {
|
|
13068
13077
|
return true;
|
|
13069
13078
|
}
|
|
13070
13079
|
}
|
|
@@ -13081,7 +13090,7 @@ function steppedOverIn(directory) {
|
|
|
13081
13090
|
continue;
|
|
13082
13091
|
}
|
|
13083
13092
|
const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
13084
|
-
const path =
|
|
13093
|
+
const path = join12(at, entry.name);
|
|
13085
13094
|
if (gdignored(path)) {
|
|
13086
13095
|
found.push({ folder: spelled, why: "gdignore" });
|
|
13087
13096
|
} else if (installedByUs(path)) {
|
|
@@ -13102,7 +13111,7 @@ function filesBelow(root, extensions) {
|
|
|
13102
13111
|
continue;
|
|
13103
13112
|
}
|
|
13104
13113
|
const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
13105
|
-
const path =
|
|
13114
|
+
const path = join12(directory, entry.name);
|
|
13106
13115
|
if (entry.isDirectory()) {
|
|
13107
13116
|
if (!steppedOver(path)) {
|
|
13108
13117
|
visit(path, spelled);
|
|
@@ -13127,14 +13136,14 @@ function scriptsWithoutUid(projectPath) {
|
|
|
13127
13136
|
}
|
|
13128
13137
|
const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
13129
13138
|
if (entry.isDirectory()) {
|
|
13130
|
-
visit(
|
|
13139
|
+
visit(join12(directory, entry.name), spelled);
|
|
13131
13140
|
continue;
|
|
13132
13141
|
}
|
|
13133
13142
|
if (!entry.isFile()) {
|
|
13134
13143
|
continue;
|
|
13135
13144
|
}
|
|
13136
13145
|
const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
|
|
13137
|
-
if (CARRIES_A_UID.has(extension) && !existsSync9(
|
|
13146
|
+
if (CARRIES_A_UID.has(extension) && !existsSync9(join12(directory, `${entry.name}.uid`))) {
|
|
13138
13147
|
found.push(spelled);
|
|
13139
13148
|
}
|
|
13140
13149
|
}
|
|
@@ -13145,7 +13154,7 @@ function scriptsWithoutUid(projectPath) {
|
|
|
13145
13154
|
function pathsInUidCache(projectPath) {
|
|
13146
13155
|
let data;
|
|
13147
13156
|
try {
|
|
13148
|
-
data = readFileSync9(
|
|
13157
|
+
data = readFileSync9(join12(projectPath, ".godot", "uid_cache.bin"));
|
|
13149
13158
|
} catch {
|
|
13150
13159
|
return null;
|
|
13151
13160
|
}
|
|
@@ -13173,7 +13182,7 @@ function pathsInUidCache(projectPath) {
|
|
|
13173
13182
|
function steppedOverAround(projectPath, place) {
|
|
13174
13183
|
let at = projectPath;
|
|
13175
13184
|
for (const step of relative4(projectPath, place).split(sep3).filter((part) => part !== "")) {
|
|
13176
|
-
at =
|
|
13185
|
+
at = join12(at, step);
|
|
13177
13186
|
if (!statSync9(at).isDirectory()) {
|
|
13178
13187
|
break;
|
|
13179
13188
|
}
|
|
@@ -13197,7 +13206,7 @@ function projectTexts(projectPath) {
|
|
|
13197
13206
|
if (skipped(entry.name)) {
|
|
13198
13207
|
continue;
|
|
13199
13208
|
}
|
|
13200
|
-
const absolute =
|
|
13209
|
+
const absolute = join12(directory, entry.name);
|
|
13201
13210
|
const spelled = `${prefix}${entry.name}`;
|
|
13202
13211
|
if (entry.isDirectory()) {
|
|
13203
13212
|
visit(absolute, `${spelled}/`);
|
|
@@ -13227,7 +13236,7 @@ function ignoredTexts(projectPath) {
|
|
|
13227
13236
|
if (skipped(entry.name)) {
|
|
13228
13237
|
continue;
|
|
13229
13238
|
}
|
|
13230
|
-
const absolute =
|
|
13239
|
+
const absolute = join12(directory, entry.name);
|
|
13231
13240
|
const spelled = `${prefix}${entry.name}`;
|
|
13232
13241
|
if (entry.isDirectory()) {
|
|
13233
13242
|
visit(absolute, `${spelled}/`, under);
|
|
@@ -13325,7 +13334,7 @@ function searchProject(projectPath, options) {
|
|
|
13325
13334
|
if (skipped(entry.name)) {
|
|
13326
13335
|
continue;
|
|
13327
13336
|
}
|
|
13328
|
-
const entryPath =
|
|
13337
|
+
const entryPath = join12(directory, entry.name);
|
|
13329
13338
|
if (entry.isDirectory()) {
|
|
13330
13339
|
visit(entryPath);
|
|
13331
13340
|
} else if (entry.isFile()) {
|
|
@@ -13402,7 +13411,7 @@ var init_project_scan = __esm(() => {
|
|
|
13402
13411
|
// src/import-freshness.ts
|
|
13403
13412
|
import { createHash as createHash2 } from "node:crypto";
|
|
13404
13413
|
import { existsSync as existsSync10, readdirSync as readdirSync7, readFileSync as readFileSync10, statSync as statSync10 } from "node:fs";
|
|
13405
|
-
import { join as
|
|
13414
|
+
import { join as join13 } from "node:path";
|
|
13406
13415
|
function md5Of(file) {
|
|
13407
13416
|
let stats;
|
|
13408
13417
|
try {
|
|
@@ -13462,7 +13471,7 @@ function importedIntoTheProject(projectPath, resPaths) {
|
|
|
13462
13471
|
return wrote;
|
|
13463
13472
|
}
|
|
13464
13473
|
function onDisk(projectPath, resPath) {
|
|
13465
|
-
return
|
|
13474
|
+
return join13(projectPath, resPath.slice("res://".length));
|
|
13466
13475
|
}
|
|
13467
13476
|
function behind(projectPath, resPath, sidecar) {
|
|
13468
13477
|
const remap = sectionOf(sidecar, "remap");
|
|
@@ -13475,7 +13484,7 @@ function behind(projectPath, resPath, sidecar) {
|
|
|
13475
13484
|
return "its imported output is not on disk";
|
|
13476
13485
|
}
|
|
13477
13486
|
const name = resPath.slice(resPath.lastIndexOf("/") + 1);
|
|
13478
|
-
const record =
|
|
13487
|
+
const record = join13(projectPath, ".godot", "imported", `${name}-${createHash2("md5").update(resPath, "utf8").digest("hex")}.md5`);
|
|
13479
13488
|
let recorded = "";
|
|
13480
13489
|
try {
|
|
13481
13490
|
recorded = /^source_md5="([0-9a-f]*)"/m.exec(readFileSync10(record, "utf8"))?.[1] ?? "";
|
|
@@ -13491,7 +13500,7 @@ function behind(projectPath, resPath, sidecar) {
|
|
|
13491
13500
|
function staleImports(projectPath) {
|
|
13492
13501
|
const stale = [];
|
|
13493
13502
|
const visit = (directory, resDirectory) => {
|
|
13494
|
-
if (existsSync10(
|
|
13503
|
+
if (existsSync10(join13(directory, ".gdignore")) || existsSync10(join13(directory, VERSION_MARKER))) {
|
|
13495
13504
|
return;
|
|
13496
13505
|
}
|
|
13497
13506
|
let entries;
|
|
@@ -13507,7 +13516,7 @@ function staleImports(projectPath) {
|
|
|
13507
13516
|
}
|
|
13508
13517
|
const resPath = `${resDirectory}${entry.name}`;
|
|
13509
13518
|
if (entry.isDirectory()) {
|
|
13510
|
-
visit(
|
|
13519
|
+
visit(join13(directory, entry.name), `${resPath}/`);
|
|
13511
13520
|
continue;
|
|
13512
13521
|
}
|
|
13513
13522
|
if (!entry.isFile()) {
|
|
@@ -13520,7 +13529,7 @@ function staleImports(projectPath) {
|
|
|
13520
13529
|
}
|
|
13521
13530
|
let sidecar;
|
|
13522
13531
|
try {
|
|
13523
|
-
sidecar = readFileSync10(
|
|
13532
|
+
sidecar = readFileSync10(join13(directory, entry.name), "utf8");
|
|
13524
13533
|
} catch {
|
|
13525
13534
|
continue;
|
|
13526
13535
|
}
|
|
@@ -13589,7 +13598,7 @@ import {
|
|
|
13589
13598
|
unlinkSync,
|
|
13590
13599
|
writeFileSync as writeFileSync6
|
|
13591
13600
|
} from "node:fs";
|
|
13592
|
-
import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute6, join as
|
|
13601
|
+
import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute6, join as join14 } from "node:path";
|
|
13593
13602
|
function freeLibraryCopies(projectPath, platform = process.platform) {
|
|
13594
13603
|
const setAside = [];
|
|
13595
13604
|
const swept = [];
|
|
@@ -13599,10 +13608,10 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
|
|
|
13599
13608
|
for (const library of windowsLibraries(projectPath)) {
|
|
13600
13609
|
const folder = dirname6(library);
|
|
13601
13610
|
const copy = `~${basename6(library)}`;
|
|
13602
|
-
if (existsSync11(
|
|
13603
|
-
const aside =
|
|
13611
|
+
if (existsSync11(join14(folder, copy))) {
|
|
13612
|
+
const aside = join14(folder, `${copy}.aside-${process.pid}-${Date.now()}`);
|
|
13604
13613
|
try {
|
|
13605
|
-
renameSync2(
|
|
13614
|
+
renameSync2(join14(folder, copy), aside);
|
|
13606
13615
|
setAside.push(aside);
|
|
13607
13616
|
} catch {}
|
|
13608
13617
|
}
|
|
@@ -13615,8 +13624,8 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
|
|
|
13615
13624
|
for (const name of names) {
|
|
13616
13625
|
if (name.length > copy.length && name.toLowerCase().startsWith(copy.toLowerCase())) {
|
|
13617
13626
|
try {
|
|
13618
|
-
unlinkSync(
|
|
13619
|
-
swept.push(
|
|
13627
|
+
unlinkSync(join14(folder, name));
|
|
13628
|
+
swept.push(join14(folder, name));
|
|
13620
13629
|
} catch {}
|
|
13621
13630
|
}
|
|
13622
13631
|
}
|
|
@@ -13624,13 +13633,13 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
|
|
|
13624
13633
|
return { setAside, swept };
|
|
13625
13634
|
}
|
|
13626
13635
|
function seedExtensionList(projectPath) {
|
|
13627
|
-
const list =
|
|
13636
|
+
const list = join14(projectPath, ".godot", "extension_list.cfg");
|
|
13628
13637
|
if (existsSync11(list)) {
|
|
13629
13638
|
return null;
|
|
13630
13639
|
}
|
|
13631
13640
|
const found = [];
|
|
13632
13641
|
const visit = (directory, resDirectory) => {
|
|
13633
|
-
if (existsSync11(
|
|
13642
|
+
if (existsSync11(join14(directory, ".gdignore"))) {
|
|
13634
13643
|
return;
|
|
13635
13644
|
}
|
|
13636
13645
|
let entries;
|
|
@@ -13644,7 +13653,7 @@ function seedExtensionList(projectPath) {
|
|
|
13644
13653
|
continue;
|
|
13645
13654
|
}
|
|
13646
13655
|
if (entry.isDirectory()) {
|
|
13647
|
-
visit(
|
|
13656
|
+
visit(join14(directory, entry.name), `${resDirectory}${entry.name}/`);
|
|
13648
13657
|
} else if (entry.name.endsWith(".gdextension")) {
|
|
13649
13658
|
found.push(`${resDirectory}${entry.name}`);
|
|
13650
13659
|
}
|
|
@@ -13662,7 +13671,7 @@ function seedExtensionList(projectPath) {
|
|
|
13662
13671
|
return found;
|
|
13663
13672
|
}
|
|
13664
13673
|
function windowsLibraries(projectPath) {
|
|
13665
|
-
const listed = readOrNull(
|
|
13674
|
+
const listed = readOrNull(join14(projectPath, ".godot", "extension_list.cfg"));
|
|
13666
13675
|
if (listed === null) {
|
|
13667
13676
|
return [];
|
|
13668
13677
|
}
|
|
@@ -13694,9 +13703,9 @@ function resolveResource(projectPath, relativeTo, path) {
|
|
|
13694
13703
|
return null;
|
|
13695
13704
|
}
|
|
13696
13705
|
if (path.startsWith("res://")) {
|
|
13697
|
-
return
|
|
13706
|
+
return join14(projectPath, path.slice("res://".length));
|
|
13698
13707
|
}
|
|
13699
|
-
return isAbsolute6(path) ? path :
|
|
13708
|
+
return isAbsolute6(path) ? path : join14(relativeTo, path);
|
|
13700
13709
|
}
|
|
13701
13710
|
function readOrNull(path) {
|
|
13702
13711
|
try {
|
|
@@ -13710,10 +13719,10 @@ var init_library_copies = () => {};
|
|
|
13710
13719
|
// src/reimport.ts
|
|
13711
13720
|
import { createHash as createHash3 } from "node:crypto";
|
|
13712
13721
|
import { existsSync as existsSync12, readFileSync as readFileSync12, rmSync as rmSync7, statSync as statSync11, utimesSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
13713
|
-
import { basename as basename7, join as
|
|
13722
|
+
import { basename as basename7, join as join15 } from "node:path";
|
|
13714
13723
|
function forceNextImport(projectPath, resourcePath) {
|
|
13715
13724
|
const relative = resourcePath.replace(/^res:\/\//, "");
|
|
13716
|
-
const sidecar =
|
|
13725
|
+
const sidecar = join15(projectPath, `${relative}.import`);
|
|
13717
13726
|
if (!existsSync12(sidecar)) {
|
|
13718
13727
|
return;
|
|
13719
13728
|
}
|
|
@@ -13724,17 +13733,17 @@ function forceNextImport(projectPath, resourcePath) {
|
|
|
13724
13733
|
}
|
|
13725
13734
|
function importRecord(projectPath, resourcePath) {
|
|
13726
13735
|
const digest = createHash3("md5").update(resourcePath).digest("hex");
|
|
13727
|
-
return
|
|
13736
|
+
return join15(projectPath, ".godot", "imported", `${basename7(resourcePath)}-${digest}.md5`);
|
|
13728
13737
|
}
|
|
13729
13738
|
var init_reimport = () => {};
|
|
13730
13739
|
|
|
13731
13740
|
// src/scratch.ts
|
|
13732
13741
|
import { existsSync as existsSync13, mkdtempSync as mkdtempSync2, readdirSync as readdirSync9, rmSync as rmSync8 } from "node:fs";
|
|
13733
13742
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
13734
|
-
import { join as
|
|
13743
|
+
import { join as join16 } from "node:path";
|
|
13735
13744
|
import process10 from "node:process";
|
|
13736
13745
|
function scratchDirectory(kind) {
|
|
13737
|
-
return mkdtempSync2(
|
|
13746
|
+
return mkdtempSync2(join16(tmpdir3(), `gdharness-${kind}-${process10.pid}-`));
|
|
13738
13747
|
}
|
|
13739
13748
|
function sweepAbandonedScratch(directory = tmpdir3()) {
|
|
13740
13749
|
let entries;
|
|
@@ -13750,7 +13759,7 @@ function sweepAbandonedScratch(directory = tmpdir3()) {
|
|
|
13750
13759
|
continue;
|
|
13751
13760
|
}
|
|
13752
13761
|
try {
|
|
13753
|
-
remove(
|
|
13762
|
+
remove(join16(directory, entry));
|
|
13754
13763
|
} catch {}
|
|
13755
13764
|
}
|
|
13756
13765
|
}
|
|
@@ -13836,7 +13845,7 @@ var init_scratch = __esm(() => {
|
|
|
13836
13845
|
});
|
|
13837
13846
|
|
|
13838
13847
|
// src/script-origins.ts
|
|
13839
|
-
import { join as
|
|
13848
|
+
import { join as join17 } from "node:path";
|
|
13840
13849
|
function unresolvedClassIn(message) {
|
|
13841
13850
|
return UNRESOLVED.exec(message)?.[1] ?? null;
|
|
13842
13851
|
}
|
|
@@ -13898,7 +13907,7 @@ function checkWithEngine(godotPath, projectPath) {
|
|
|
13898
13907
|
const ran = await runEngine(godotPath, [
|
|
13899
13908
|
"--headless",
|
|
13900
13909
|
"--log-file",
|
|
13901
|
-
|
|
13910
|
+
join17(logDir, "engine.log"),
|
|
13902
13911
|
"--path",
|
|
13903
13912
|
projectPath,
|
|
13904
13913
|
"--check-only",
|
|
@@ -13945,7 +13954,7 @@ var init_script_origins = __esm(() => {
|
|
|
13945
13954
|
|
|
13946
13955
|
// src/headless.ts
|
|
13947
13956
|
import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "node:fs";
|
|
13948
|
-
import { dirname as dirname7, join as
|
|
13957
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
13949
13958
|
function snakeCased(params) {
|
|
13950
13959
|
const result = emptyRecord();
|
|
13951
13960
|
for (const [key, value] of Object.entries(params)) {
|
|
@@ -14101,7 +14110,7 @@ async function importOnce(godotPath, projectPath) {
|
|
|
14101
14110
|
ran = await runEngine(godotPath, [
|
|
14102
14111
|
"--headless",
|
|
14103
14112
|
"--log-file",
|
|
14104
|
-
|
|
14113
|
+
join18(logDir, "engine.log"),
|
|
14105
14114
|
"--path",
|
|
14106
14115
|
projectPath,
|
|
14107
14116
|
"--import"
|
|
@@ -14137,14 +14146,14 @@ async function runOperation(engine, operation, params, projectPath) {
|
|
|
14137
14146
|
}
|
|
14138
14147
|
async function operationOutcome(engine, operation, params, projectPath) {
|
|
14139
14148
|
const paramsDir = scratchDirectory("params");
|
|
14140
|
-
const paramsFile =
|
|
14141
|
-
const answerFile =
|
|
14149
|
+
const paramsFile = join18(paramsDir, `${operation}.json`);
|
|
14150
|
+
const answerFile = join18(paramsDir, "answer.json");
|
|
14142
14151
|
writeFileSync8(paramsFile, JSON.stringify(snakeCased(params)), "utf8");
|
|
14143
14152
|
const args = [
|
|
14144
14153
|
"--headless",
|
|
14145
14154
|
...engine.editor === true ? ["--editor"] : [],
|
|
14146
14155
|
"--log-file",
|
|
14147
|
-
|
|
14156
|
+
join18(paramsDir, "engine.log"),
|
|
14148
14157
|
"--path",
|
|
14149
14158
|
projectPath,
|
|
14150
14159
|
"--script",
|
|
@@ -14261,8 +14270,8 @@ var init_headless = __esm(() => {
|
|
|
14261
14270
|
|
|
14262
14271
|
// src/update-check.ts
|
|
14263
14272
|
import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
|
|
14264
|
-
import { homedir as
|
|
14265
|
-
import { join as
|
|
14273
|
+
import { homedir as homedir6, tmpdir as tmpdir4 } from "node:os";
|
|
14274
|
+
import { join as join19 } from "node:path";
|
|
14266
14275
|
function packageUrl(root) {
|
|
14267
14276
|
return `${root.replace(/\/+$/, "")}/gdharness/latest`;
|
|
14268
14277
|
}
|
|
@@ -14282,22 +14291,22 @@ function cacheDirectory(environment) {
|
|
|
14282
14291
|
const value = environment[name];
|
|
14283
14292
|
return value !== undefined && value !== "" ? value : null;
|
|
14284
14293
|
};
|
|
14285
|
-
const home = set("HOME") ??
|
|
14294
|
+
const home = set("HOME") ?? homedir6();
|
|
14286
14295
|
if (process.platform === "win32") {
|
|
14287
|
-
return
|
|
14296
|
+
return join19(set("LOCALAPPDATA") ?? home, "gdharness");
|
|
14288
14297
|
}
|
|
14289
14298
|
if (process.platform === "darwin") {
|
|
14290
|
-
return
|
|
14299
|
+
return join19(home, "Library", "Caches", "gdharness");
|
|
14291
14300
|
}
|
|
14292
|
-
return
|
|
14301
|
+
return join19(set("XDG_CACHE_HOME") ?? join19(home, ".cache"), "gdharness");
|
|
14293
14302
|
}
|
|
14294
14303
|
function cacheFile(environment = process.env) {
|
|
14295
14304
|
try {
|
|
14296
14305
|
const directory = cacheDirectory(environment);
|
|
14297
14306
|
mkdirSync5(directory, { recursive: true, mode: 448 });
|
|
14298
|
-
return
|
|
14307
|
+
return join19(directory, "update-check.json");
|
|
14299
14308
|
} catch {
|
|
14300
|
-
return
|
|
14309
|
+
return join19(tmpdir4(), "gdharness-update-check.json");
|
|
14301
14310
|
}
|
|
14302
14311
|
}
|
|
14303
14312
|
function readCache(path) {
|
|
@@ -14785,7 +14794,7 @@ var init_ports = __esm(() => {
|
|
|
14785
14794
|
import { existsSync as existsSync16, realpathSync as realpathSync2 } from "node:fs";
|
|
14786
14795
|
import { readFile, realpath } from "node:fs/promises";
|
|
14787
14796
|
import { createConnection } from "node:net";
|
|
14788
|
-
import { dirname as dirname8, join as
|
|
14797
|
+
import { dirname as dirname8, join as join20, resolve as resolve6 } from "node:path";
|
|
14789
14798
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
14790
14799
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14791
14800
|
function initializeTimeoutMs() {
|
|
@@ -15463,7 +15472,7 @@ async function resolveLSPPaths(projectPathValue, scriptPathValue) {
|
|
|
15463
15472
|
} catch {
|
|
15464
15473
|
throw new ArgumentRefusal(`Project path does not exist: ${requestedProjectPath}`);
|
|
15465
15474
|
}
|
|
15466
|
-
if (!existsSync16(
|
|
15475
|
+
if (!existsSync16(join20(projectPath, "project.godot"))) {
|
|
15467
15476
|
throw new ArgumentRefusal(`Not a Godot project: ${projectPath}. Point projectPath at the directory holding project.godot.`);
|
|
15468
15477
|
}
|
|
15469
15478
|
const contained = resolveWithinProject(projectPath, scriptPathValue);
|
|
@@ -15981,7 +15990,7 @@ import {
|
|
|
15981
15990
|
statSync as statSync12,
|
|
15982
15991
|
writeFileSync as writeFileSync10
|
|
15983
15992
|
} from "node:fs";
|
|
15984
|
-
import { dirname as dirname9, join as
|
|
15993
|
+
import { dirname as dirname9, join as join22 } from "node:path";
|
|
15985
15994
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
15986
15995
|
function addonMarking(name) {
|
|
15987
15996
|
if (name === RUNTIME_ADDON) {
|
|
@@ -16002,7 +16011,7 @@ function addonsDigest(names, from) {
|
|
|
16002
16011
|
if (name === VERSION_MARKER || name === DIGEST_MARKER) {
|
|
16003
16012
|
continue;
|
|
16004
16013
|
}
|
|
16005
|
-
const path =
|
|
16014
|
+
const path = join22(directory, name);
|
|
16006
16015
|
const inside = `${relative}/${name}`;
|
|
16007
16016
|
if (statSync12(path).isDirectory()) {
|
|
16008
16017
|
walk(path, inside);
|
|
@@ -16016,7 +16025,7 @@ function addonsDigest(names, from) {
|
|
|
16016
16025
|
}
|
|
16017
16026
|
};
|
|
16018
16027
|
for (const name of names) {
|
|
16019
|
-
walk(
|
|
16028
|
+
walk(join22(from, name), name);
|
|
16020
16029
|
}
|
|
16021
16030
|
return hash.digest("hex");
|
|
16022
16031
|
}
|
|
@@ -16035,7 +16044,7 @@ function installedRuntimeDigest(projectPath) {
|
|
|
16035
16044
|
return digestMarker(projectPath, RUNTIME_ADDON);
|
|
16036
16045
|
}
|
|
16037
16046
|
function digestMarker(projectPath, addon) {
|
|
16038
|
-
const marker =
|
|
16047
|
+
const marker = join22(projectPath, "addons", addon, DIGEST_MARKER);
|
|
16039
16048
|
if (!existsSync18(marker)) {
|
|
16040
16049
|
return null;
|
|
16041
16050
|
}
|
|
@@ -16043,16 +16052,16 @@ function digestMarker(projectPath, addon) {
|
|
|
16043
16052
|
return said === "" ? null : said;
|
|
16044
16053
|
}
|
|
16045
16054
|
function shippedAddonsDirectory() {
|
|
16046
|
-
return
|
|
16055
|
+
return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "addons");
|
|
16047
16056
|
}
|
|
16048
16057
|
function shippedOperationsScript() {
|
|
16049
|
-
return
|
|
16058
|
+
return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "operations", "godot_operations.gd");
|
|
16050
16059
|
}
|
|
16051
16060
|
function shippedLoader() {
|
|
16052
|
-
return
|
|
16061
|
+
return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "loader", "loader.gd");
|
|
16053
16062
|
}
|
|
16054
16063
|
function loaderState(projectPath) {
|
|
16055
|
-
const copy =
|
|
16064
|
+
const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
|
|
16056
16065
|
if (!existsSync18(copy)) {
|
|
16057
16066
|
return "missing";
|
|
16058
16067
|
}
|
|
@@ -16065,13 +16074,13 @@ function writeLoader(projectPath) {
|
|
|
16065
16074
|
if (loaderState(projectPath) === "current") {
|
|
16066
16075
|
return false;
|
|
16067
16076
|
}
|
|
16068
|
-
const copy =
|
|
16077
|
+
const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
|
|
16069
16078
|
mkdirSync6(dirname9(copy), { recursive: true });
|
|
16070
16079
|
writeFileSync10(copy, readFileSync18(shippedLoader()));
|
|
16071
16080
|
return true;
|
|
16072
16081
|
}
|
|
16073
16082
|
function removeLoader(projectPath) {
|
|
16074
|
-
const copy =
|
|
16083
|
+
const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
|
|
16075
16084
|
if (!existsSync18(copy)) {
|
|
16076
16085
|
return false;
|
|
16077
16086
|
}
|
|
@@ -16084,14 +16093,14 @@ function removeLoader(projectPath) {
|
|
|
16084
16093
|
return true;
|
|
16085
16094
|
}
|
|
16086
16095
|
function shippedListedRunner() {
|
|
16087
|
-
return
|
|
16096
|
+
return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "tests", "listed.gd");
|
|
16088
16097
|
}
|
|
16089
16098
|
function gdUnit4Unusable(projectPath) {
|
|
16090
16099
|
const marker = "addons/gdUnit4/plugin.cfg";
|
|
16091
|
-
if (!existsSync18(
|
|
16100
|
+
if (!existsSync18(join22(projectPath, ...marker.split("/")))) {
|
|
16092
16101
|
return { missing: true, reason: `gdUnit4 is not installed in this project: no ${marker}` };
|
|
16093
16102
|
}
|
|
16094
|
-
if (!existsSync18(
|
|
16103
|
+
if (!existsSync18(join22(projectPath, ...GDUNIT4_CI_RUNNER.split("/")))) {
|
|
16095
16104
|
return {
|
|
16096
16105
|
missing: false,
|
|
16097
16106
|
reason: `gdUnit4 in this project is older than 6.0, which the shipped runner needs: no ${GDUNIT4_CI_RUNNER}`
|
|
@@ -16102,27 +16111,27 @@ function gdUnit4Unusable(projectPath) {
|
|
|
16102
16111
|
function installAddons(projectPath, from = shippedAddonsDirectory()) {
|
|
16103
16112
|
const installed = [];
|
|
16104
16113
|
for (const name of ADDONS) {
|
|
16105
|
-
const source =
|
|
16106
|
-
if (!existsSync18(
|
|
16114
|
+
const source = join22(from, name);
|
|
16115
|
+
if (!existsSync18(join22(source, addonMarking(name)))) {
|
|
16107
16116
|
throw new Error(`The package holds no ${name} addon at ${source}.`);
|
|
16108
16117
|
}
|
|
16109
|
-
const target =
|
|
16118
|
+
const target = join22(projectPath, "addons", name);
|
|
16110
16119
|
const replaced = existsSync18(target);
|
|
16111
16120
|
rmSync9(target, { recursive: true, force: true });
|
|
16112
16121
|
mkdirSync6(dirname9(target), { recursive: true });
|
|
16113
16122
|
cpSync(source, target, { recursive: true });
|
|
16114
|
-
writeFileSync10(
|
|
16123
|
+
writeFileSync10(join22(target, VERSION_MARKER), `${SERVER_VERSION}
|
|
16115
16124
|
`);
|
|
16116
16125
|
installed.push({ name, path: target, replaced });
|
|
16117
16126
|
}
|
|
16118
|
-
writeFileSync10(
|
|
16127
|
+
writeFileSync10(join22(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
|
|
16119
16128
|
`);
|
|
16120
|
-
writeFileSync10(
|
|
16129
|
+
writeFileSync10(join22(projectPath, "addons", RUNTIME_ADDON, DIGEST_MARKER), `${runtimeAddonDigest(from)}
|
|
16121
16130
|
`);
|
|
16122
16131
|
return installed;
|
|
16123
16132
|
}
|
|
16124
16133
|
function installedAddonVersion(projectPath) {
|
|
16125
|
-
const marker =
|
|
16134
|
+
const marker = join22(projectPath, "addons", ADDONS[0], VERSION_MARKER);
|
|
16126
16135
|
if (!existsSync18(marker)) {
|
|
16127
16136
|
return null;
|
|
16128
16137
|
}
|
|
@@ -16132,13 +16141,13 @@ function installedAddonVersion(projectPath) {
|
|
|
16132
16141
|
function removeAddons(projectPath) {
|
|
16133
16142
|
const removed = [];
|
|
16134
16143
|
for (const name of ADDONS) {
|
|
16135
|
-
const target =
|
|
16144
|
+
const target = join22(projectPath, "addons", name);
|
|
16136
16145
|
if (existsSync18(target)) {
|
|
16137
16146
|
rmSync9(target, { recursive: true, force: true });
|
|
16138
16147
|
removed.push(target);
|
|
16139
16148
|
}
|
|
16140
16149
|
}
|
|
16141
|
-
const addons =
|
|
16150
|
+
const addons = join22(projectPath, "addons");
|
|
16142
16151
|
if (removed.length > 0 && existsSync18(addons) && readdirSync11(addons).length === 0) {
|
|
16143
16152
|
rmdirSync(addons);
|
|
16144
16153
|
removed.push(addons);
|
|
@@ -16181,7 +16190,7 @@ function loaderAmong(projectPath, named) {
|
|
|
16181
16190
|
}
|
|
16182
16191
|
let source = null;
|
|
16183
16192
|
try {
|
|
16184
|
-
source = readFileSync18(
|
|
16193
|
+
source = readFileSync18(join22(projectPath, path), "utf8");
|
|
16185
16194
|
} catch {}
|
|
16186
16195
|
if (source?.includes(RUNTIME_SCRIPT)) {
|
|
16187
16196
|
return { name: entry, path, exists: true };
|
|
@@ -16237,8 +16246,8 @@ function enabledPlugins(settings) {
|
|
|
16237
16246
|
function inspectProject(projectPath) {
|
|
16238
16247
|
const problems = [];
|
|
16239
16248
|
const addons = ADDONS.map((name) => {
|
|
16240
|
-
const directory =
|
|
16241
|
-
const marker =
|
|
16249
|
+
const directory = join22(projectPath, "addons", name);
|
|
16250
|
+
const marker = join22(directory, VERSION_MARKER);
|
|
16242
16251
|
const installed = existsSync18(directory);
|
|
16243
16252
|
const version = existsSync18(marker) ? readFileSync18(marker, "utf8").trim() : null;
|
|
16244
16253
|
const current = version === SERVER_VERSION;
|
|
@@ -16249,7 +16258,7 @@ function inspectProject(projectPath) {
|
|
|
16249
16258
|
}
|
|
16250
16259
|
return { name, installed, version, current };
|
|
16251
16260
|
});
|
|
16252
|
-
const settings = parseProjectGodot(readFileSync18(
|
|
16261
|
+
const settings = parseProjectGodot(readFileSync18(join22(projectPath, "project.godot"), "utf8"));
|
|
16253
16262
|
const pluginsEnabled = enabledPlugins(settings);
|
|
16254
16263
|
for (const name of EDITOR_PLUGINS) {
|
|
16255
16264
|
if (!pluginsEnabled.includes(name)) {
|
|
@@ -16273,7 +16282,7 @@ function inspectProject(projectPath) {
|
|
|
16273
16282
|
const ignoredAutoloads = [];
|
|
16274
16283
|
const addonMissing = (path) => addons.some((addon) => !addon.installed && path.startsWith(`addons/${addon.name}/`));
|
|
16275
16284
|
for (const [name, path] of named) {
|
|
16276
|
-
if (!existsSync18(
|
|
16285
|
+
if (!existsSync18(join22(projectPath, path))) {
|
|
16277
16286
|
if (!addonMissing(path)) {
|
|
16278
16287
|
problems.push(`the ${name} autoload names res://${path}, which is not in this project, so it boots with a missing script; restore that file, or point the autoload at one that is here`);
|
|
16279
16288
|
}
|
|
@@ -16642,7 +16651,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
16642
16651
|
include: {
|
|
16643
16652
|
type: "array",
|
|
16644
16653
|
items: { type: "string", enum: [...PROJECT_INFO_SECTIONS] },
|
|
16645
|
-
description: "Extra sections: registered autoloads, the classes the project's scripts declare with class_name, each with its script, read from the files, the input actions project.godot holds with their events (an engine ui_ action only when the project rebinds it, as engineAction), addons and whether each is enabled, export presets, the audio bus layout, a health report, or export validation. health and validation compile every script of the project in headless engines and name each that fails with its first error, each file a scene, resource or script refers to that does not exist, each input action a script reads by a name written in the call that neither the project nor the engine defines, with every line reading it, and each signal connection in a scene whose method or signal the node at its end does not have, judged from the node's type and scripts as their files are written."
|
|
16654
|
+
description: "Extra sections: registered autoloads, the classes the project's scripts declare with class_name, each with its script, read from the files, the input actions project.godot holds with their events (an engine ui_ action only when the project rebinds it, as engineAction), addons and whether each is enabled, export presets (runnable marks the one preset of its platform the editor's one-click deploy uses), the audio bus layout, a health report, or export validation. health and validation compile every script of the project in headless engines and name each that fails with its first error, each file a scene, resource or script refers to that does not exist, each input action a script reads by a name written in the call that neither the project nor the engine defines, with every line reading it, and each signal connection in a scene whose method or signal the node at its end does not have, judged from the node's type and scripts as their files are written."
|
|
16646
16655
|
},
|
|
16647
16656
|
preset: { type: "string", description: "For validation: the export preset to validate against." },
|
|
16648
16657
|
detail: {
|
|
@@ -16673,7 +16682,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
16673
16682
|
prefix: {
|
|
16674
16683
|
type: "string",
|
|
16675
16684
|
ops: ["get"],
|
|
16676
|
-
description: 'get: answer with every setting whose name starts with this, and the type the engine registers for each, instead of one setting by name. "debug/gdscript/warnings/" answers the whole family. The type matters: a family of levels can hold a setting that is a bool, and writing a level over it looks like it worked.'
|
|
16685
|
+
description: 'get: answer with every setting whose name starts with this, and the type the engine registers for each, a typed array or dictionary with what it holds as project.godot writes it (Dictionary[String, bool]), instead of one setting by name. "debug/gdscript/warnings/" answers the whole family. The type matters: a family of levels can hold a setting that is a bool, and writing a level over it looks like it worked.'
|
|
16677
16686
|
},
|
|
16678
16687
|
value: {
|
|
16679
16688
|
blank: true,
|
|
@@ -16854,12 +16863,12 @@ var init_tool_definitions = __esm(() => {
|
|
|
16854
16863
|
direction: {
|
|
16855
16864
|
type: "string",
|
|
16856
16865
|
enum: ["forward", "reverse"],
|
|
16857
|
-
description: "forward: what this resource loads, with each reference closing a cycle marked circular and the cycle under circular_references, a script's dependencies including every script whose class_name it uses, marked by_class with the name, and the script of every autoload it names, marked by_autoload with the autoload's name. An ext_resource whose uid names another file than its path is followed to that file, as the engine loads it, with the path written under stale_path; one whose uid names no file the project has is followed by its path, as the engine does after warning, with the uid under unknown_uid; and a load or preload of a uid the project does not know is listed under that uid as missing. A shader's #include is followed as the preprocessor reads it, relative to the shader. A file the depth stops at carries beyond_depth, how many files it names that were not walked. summary.total_resources is the file asked about, so 1; total_dependencies counts each file reached, directly or through another, once however many places load it; total_references counts the entries in the tree, and missing names every file referenced that does not exist, with the files referring to it. reverse: every file that refers to it and how, for a file that is gone as well while anything still refers to it, answered with exists: false (a missing file nothing refers to is refused, naming the nearest files), a scene instancing it, a script extending, preloading or loading it, and for a script with a class_name every use of that name, and for an autoload's script every use of the autoload's name, with autoload naming it. Each reference carries a kind: ext_resource, extends, preload, load, include or path for a reference by path, with stale_path when an ext_resource reaches it by its uid under another path, and unknown_uid when one names it by path beside a uid naming no file; setting, plugin, export_preset and import for one in project.godot, a plugin.cfg, export_presets.cfg or an import sidecar; class_name for a use of the declared name, the declaration itself being the script asked about; autoload for code naming the autoload. Three kinds are not uses: doc is a name inside a ## documentation comment, which renaming would break in the generated docs; comment is one in ordinary prose, which it would only make stale; and stale_path is an ext_resource naming it by a path the engine does not load, since its uid leads to the file under loads. summary.in_code is the count with those left out, which is the number to read when the question is whether anything still uses this. Default forward."
|
|
16866
|
+
description: "forward: what this resource loads, with each reference closing a cycle marked circular and the cycle under circular_references, a script's dependencies including every script whose class_name it uses, marked by_class with the name, and the script of every autoload it names, marked by_autoload with the autoload's name. An ext_resource whose uid names another file than its path is followed to that file, as the engine loads it, with the path written under stale_path; one whose uid names no file the project has is followed by its path, as the engine does after warning, with the uid under unknown_uid; and a load or preload of a uid the project does not know is listed under that uid as missing. A shader's #include is followed as the preprocessor reads it, relative to the shader. A file the depth stops at carries beyond_depth, how many files it names that were not walked. A file's dependencies are listed at its first entry, and again further down only where the depth cut that list short and more is left; every other entry for a file naming any carries dependencies_listed_above. summary.total_resources is the file asked about, so 1; total_dependencies counts each file reached, directly or through another, once however many places load it; total_references counts the entries in the tree, and missing names every file referenced that does not exist, with the files referring to it. reverse: every file that refers to it and how, for a file that is gone as well while anything still refers to it, answered with exists: false (a missing file nothing refers to is refused, naming the nearest files), a scene instancing it, a script extending, preloading or loading it, and for a script with a class_name every use of that name, and for an autoload's script every use of the autoload's name, with autoload naming it. Each reference carries a kind: ext_resource, extends, preload, load, include or path for a reference by path, with stale_path when an ext_resource reaches it by its uid under another path, and unknown_uid when one names it by path beside a uid naming no file; setting, plugin, export_preset and import for one in project.godot, a plugin.cfg, export_presets.cfg or an import sidecar; class_name for a use of the declared name, the declaration itself being the script asked about; autoload for code naming the autoload. Three kinds are not uses: doc is a name inside a ## documentation comment, which renaming would break in the generated docs; comment is one in ordinary prose, which it would only make stale; and stale_path is an ext_resource naming it by a path the engine does not load, since its uid leads to the file under loads. summary.in_code is the count with those left out, which is the number to read when the question is whether anything still uses this. Default forward."
|
|
16858
16867
|
},
|
|
16859
16868
|
depth: {
|
|
16860
16869
|
type: "integer",
|
|
16861
16870
|
minimum: 1,
|
|
16862
|
-
description: "forward: how many levels to follow, 1 being what the file loads itself. Default unlimited."
|
|
16871
|
+
description: "forward: how many levels to follow, 1 being what the file loads itself. Default unlimited, which follows every class_name use too and in a project whose scripts name each other's classes reaches most of it: a game of a hundred scripts with large addons answered 488 files in about a megabyte from its main scene. A depth of 2 or 3 keeps the answer to what is near."
|
|
16863
16872
|
},
|
|
16864
16873
|
includeBuiltin: {
|
|
16865
16874
|
type: "boolean",
|
|
@@ -17545,7 +17554,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
17545
17554
|
operations: {
|
|
17546
17555
|
structure: {
|
|
17547
17556
|
effect: "read",
|
|
17548
|
-
summary: `functions (each parameter's default the source text after its =, so = null reads "null", and null for a parameter with none), variables (static ones marked is_static; one written with := has the type of a literal or built-in constructor it is given, marked inferred, as a constant always does), signals, constants, enums, inner_classes (each with its name, line and extends, and its own members in these same fields), class_name, extends and line_count, read from the file, and dependencies: the paths it loads or preloads as written, then the scripts declaring each project class_name its code uses, which classes_used names with the class; autoloads_used names each autoload the code uses by its global name, with the autoload's script, which the project loads rather than this script, so it is not under dependencies. A member or inner class with a ## documentation comment directly above it carries the comment's text as doc, and the script's own, the ## block above class_name or extends or one followed by a blank line before any member, comes back as class_doc`,
|
|
17557
|
+
summary: `functions (each parameter's default the source text after its =, so = null reads "null", and null for a parameter with none), variables (static ones marked is_static; one written with := has the type of a literal or built-in constructor it is given, marked inferred, as a constant always does), signals, constants, enums, inner_classes (each with its name, line and extends, and its own members in these same fields), class_name, extends and line_count, read from the file, and dependencies: the paths it loads or preloads as written, by a constant it declares too, and the paths it or an inner class extends by, then the scripts declaring each project class_name its code uses, which classes_used names with the class; autoloads_used names each autoload the code uses by its global name, with the autoload's script, which the project loads rather than this script, so it is not under dependencies. A member or inner class with a ## documentation comment directly above it carries the comment's text as doc, and the script's own, the ## block above class_name or extends or one followed by a blank line before any member, comes back as class_doc`,
|
|
17549
17558
|
requires: []
|
|
17550
17559
|
},
|
|
17551
17560
|
symbols: {
|
|
@@ -18814,7 +18823,7 @@ var init_tool_reference = __esm(() => {
|
|
|
18814
18823
|
|
|
18815
18824
|
// src/suite-plan.ts
|
|
18816
18825
|
import { existsSync as existsSync22, mkdirSync as mkdirSync9, readFileSync as readFileSync21 } from "node:fs";
|
|
18817
|
-
import { dirname as dirname11, join as
|
|
18826
|
+
import { dirname as dirname11, join as join26, posix as posix3 } from "node:path";
|
|
18818
18827
|
function within(path, folder) {
|
|
18819
18828
|
return path === folder || path.startsWith(`${folder}/`);
|
|
18820
18829
|
}
|
|
@@ -18830,7 +18839,7 @@ class ProjectScripts {
|
|
|
18830
18839
|
this.projectPath = projectPath;
|
|
18831
18840
|
let settings = {};
|
|
18832
18841
|
try {
|
|
18833
|
-
settings = parseProjectGodot(readFileSync21(
|
|
18842
|
+
settings = parseProjectGodot(readFileSync21(join26(projectPath, "project.godot"), "utf8"))["gdharness"] ?? {};
|
|
18834
18843
|
} catch {}
|
|
18835
18844
|
const [section, key] = [NOT_SEARCHED_SETTING, GUESS_WINDOW_SETTING].map((setting) => setting.slice("gdharness/".length));
|
|
18836
18845
|
const listed = settings[section ?? ""];
|
|
@@ -40848,12 +40857,12 @@ var init_stdio = __esm(() => {
|
|
|
40848
40857
|
|
|
40849
40858
|
// src/autoload-failure.ts
|
|
40850
40859
|
import { existsSync as existsSync24, readFileSync as readFileSync24 } from "node:fs";
|
|
40851
|
-
import { join as
|
|
40860
|
+
import { join as join29 } from "node:path";
|
|
40852
40861
|
function scriptsAutoloaded(projectPath) {
|
|
40853
40862
|
const scripts = new Map;
|
|
40854
40863
|
let settings;
|
|
40855
40864
|
try {
|
|
40856
|
-
settings = parseProjectGodot(readFileSync24(
|
|
40865
|
+
settings = parseProjectGodot(readFileSync24(join29(projectPath, "project.godot"), "utf8"));
|
|
40857
40866
|
} catch {
|
|
40858
40867
|
return scripts;
|
|
40859
40868
|
}
|
|
@@ -40862,7 +40871,7 @@ function scriptsAutoloaded(projectPath) {
|
|
|
40862
40871
|
scripts.set(`res://${path}`, name);
|
|
40863
40872
|
continue;
|
|
40864
40873
|
}
|
|
40865
|
-
const scene =
|
|
40874
|
+
const scene = join29(projectPath, path);
|
|
40866
40875
|
if (!existsSync24(scene)) {
|
|
40867
40876
|
continue;
|
|
40868
40877
|
}
|
|
@@ -40889,7 +40898,7 @@ var init_autoload_failure = __esm(() => {
|
|
|
40889
40898
|
import { existsSync as existsSync25, readdirSync as readdirSync15, readFileSync as readFileSync25, statSync as statSync15, unlinkSync as unlinkSync3 } from "node:fs";
|
|
40890
40899
|
import { createConnection as createConnection2 } from "node:net";
|
|
40891
40900
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
40892
|
-
import { dirname as dirname14, join as
|
|
40901
|
+
import { dirname as dirname14, join as join30, resolve as resolve11 } from "node:path";
|
|
40893
40902
|
import { setTimeout as delay5 } from "node:timers/promises";
|
|
40894
40903
|
function runtimeDirectory(variables = process.env) {
|
|
40895
40904
|
const explicit = envValue("GDHARNESS_RUNTIME_DIR", variables);
|
|
@@ -40897,19 +40906,19 @@ function runtimeDirectory(variables = process.env) {
|
|
|
40897
40906
|
return explicit;
|
|
40898
40907
|
}
|
|
40899
40908
|
const perUser = envValue("XDG_RUNTIME_DIR", variables);
|
|
40900
|
-
return
|
|
40909
|
+
return join30(perUser ?? tmpdir5(), "gdharness");
|
|
40901
40910
|
}
|
|
40902
40911
|
function runtimeDirectories(variables = process.env) {
|
|
40903
40912
|
const candidates = [runtimeDirectory(variables)];
|
|
40904
40913
|
const fallbacks = process.platform === "win32" ? [envValue("SystemRoot", variables) ?? envValue("windir", variables) ?? "C:\\Windows"] : ["/tmp", "/var/tmp"];
|
|
40905
40914
|
for (const base of fallbacks) {
|
|
40906
|
-
candidates.push(
|
|
40915
|
+
candidates.push(join30(base, process.platform === "win32" ? "Temp" : "", "gdharness"));
|
|
40907
40916
|
}
|
|
40908
40917
|
return [...new Set(candidates.map((path) => resolve11(path)))];
|
|
40909
40918
|
}
|
|
40910
40919
|
function errorReportOf(pid, directories = runtimeDirectories()) {
|
|
40911
40920
|
for (const directory of directories) {
|
|
40912
|
-
const path =
|
|
40921
|
+
const path = join30(directory, `runtime-${pid}.log`);
|
|
40913
40922
|
if (existsSync25(path)) {
|
|
40914
40923
|
return path;
|
|
40915
40924
|
}
|
|
@@ -41065,14 +41074,14 @@ function announcedIn(directory) {
|
|
|
41065
41074
|
for (const entry of readdirSync15(directory)) {
|
|
41066
41075
|
const report = ERROR_REPORT_PATTERN.exec(entry);
|
|
41067
41076
|
if (report) {
|
|
41068
|
-
sweepErrorReport(
|
|
41077
|
+
sweepErrorReport(join30(directory, entry), Number.parseInt(report[1] ?? "", 10));
|
|
41069
41078
|
continue;
|
|
41070
41079
|
}
|
|
41071
41080
|
const match = ANNOUNCEMENT_PATTERN.exec(entry);
|
|
41072
41081
|
if (!match) {
|
|
41073
41082
|
continue;
|
|
41074
41083
|
}
|
|
41075
|
-
const file =
|
|
41084
|
+
const file = join30(directory, entry);
|
|
41076
41085
|
const pid = Number.parseInt(match[1] ?? "", 10);
|
|
41077
41086
|
const running = alive(pid);
|
|
41078
41087
|
entries.push({ file, pid, running });
|
|
@@ -41100,7 +41109,7 @@ function announcedIn(directory) {
|
|
|
41100
41109
|
found.push(announced);
|
|
41101
41110
|
}
|
|
41102
41111
|
const held = new Set(entries.map((one) => one.file));
|
|
41103
|
-
const here =
|
|
41112
|
+
const here = join30(directory, ".");
|
|
41104
41113
|
for (const file of verdicts.keys()) {
|
|
41105
41114
|
if (dirname14(file) === here && !held.has(file)) {
|
|
41106
41115
|
verdicts.delete(file);
|
|
@@ -41109,7 +41118,7 @@ function announcedIn(directory) {
|
|
|
41109
41118
|
return found;
|
|
41110
41119
|
}
|
|
41111
41120
|
async function announcementEnded(pid, directories = runtimeDirectories()) {
|
|
41112
|
-
const files = directories.map((directory) =>
|
|
41121
|
+
const files = directories.map((directory) => join30(directory, `runtime-${pid}.json`)).filter((file) => existsSync25(file));
|
|
41113
41122
|
const first = files[0];
|
|
41114
41123
|
if (first === undefined) {
|
|
41115
41124
|
return;
|
|
@@ -41529,9 +41538,9 @@ var init_runtime_client = __esm(() => {
|
|
|
41529
41538
|
|
|
41530
41539
|
// src/boot-note.ts
|
|
41531
41540
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "node:fs";
|
|
41532
|
-
import { dirname as dirname15, join as
|
|
41541
|
+
import { dirname as dirname15, join as join31 } from "node:path";
|
|
41533
41542
|
function bootNotePath(projectPath) {
|
|
41534
|
-
return
|
|
41543
|
+
return join31(projectPath, ".godot", "gdharness-boot.json");
|
|
41535
41544
|
}
|
|
41536
41545
|
function readScenes(projectPath) {
|
|
41537
41546
|
try {
|
|
@@ -41578,9 +41587,9 @@ var init_boot_note = __esm(() => {
|
|
|
41578
41587
|
|
|
41579
41588
|
// src/breakpoint-note.ts
|
|
41580
41589
|
import { mkdirSync as mkdirSync12, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync14 } from "node:fs";
|
|
41581
|
-
import { dirname as dirname16, isAbsolute as isAbsolute7, join as
|
|
41590
|
+
import { dirname as dirname16, isAbsolute as isAbsolute7, join as join32, relative as relative6 } from "node:path";
|
|
41582
41591
|
function breakpointNotePath(projectPath) {
|
|
41583
|
-
return
|
|
41592
|
+
return join32(projectPath, ".godot", "gdharness-breakpoints.json");
|
|
41584
41593
|
}
|
|
41585
41594
|
function writeBreakpointNote(projectPath, held) {
|
|
41586
41595
|
const path = breakpointNotePath(projectPath);
|
|
@@ -41621,7 +41630,7 @@ function readBreakpointNote(projectPath) {
|
|
|
41621
41630
|
}
|
|
41622
41631
|
const lines = Array.isArray(listed) ? listed.filter((line) => Number.isInteger(line) && line > 0) : [];
|
|
41623
41632
|
if (lines.length > 0) {
|
|
41624
|
-
held.push({ scriptPath: realAsFarAsItExists(
|
|
41633
|
+
held.push({ scriptPath: realAsFarAsItExists(join32(projectPath, script)), lines });
|
|
41625
41634
|
}
|
|
41626
41635
|
}
|
|
41627
41636
|
return held;
|
|
@@ -41640,9 +41649,9 @@ var init_breakpoint_note = __esm(() => {
|
|
|
41640
41649
|
|
|
41641
41650
|
// src/class-note.ts
|
|
41642
41651
|
import { mkdirSync as mkdirSync13, readFileSync as readFileSync28 } from "node:fs";
|
|
41643
|
-
import { dirname as dirname17, join as
|
|
41652
|
+
import { dirname as dirname17, join as join33 } from "node:path";
|
|
41644
41653
|
function classNotePath(projectPath) {
|
|
41645
|
-
return
|
|
41654
|
+
return join33(projectPath, ".godot", "gdharness-classes.json");
|
|
41646
41655
|
}
|
|
41647
41656
|
function readClassNote(projectPath) {
|
|
41648
41657
|
try {
|
|
@@ -41689,9 +41698,9 @@ var init_class_note = __esm(() => {
|
|
|
41689
41698
|
|
|
41690
41699
|
// src/config-pin.ts
|
|
41691
41700
|
import { existsSync as existsSync26, readFileSync as readFileSync29 } from "node:fs";
|
|
41692
|
-
import { join as
|
|
41701
|
+
import { join as join34 } from "node:path";
|
|
41693
41702
|
function versionsNamedInConfig(projectPath) {
|
|
41694
|
-
const config =
|
|
41703
|
+
const config = join34(projectPath, ".mcp.json");
|
|
41695
41704
|
if (!existsSync26(config)) {
|
|
41696
41705
|
return [];
|
|
41697
41706
|
}
|
|
@@ -41719,9 +41728,9 @@ var init_config_pin = __esm(() => {
|
|
|
41719
41728
|
|
|
41720
41729
|
// src/cut-test-run.ts
|
|
41721
41730
|
import { existsSync as existsSync27, mkdirSync as mkdirSync14, readFileSync as readFileSync30, rmSync as rmSync14, writeFileSync as writeFileSync15 } from "node:fs";
|
|
41722
|
-
import { dirname as dirname18, join as
|
|
41731
|
+
import { dirname as dirname18, join as join35 } from "node:path";
|
|
41723
41732
|
function keptAt(projectPath) {
|
|
41724
|
-
return
|
|
41733
|
+
return join35(projectPath, ".godot", "gdharness-reports", "cut-run.json");
|
|
41725
41734
|
}
|
|
41726
41735
|
function keepCutTestRun(projectPath, run) {
|
|
41727
41736
|
const path = keptAt(projectPath);
|
|
@@ -42479,12 +42488,12 @@ import {
|
|
|
42479
42488
|
statSync as statSync16,
|
|
42480
42489
|
writeFileSync as writeFileSync16
|
|
42481
42490
|
} from "node:fs";
|
|
42482
|
-
import { dirname as dirname19, join as
|
|
42491
|
+
import { dirname as dirname19, join as join36 } from "node:path";
|
|
42483
42492
|
function editorLogPath(projectPath) {
|
|
42484
|
-
return
|
|
42493
|
+
return join36(projectPath, ".godot", "gdharness-editor.log");
|
|
42485
42494
|
}
|
|
42486
42495
|
function editorLogNotePath(projectPath) {
|
|
42487
|
-
return
|
|
42496
|
+
return join36(projectPath, ".godot", "gdharness-editor.json");
|
|
42488
42497
|
}
|
|
42489
42498
|
function readEditorLogNote(projectPath) {
|
|
42490
42499
|
try {
|
|
@@ -43523,7 +43532,7 @@ var init_rename = __esm(() => {
|
|
|
43523
43532
|
|
|
43524
43533
|
// src/rename-symbol.ts
|
|
43525
43534
|
import { existsSync as existsSync30, mkdirSync as mkdirSync17, readdirSync as readdirSync16, realpathSync as realpathSync4, rmSync as rmSync16, writeFileSync as writeFileSync18 } from "node:fs";
|
|
43526
|
-
import { basename as basename9, dirname as dirname21, join as
|
|
43535
|
+
import { basename as basename9, dirname as dirname21, join as join37, relative as relative7, resolve as resolve12 } from "node:path";
|
|
43527
43536
|
function resourcePathOf(projectPath, absolute) {
|
|
43528
43537
|
const inside = relative7(onDiskSpelling(projectPath), onDiskSpelling(absolute));
|
|
43529
43538
|
if (inside === "" || inside.startsWith("..") || /^[A-Za-z]:/.test(inside)) {
|
|
@@ -43536,7 +43545,7 @@ function onDiskSpelling(path) {
|
|
|
43536
43545
|
let at = resolve12(path);
|
|
43537
43546
|
for (;; ) {
|
|
43538
43547
|
try {
|
|
43539
|
-
return
|
|
43548
|
+
return join37(realpathSync4.native(at), ...missing.reverse());
|
|
43540
43549
|
} catch {
|
|
43541
43550
|
const parent = dirname21(at);
|
|
43542
43551
|
if (parent === at) {
|
|
@@ -43974,15 +43983,15 @@ ${mention.kind}`;
|
|
|
43974
43983
|
};
|
|
43975
43984
|
}
|
|
43976
43985
|
function writeLeftAloneDetail(projectPath, symbol, detail) {
|
|
43977
|
-
const directory =
|
|
43986
|
+
const directory = join37(projectPath, ".godot", "gdharness-renames");
|
|
43978
43987
|
mkdirSync17(directory, { recursive: true });
|
|
43979
43988
|
detailWrites += 1;
|
|
43980
|
-
const path =
|
|
43989
|
+
const path = join37(directory, `${String(Date.now())}-${String(detailWrites).padStart(6, "0")}-${String(process.pid)}-${symbol}.json`);
|
|
43981
43990
|
writeFileSync18(path, `${JSON.stringify(detail, null, 2)}
|
|
43982
43991
|
`, "utf8");
|
|
43983
43992
|
const kept = readdirSync16(directory).filter((name) => name.endsWith(".json")).sort().reverse();
|
|
43984
43993
|
for (const old of kept.slice(10)) {
|
|
43985
|
-
rmSync16(
|
|
43994
|
+
rmSync16(join37(directory, old), { force: true });
|
|
43986
43995
|
}
|
|
43987
43996
|
return path;
|
|
43988
43997
|
}
|
|
@@ -44031,10 +44040,10 @@ import {
|
|
|
44031
44040
|
statSync as statSync17,
|
|
44032
44041
|
writeFileSync as writeFileSync19
|
|
44033
44042
|
} from "node:fs";
|
|
44034
|
-
import { basename as basename10, dirname as dirname22, extname as extname3, join as
|
|
44043
|
+
import { basename as basename10, dirname as dirname22, extname as extname3, join as join38, relative as relative8 } from "node:path";
|
|
44035
44044
|
function filesUnder(directory) {
|
|
44036
44045
|
return readdirSync17(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
44037
|
-
const path =
|
|
44046
|
+
const path = join38(directory, entry.name);
|
|
44038
44047
|
return entry.isDirectory() ? filesUnder(path) : [path];
|
|
44039
44048
|
});
|
|
44040
44049
|
}
|
|
@@ -44055,8 +44064,8 @@ function unseenByTheEngine(projectPath, path) {
|
|
|
44055
44064
|
return `${path} is under ${step}, and the engine passes over every directory whose name starts with a dot`;
|
|
44056
44065
|
}
|
|
44057
44066
|
if (at < steps.length - 1) {
|
|
44058
|
-
directory =
|
|
44059
|
-
if (existsSync31(
|
|
44067
|
+
directory = join38(directory, step);
|
|
44068
|
+
if (existsSync31(join38(directory, ".gdignore"))) {
|
|
44060
44069
|
return `${path} is under a directory holding a .gdignore, which the engine does not load`;
|
|
44061
44070
|
}
|
|
44062
44071
|
}
|
|
@@ -44068,12 +44077,12 @@ function installedAddonOf(projectPath, path) {
|
|
|
44068
44077
|
if (steps[0] !== "addons" || steps[1] === undefined) {
|
|
44069
44078
|
return null;
|
|
44070
44079
|
}
|
|
44071
|
-
return existsSync31(
|
|
44080
|
+
return existsSync31(join38(projectPath, "addons", steps[1], VERSION_MARKER)) ? `res://addons/${steps[1]}` : null;
|
|
44072
44081
|
}
|
|
44073
44082
|
function binaryResources(projectPath) {
|
|
44074
44083
|
const found = [];
|
|
44075
44084
|
const visit = (directory, prefix) => {
|
|
44076
|
-
if (existsSync31(
|
|
44085
|
+
if (existsSync31(join38(directory, ".gdignore"))) {
|
|
44077
44086
|
return;
|
|
44078
44087
|
}
|
|
44079
44088
|
for (const entry of readdirSync17(directory, { withFileTypes: true })) {
|
|
@@ -44082,7 +44091,7 @@ function binaryResources(projectPath) {
|
|
|
44082
44091
|
}
|
|
44083
44092
|
const path = `${prefix}${entry.name}`;
|
|
44084
44093
|
if (entry.isDirectory()) {
|
|
44085
|
-
visit(
|
|
44094
|
+
visit(join38(directory, entry.name), `${path}/`);
|
|
44086
44095
|
} else if (/\.(scn|res)$/i.test(entry.name)) {
|
|
44087
44096
|
found.push(path);
|
|
44088
44097
|
}
|
|
@@ -44092,7 +44101,7 @@ function binaryResources(projectPath) {
|
|
|
44092
44101
|
return found;
|
|
44093
44102
|
}
|
|
44094
44103
|
function targetPathOf(projectPath, absolute) {
|
|
44095
|
-
const inside = relative8(onDiskSpelling(projectPath),
|
|
44104
|
+
const inside = relative8(onDiskSpelling(projectPath), join38(onDiskSpelling(dirname22(absolute)), basename10(absolute)));
|
|
44096
44105
|
if (inside === "" || inside.startsWith("..") || /^[A-Za-z]:/.test(inside)) {
|
|
44097
44106
|
return null;
|
|
44098
44107
|
}
|
|
@@ -44147,7 +44156,7 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
|
|
|
44147
44156
|
return { ok: false, reason: `${unseen}, so nothing there could load what was moved.` };
|
|
44148
44157
|
}
|
|
44149
44158
|
if (!isDirectory) {
|
|
44150
|
-
const owner = SIDECARS.map((sidecar) => from.endsWith(sidecar) ? from.slice(0, -sidecar.length) : null).find((path) => path !== null && existsSync31(
|
|
44159
|
+
const owner = SIDECARS.map((sidecar) => from.endsWith(sidecar) ? from.slice(0, -sidecar.length) : null).find((path) => path !== null && existsSync31(join38(projectPath, path.slice("res://".length))));
|
|
44151
44160
|
if (owner !== undefined && owner !== null) {
|
|
44152
44161
|
return { ok: false, reason: `${from} belongs to ${owner} and moves with it: move ${owner} instead.` };
|
|
44153
44162
|
}
|
|
@@ -44181,12 +44190,12 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
|
|
|
44181
44190
|
scripts,
|
|
44182
44191
|
moves,
|
|
44183
44192
|
named: [from],
|
|
44184
|
-
exists: (path) => existsSync31(
|
|
44193
|
+
exists: (path) => existsSync31(join38(projectPath, path.slice("res://".length)))
|
|
44185
44194
|
}, { edits: [], mentions: [] });
|
|
44186
44195
|
plan = mentionIgnored(plan, ignoredTexts(projectPath), null, [from]);
|
|
44187
44196
|
const binaries = [];
|
|
44188
44197
|
for (const path of binaryResources(projectPath)) {
|
|
44189
|
-
const bytes = readFileSync33(
|
|
44198
|
+
const bytes = readFileSync33(join38(projectPath, path.slice("res://".length)));
|
|
44190
44199
|
const names = [...moves.keys()].find((moving) => bytes.includes(moving));
|
|
44191
44200
|
if (names !== undefined) {
|
|
44192
44201
|
binaries.push({
|
|
@@ -44205,7 +44214,7 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
|
|
|
44205
44214
|
file: afterwards(mention.file)
|
|
44206
44215
|
}));
|
|
44207
44216
|
const left = leftAloneReport(mentions);
|
|
44208
|
-
const absoluteOf = (path) =>
|
|
44217
|
+
const absoluteOf = (path) => join38(projectPath, path.slice("res://".length));
|
|
44209
44218
|
const rewritten = new Map(rewrites.map((rewrite) => [rewrite.path, rewrite]));
|
|
44210
44219
|
const moved = [...moves].map(([source, target]) => {
|
|
44211
44220
|
const rewrite = rewritten.get(source);
|
|
@@ -47996,10 +48005,10 @@ var init_keeper_channel = () => {};
|
|
|
47996
48005
|
|
|
47997
48006
|
// src/lifecycle-log.ts
|
|
47998
48007
|
import { appendFileSync, mkdirSync as mkdirSync19, renameSync as renameSync5, statSync as statSync18 } from "node:fs";
|
|
47999
|
-
import { dirname as dirname23, join as
|
|
48008
|
+
import { dirname as dirname23, join as join39 } from "node:path";
|
|
48000
48009
|
import process16 from "node:process";
|
|
48001
48010
|
function lifecycleLogPath() {
|
|
48002
|
-
return
|
|
48011
|
+
return join39(runtimeDirectory(), "servers.log");
|
|
48003
48012
|
}
|
|
48004
48013
|
function writeLifecycle(event, fields = {}) {
|
|
48005
48014
|
const path = lifecycleLogPath();
|
|
@@ -48370,9 +48379,9 @@ var init_prompts = __esm(() => {
|
|
|
48370
48379
|
|
|
48371
48380
|
// src/restart-note.ts
|
|
48372
48381
|
import { mkdirSync as mkdirSync20, readFileSync as readFileSync34, rmSync as rmSync17, writeFileSync as writeFileSync20 } from "node:fs";
|
|
48373
|
-
import { dirname as dirname24, join as
|
|
48382
|
+
import { dirname as dirname24, join as join40 } from "node:path";
|
|
48374
48383
|
function restartNotePath(projectPath) {
|
|
48375
|
-
return
|
|
48384
|
+
return join40(projectPath, ".godot", "gdharness-restart.json");
|
|
48376
48385
|
}
|
|
48377
48386
|
function noteRestartBegun(note) {
|
|
48378
48387
|
const path = restartNotePath(note.projectPath);
|
|
@@ -48413,9 +48422,9 @@ var init_restart_note = __esm(() => {
|
|
|
48413
48422
|
// src/run-record.ts
|
|
48414
48423
|
import { createHash as createHash7 } from "node:crypto";
|
|
48415
48424
|
import { mkdirSync as mkdirSync21, openSync as openSync5, readdirSync as readdirSync18, readFileSync as readFileSync35, rmSync as rmSync18, statSync as statSync19 } from "node:fs";
|
|
48416
|
-
import { basename as basename11, join as
|
|
48425
|
+
import { basename as basename11, join as join41, resolve as resolve13 } from "node:path";
|
|
48417
48426
|
function runsDirectory() {
|
|
48418
|
-
return
|
|
48427
|
+
return join41(runtimeDirectory(), "runs");
|
|
48419
48428
|
}
|
|
48420
48429
|
function projectKey(projectPath) {
|
|
48421
48430
|
const real = realAsFarAsItExists(resolve13(projectPath)).replace(/[\\/]+$/, "");
|
|
@@ -48423,10 +48432,10 @@ function projectKey(projectPath) {
|
|
|
48423
48432
|
return createHash7("sha256").update(folded.replaceAll("\\", "/")).digest("hex").slice(0, 16);
|
|
48424
48433
|
}
|
|
48425
48434
|
function runRecordPath(projectPath, directory = runtimeDirectory()) {
|
|
48426
|
-
return
|
|
48435
|
+
return join41(directory, "runs", `note-${projectKey(projectPath)}.json`);
|
|
48427
48436
|
}
|
|
48428
48437
|
function latestRunPath(servedBy, directory = runtimeDirectory()) {
|
|
48429
|
-
return
|
|
48438
|
+
return join41(directory, "runs", `latest-${projectKey(servedBy)}.json`);
|
|
48430
48439
|
}
|
|
48431
48440
|
function writeLatestRun(servedBy, latest) {
|
|
48432
48441
|
try {
|
|
@@ -48451,20 +48460,20 @@ function readLatestRun(servedBy, directory = runtimeDirectory()) {
|
|
|
48451
48460
|
}
|
|
48452
48461
|
function openTranscript(startedAt) {
|
|
48453
48462
|
mkdirSync21(runsDirectory(), { recursive: true });
|
|
48454
|
-
const path =
|
|
48463
|
+
const path = join41(runsDirectory(), `run-${startedAt}.log`);
|
|
48455
48464
|
return { path, fd: openSync5(path, "a") };
|
|
48456
48465
|
}
|
|
48457
48466
|
function profilePath(startedAt) {
|
|
48458
|
-
return
|
|
48467
|
+
return join41(runsDirectory(), `run-${startedAt}.profile.json`);
|
|
48459
48468
|
}
|
|
48460
48469
|
function profileMarkPath(startedAt) {
|
|
48461
|
-
return
|
|
48470
|
+
return join41(runsDirectory(), `run-${startedAt}.profile-mark.json`);
|
|
48462
48471
|
}
|
|
48463
48472
|
function noteIsAbout(note, playing) {
|
|
48464
48473
|
return note.play !== undefined && playing !== null && note.play.play === playing.play && note.play.editorPid === playing.editorPid;
|
|
48465
48474
|
}
|
|
48466
48475
|
function editorNotePath(projectPath, directory = runtimeDirectory()) {
|
|
48467
|
-
return
|
|
48476
|
+
return join41(directory, "runs", `editor-${projectKey(projectPath)}.json`);
|
|
48468
48477
|
}
|
|
48469
48478
|
function writeEditorRunNote(note) {
|
|
48470
48479
|
mkdirSync21(runsDirectory(), { recursive: true });
|
|
@@ -48517,13 +48526,13 @@ function everyRunRecord() {
|
|
|
48517
48526
|
for (const directory of runtimeDirectories()) {
|
|
48518
48527
|
let entries;
|
|
48519
48528
|
try {
|
|
48520
|
-
entries = readdirSync18(
|
|
48529
|
+
entries = readdirSync18(join41(directory, "runs"));
|
|
48521
48530
|
} catch {
|
|
48522
48531
|
continue;
|
|
48523
48532
|
}
|
|
48524
48533
|
for (const entry of entries) {
|
|
48525
48534
|
if (entry.startsWith("note-") && entry.endsWith(".json")) {
|
|
48526
|
-
const record = recordAt(
|
|
48535
|
+
const record = recordAt(join41(directory, "runs", entry));
|
|
48527
48536
|
if (record !== null) {
|
|
48528
48537
|
found.push(record);
|
|
48529
48538
|
}
|
|
@@ -48791,7 +48800,7 @@ function sweepTranscripts(keepMs = 24 * 60 * 60 * 1000, now = Date.now()) {
|
|
|
48791
48800
|
if (!transcript && !entry.endsWith(".partial")) {
|
|
48792
48801
|
continue;
|
|
48793
48802
|
}
|
|
48794
|
-
const path =
|
|
48803
|
+
const path = join41(directory, entry);
|
|
48795
48804
|
if (kept.has(path) || ageMs(path, now) < keepMs) {
|
|
48796
48805
|
continue;
|
|
48797
48806
|
}
|
|
@@ -49047,16 +49056,16 @@ var init_server_instructions = __esm(() => {
|
|
|
49047
49056
|
|
|
49048
49057
|
// src/suites-scene.ts
|
|
49049
49058
|
import { existsSync as existsSync32, mkdirSync as mkdirSync22, writeFileSync as writeFileSync21 } from "node:fs";
|
|
49050
|
-
import { join as
|
|
49059
|
+
import { join as join42, relative as relative9, sep as sep5 } from "node:path";
|
|
49051
49060
|
function hasSuitesScene(projectPath) {
|
|
49052
|
-
return existsSync32(
|
|
49061
|
+
return existsSync32(join42(projectPath, SUITES_SCENE));
|
|
49053
49062
|
}
|
|
49054
49063
|
function suitesSceneArgs(projectPath, suites) {
|
|
49055
|
-
const runs =
|
|
49064
|
+
const runs = join42(projectPath, ".godot", "gdharness", "suite-scenes");
|
|
49056
49065
|
sweepRunDirectories(runs);
|
|
49057
|
-
const directory =
|
|
49066
|
+
const directory = join42(runs, `${String(STARTED_AT)}-${String(process.pid)}`);
|
|
49058
49067
|
mkdirSync22(directory, { recursive: true });
|
|
49059
|
-
const suitesFile =
|
|
49068
|
+
const suitesFile = join42(directory, "suites.txt");
|
|
49060
49069
|
writeFileSync21(suitesFile, `${suites.join(`
|
|
49061
49070
|
`)}
|
|
49062
49071
|
`);
|
|
@@ -49071,7 +49080,7 @@ function suitesSceneArgs(projectPath, suites) {
|
|
|
49071
49080
|
"-c",
|
|
49072
49081
|
"--ignoreHeadlessMode",
|
|
49073
49082
|
"-rd",
|
|
49074
|
-
`res://${relative9(projectPath,
|
|
49083
|
+
`res://${relative9(projectPath, join42(directory, "reports")).split(sep5).join("/")}`,
|
|
49075
49084
|
"-rc",
|
|
49076
49085
|
"1"
|
|
49077
49086
|
];
|
|
@@ -49085,7 +49094,7 @@ var init_suites_scene = __esm(() => {
|
|
|
49085
49094
|
|
|
49086
49095
|
// src/test-selection.ts
|
|
49087
49096
|
import { existsSync as existsSync33 } from "node:fs";
|
|
49088
|
-
import { basename as basename12, join as
|
|
49097
|
+
import { basename as basename12, join as join43 } from "node:path";
|
|
49089
49098
|
function casesOutOfPath(projectPath, given, tests) {
|
|
49090
49099
|
const entries = Array.isArray(given) ? given : [given];
|
|
49091
49100
|
const cases = [];
|
|
@@ -49129,12 +49138,12 @@ function casesIn(scripts, suite) {
|
|
|
49129
49138
|
}
|
|
49130
49139
|
function scriptsWithoutCases(projectPath, asked) {
|
|
49131
49140
|
const scripts = new ProjectScripts(projectPath);
|
|
49132
|
-
return asked.filter((path) => path.endsWith(".gd") && existsSync33(
|
|
49141
|
+
return asked.filter((path) => path.endsWith(".gd") && existsSync33(join43(projectPath, path.slice("res://".length))) && casesIn(scripts, path).length === 0);
|
|
49133
49142
|
}
|
|
49134
49143
|
function suitesUnder(projectPath, asked) {
|
|
49135
49144
|
const scripts = projectFiles(projectPath, [".gd"]).map((path) => `res://${path}`);
|
|
49136
49145
|
return [
|
|
49137
|
-
...new Set(asked.flatMap((path) => path.endsWith(".gd") ? existsSync33(
|
|
49146
|
+
...new Set(asked.flatMap((path) => path.endsWith(".gd") ? existsSync33(join43(projectPath, path.slice("res://".length))) ? [path] : [] : scripts.filter((script) => script.startsWith(`${path}/`))))
|
|
49138
49147
|
];
|
|
49139
49148
|
}
|
|
49140
49149
|
function selectTests(projectPath, asked, given) {
|
|
@@ -49212,7 +49221,7 @@ import {
|
|
|
49212
49221
|
statSync as statSync20,
|
|
49213
49222
|
writeFileSync as writeFileSync22
|
|
49214
49223
|
} from "node:fs";
|
|
49215
|
-
import { basename as basename13, dirname as dirname25, extname as extname4, isAbsolute as isAbsolute8, join as
|
|
49224
|
+
import { basename as basename13, dirname as dirname25, extname as extname4, isAbsolute as isAbsolute8, join as join44, normalize as normalize2, relative as relative10 } from "node:path";
|
|
49216
49225
|
import { setTimeout as delay7 } from "node:timers/promises";
|
|
49217
49226
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
49218
49227
|
function editorRestartTimeoutMs() {
|
|
@@ -49271,7 +49280,7 @@ function writtenFileRefusal(path, rule) {
|
|
|
49271
49280
|
if (!existsSync34(directory)) {
|
|
49272
49281
|
return `${named}'s directory ${dirname25(path)} does not exist; ${what} creates no directories.`;
|
|
49273
49282
|
}
|
|
49274
|
-
const where =
|
|
49283
|
+
const where = join44(directory, basename13(path));
|
|
49275
49284
|
const inside = rule.projects.find((project) => project !== "" && isWithinRoot(realAsFarAsItExists(project), where));
|
|
49276
49285
|
if (inside !== undefined) {
|
|
49277
49286
|
return `${named} ${path} is inside the project at ${inside}; ${what} is saved outside it, so it never becomes part of the game.`;
|
|
@@ -49918,7 +49927,7 @@ function notRunNote(notRun, failFast) {
|
|
|
49918
49927
|
function presetsIn(projectPath) {
|
|
49919
49928
|
let text;
|
|
49920
49929
|
try {
|
|
49921
|
-
text = readFileSync37(
|
|
49930
|
+
text = readFileSync37(join44(projectPath, "export_presets.cfg"), "utf8");
|
|
49922
49931
|
} catch {
|
|
49923
49932
|
return null;
|
|
49924
49933
|
}
|
|
@@ -49999,7 +50008,7 @@ function filesIn(folder) {
|
|
|
49999
50008
|
try {
|
|
50000
50009
|
for (const entry of readdirSync19(folder, { withFileTypes: true })) {
|
|
50001
50010
|
if (entry.isFile()) {
|
|
50002
|
-
found.set(entry.name, statSync20(
|
|
50011
|
+
found.set(entry.name, statSync20(join44(folder, entry.name)).mtimeMs);
|
|
50003
50012
|
}
|
|
50004
50013
|
}
|
|
50005
50014
|
} catch {}
|
|
@@ -50039,7 +50048,7 @@ function unsavedInEditorNote(scripts) {
|
|
|
50039
50048
|
return `${named} ${one ? "is" : "are"} open in the editor's script ${one ? "tab" : "tabs"} with unsaved edits, and saving ${one ? "that tab" : "them"} there writes ${one ? "its" : "their"} text over what was written here: close ${one ? "it" : "them"} without saving, or save first and edit again.`;
|
|
50040
50049
|
}
|
|
50041
50050
|
function editorAddonMissing(projectPath) {
|
|
50042
|
-
if (!existsSync34(
|
|
50051
|
+
if (!existsSync34(join44(projectPath, "project.godot"))) {
|
|
50043
50052
|
return null;
|
|
50044
50053
|
}
|
|
50045
50054
|
const report = inspectProject(projectPath);
|
|
@@ -50067,7 +50076,7 @@ function rewriteBusNamed(projectPath, from, to) {
|
|
|
50067
50076
|
const giving = [`bus = &"${quoted(from)}"`, `bus = "${quoted(from)}"`];
|
|
50068
50077
|
const rewritten = [];
|
|
50069
50078
|
for (const file of projectFiles(projectPath, [".tscn", ".tres"])) {
|
|
50070
|
-
const absolute =
|
|
50079
|
+
const absolute = join44(projectPath, file);
|
|
50071
50080
|
const lines = readFileSync37(absolute, "utf8").split(`
|
|
50072
50081
|
`);
|
|
50073
50082
|
const at = [];
|
|
@@ -50087,7 +50096,7 @@ function rewriteBusNamed(projectPath, from, to) {
|
|
|
50087
50096
|
}
|
|
50088
50097
|
const namedInScripts = [];
|
|
50089
50098
|
for (const file of projectFiles(projectPath, [".gd"])) {
|
|
50090
|
-
readFileSync37(
|
|
50099
|
+
readFileSync37(join44(projectPath, file), "utf8").split(`
|
|
50091
50100
|
`).forEach((line, index) => {
|
|
50092
50101
|
if (line.includes(`"${from}"`)) {
|
|
50093
50102
|
namedInScripts.push({ file: `res://${file}`, line: index + 1, text: line.trim() });
|
|
@@ -50372,7 +50381,7 @@ function profileFrameFunctions(projectPath) {
|
|
|
50372
50381
|
let projectGodot = null;
|
|
50373
50382
|
if (projectPath !== null) {
|
|
50374
50383
|
try {
|
|
50375
|
-
projectGodot = readFileSync37(
|
|
50384
|
+
projectGodot = readFileSync37(join44(projectPath, "project.godot"), "utf8");
|
|
50376
50385
|
} catch {}
|
|
50377
50386
|
}
|
|
50378
50387
|
return frameFunctionsFor(queuedMessagesOf(projectGodot));
|
|
@@ -50568,7 +50577,7 @@ function foldedEntriesAnswer(log, floor = "warning") {
|
|
|
50568
50577
|
}
|
|
50569
50578
|
function gdUnitFailsOnScriptErrors(projectPath) {
|
|
50570
50579
|
try {
|
|
50571
|
-
return settingKeys(readFileSync37(
|
|
50580
|
+
return settingKeys(readFileSync37(join44(projectPath, "project.godot"), "utf8")).get("gdunit4/report/godot/script_error") !== false;
|
|
50572
50581
|
} catch {
|
|
50573
50582
|
return true;
|
|
50574
50583
|
}
|
|
@@ -50583,7 +50592,7 @@ function uncaughtNote(uncaught) {
|
|
|
50583
50592
|
}
|
|
50584
50593
|
function elsewhereIn(projectPath, asked) {
|
|
50585
50594
|
const wanted = asked.replace(/^res:\/\//, "").replace(/\/+$/, "");
|
|
50586
|
-
if (wanted === "" || existsSync34(
|
|
50595
|
+
if (wanted === "" || existsSync34(join44(projectPath, wanted))) {
|
|
50587
50596
|
return "";
|
|
50588
50597
|
}
|
|
50589
50598
|
const root = (wanted.split("/")[0] ?? "").toLowerCase();
|
|
@@ -50606,7 +50615,7 @@ function windowNoteFor(needing, sharing) {
|
|
|
50606
50615
|
return `${named(needing)} ${one ? "needs" : "need"} a window, as gdharness test reads ${one ? "it" : "them"}, so the run had one: the engine ran without --headless, at the size project.godot gives its viewport, with no sound${process.platform === "win32" ? ", on a desktop of its own, where its window neither shows nor takes the keyboard" : ""}. ${why}${shared}`;
|
|
50607
50616
|
}
|
|
50608
50617
|
function testPathsIn(projectPath, given, named = "path") {
|
|
50609
|
-
const defaults = TEST_DIRECTORIES.filter((directory) => existsSync34(
|
|
50618
|
+
const defaults = TEST_DIRECTORIES.filter((directory) => existsSync34(join44(projectPath, directory)));
|
|
50610
50619
|
const entries = given === undefined || given === null || given === "" ? defaults.length > 0 ? defaults : TEST_DIRECTORIES : given;
|
|
50611
50620
|
const listed = Array.isArray(entries) ? entries : [entries];
|
|
50612
50621
|
if (listed.length === 0) {
|
|
@@ -50737,7 +50746,7 @@ function needsItsOwnProcess(asked) {
|
|
|
50737
50746
|
class GodotServer {
|
|
50738
50747
|
stdio = null;
|
|
50739
50748
|
locator = new GodotLocator;
|
|
50740
|
-
operationsScript =
|
|
50749
|
+
operationsScript = join44(__dirname2, "godot", "operations", "godot_operations.gd");
|
|
50741
50750
|
exportOptionsRead = new Map;
|
|
50742
50751
|
heldWhilePending = new Set;
|
|
50743
50752
|
evaluatedWhilePending = new Set;
|
|
@@ -51009,7 +51018,7 @@ class GodotServer {
|
|
|
51009
51018
|
}
|
|
51010
51019
|
noteTheStart() {
|
|
51011
51020
|
const cwd = process.cwd();
|
|
51012
|
-
const mcpJson =
|
|
51021
|
+
const mcpJson = join44(cwd, ".mcp.json");
|
|
51013
51022
|
const announced = this.ownProject === null ? null : readAnnouncement(announcementPath(this.ownProject));
|
|
51014
51023
|
const predecessor = announced !== null && announced.pid !== process.pid && alive(announced.pid) ? announced.pid : null;
|
|
51015
51024
|
writeLifecycle("started", {
|
|
@@ -51157,7 +51166,7 @@ class GodotServer {
|
|
|
51157
51166
|
return checked.response;
|
|
51158
51167
|
}
|
|
51159
51168
|
const named = args["projectPath"];
|
|
51160
|
-
if (typeof named === "string" && existsSync34(
|
|
51169
|
+
if (typeof named === "string" && existsSync34(join44(named, "project.godot"))) {
|
|
51161
51170
|
this.lastProjectPath = named;
|
|
51162
51171
|
}
|
|
51163
51172
|
this.updates.refresh();
|
|
@@ -51200,7 +51209,7 @@ class GodotServer {
|
|
|
51200
51209
|
let notSaved;
|
|
51201
51210
|
try {
|
|
51202
51211
|
savedAt = answer.content.map((item, index) => {
|
|
51203
|
-
const file =
|
|
51212
|
+
const file = join44(directory, item.type === "text" ? `${stem}-${index}.txt` : `${stem}-${index}.${item.mimeType.split("/")[1] ?? "bin"}`);
|
|
51204
51213
|
writeFileSync22(file, item.type === "text" ? item.text : Buffer.from(item.data, "base64"));
|
|
51205
51214
|
return file;
|
|
51206
51215
|
});
|
|
@@ -51897,7 +51906,7 @@ class GodotServer {
|
|
|
51897
51906
|
if (path === undefined) {
|
|
51898
51907
|
return { ok: false, response: this.createErrorResponse("projectPath is required.") };
|
|
51899
51908
|
}
|
|
51900
|
-
const file =
|
|
51909
|
+
const file = join44(path, "project.godot");
|
|
51901
51910
|
if (!existsSync34(file)) {
|
|
51902
51911
|
return {
|
|
51903
51912
|
ok: false,
|
|
@@ -52779,7 +52788,7 @@ class GodotServer {
|
|
|
52779
52788
|
const platform = presetPlatform(project.value.path, preset);
|
|
52780
52789
|
if (platform !== null) {
|
|
52781
52790
|
const known = await this.exportOptions(platform, {
|
|
52782
|
-
presetsFile:
|
|
52791
|
+
presetsFile: join44(project.value.path, "export_presets.cfg"),
|
|
52783
52792
|
preset,
|
|
52784
52793
|
asked: options
|
|
52785
52794
|
});
|
|
@@ -52830,7 +52839,7 @@ ${platform}`;
|
|
|
52830
52839
|
}
|
|
52831
52840
|
const empty = scratchDirectory("export");
|
|
52832
52841
|
try {
|
|
52833
|
-
writeFileSync22(
|
|
52842
|
+
writeFileSync22(join44(empty, "project.godot"), `config_version=5
|
|
52834
52843
|
`);
|
|
52835
52844
|
const outcome = await runOperation({ godotPath: engine.value, script: this.operationsScript, debug: DEBUG_MODE, editor: true }, "export_options", { platform, ...standing }, empty);
|
|
52836
52845
|
const options = outcome.ok ? outcome.payload["options"] : undefined;
|
|
@@ -52886,7 +52895,7 @@ ${platform}`;
|
|
|
52886
52895
|
const exportArgs = [
|
|
52887
52896
|
"--headless",
|
|
52888
52897
|
"--log-file",
|
|
52889
|
-
|
|
52898
|
+
join44(exportLogs, "engine.log"),
|
|
52890
52899
|
"--path",
|
|
52891
52900
|
project.value.path,
|
|
52892
52901
|
pack ? "--export-pack" : debug ? "--export-debug" : "--export-release",
|
|
@@ -52985,7 +52994,7 @@ ${platform}`;
|
|
|
52985
52994
|
if (movie !== null) {
|
|
52986
52995
|
return this.createErrorResponse(movie);
|
|
52987
52996
|
}
|
|
52988
|
-
const missing = paths.value.filter((path) => !existsSync34(
|
|
52997
|
+
const missing = paths.value.filter((path) => !existsSync34(join44(project.value.path, path.slice("res://".length))));
|
|
52989
52998
|
const projectScripts = new ProjectScripts(project.value.path);
|
|
52990
52999
|
const present = paths.value.filter((path) => !missing.includes(path));
|
|
52991
53000
|
const asked = projectScripts.searchedAsTold(present);
|
|
@@ -53077,10 +53086,10 @@ ${platform}`;
|
|
|
53077
53086
|
const ignored = readStringArray(args, "ignore") ?? [];
|
|
53078
53087
|
const declaredUnder = ignored.length === 0 ? [] : asked.flatMap((path) => path.endsWith(".gd") ? projectScripts.suite(path) ?? [] : projectScripts.suitesUnder([path]));
|
|
53079
53088
|
const userData = scratchDirectory("tests");
|
|
53080
|
-
const suitesFile =
|
|
53081
|
-
const skippingFile =
|
|
53082
|
-
const engineLog =
|
|
53083
|
-
const expectedFile =
|
|
53089
|
+
const suitesFile = join44(userData, "suites.txt");
|
|
53090
|
+
const skippingFile = join44(userData, "skipping.txt");
|
|
53091
|
+
const engineLog = join44(userData, "engine.log");
|
|
53092
|
+
const expectedFile = join44(userData, "expected.json");
|
|
53084
53093
|
writeFileSync22(suitesFile, `${(selection.value?.suites ?? asked).join(`
|
|
53085
53094
|
`)}
|
|
53086
53095
|
`);
|
|
@@ -53121,11 +53130,11 @@ ${platform}`;
|
|
|
53121
53130
|
const timeoutMs = readPositiveNumber(args, "timeoutMs") ?? TEST_TIMEOUT_MS;
|
|
53122
53131
|
this.logDebug(`Running tests: ${engine.value} ${cmdArgs.join(" ")}`);
|
|
53123
53132
|
const helperFiles = {
|
|
53124
|
-
spec:
|
|
53125
|
-
pid:
|
|
53126
|
-
error:
|
|
53127
|
-
stop:
|
|
53128
|
-
step:
|
|
53133
|
+
spec: join44(userData, "spec"),
|
|
53134
|
+
pid: join44(userData, "pid"),
|
|
53135
|
+
error: join44(userData, "error"),
|
|
53136
|
+
stop: join44(userData, "stop"),
|
|
53137
|
+
step: join44(userData, "step")
|
|
53129
53138
|
};
|
|
53130
53139
|
const onDesktop = windowed && process.platform === "win32";
|
|
53131
53140
|
const run = await this.spawnGame(engine.value, cmdArgs, userDataIn(userData), onDesktop ? { directory: project.value.path, files: helperFiles } : undefined);
|
|
@@ -53179,7 +53188,7 @@ ${platform}`;
|
|
|
53179
53188
|
await run.settled;
|
|
53180
53189
|
const helperFailed = onDesktop ? helperFailure(helperFiles.error) ?? (existsSync34(helperFiles.pid) ? null : `it never started, and ${helperStep(helperFiles.step)}`) : null;
|
|
53181
53190
|
if (helperFailed !== null) {
|
|
53182
|
-
discard(
|
|
53191
|
+
discard(join44(project.value.path, ".godot", ...ours.split("/")), userData);
|
|
53183
53192
|
return this.createErrorResponse(`No tests ran: ${named(needing)} ${needing.length === 1 ? "needs" : "need"} a window, and the engine could not be started on a desktop of its own: ${helperFailed}`);
|
|
53184
53193
|
}
|
|
53185
53194
|
const endedAt = Date.now();
|
|
@@ -53190,7 +53199,7 @@ ${platform}`;
|
|
|
53190
53199
|
engine: endedAt - importedAt
|
|
53191
53200
|
};
|
|
53192
53201
|
const notCompiled = stopped.for ?? run.log.all.map((entry) => autoloadNotCompiled(entry, autoloaded)).find((found) => found !== null) ?? null;
|
|
53193
|
-
const reportsDir =
|
|
53202
|
+
const reportsDir = join44(project.value.path, ".godot", ...ours.split("/"));
|
|
53194
53203
|
let report = null;
|
|
53195
53204
|
let reportProblem = null;
|
|
53196
53205
|
const casePrinted = withNestedErrors(readRun(existsSync34(engineLog) ? readFileSync37(engineLog, "utf8") : ""), run.log.all);
|
|
@@ -53199,7 +53208,7 @@ ${platform}`;
|
|
|
53199
53208
|
const written = existsSync34(reportsDir) && notCompiled === null ? readdirSync19(reportsDir).filter((name) => name.startsWith("report_")).sort((a, b) => Number(a.slice("report_".length)) - Number(b.slice("report_".length))) : [];
|
|
53200
53209
|
const newest = written.at(-1);
|
|
53201
53210
|
if (newest !== undefined) {
|
|
53202
|
-
report = parseJUnit(readFileSync37(
|
|
53211
|
+
report = parseJUnit(readFileSync37(join44(reportsDir, newest, "results.xml"), "utf8"));
|
|
53203
53212
|
}
|
|
53204
53213
|
} catch (error) {
|
|
53205
53214
|
reportProblem = errorMessage(error);
|
|
@@ -53604,7 +53613,7 @@ ${error.text}`;
|
|
|
53604
53613
|
const scripts = projectFiles(projectPath, [".gd"]).map((script) => `res://${script}`);
|
|
53605
53614
|
const wanted = `res://${relativePath}`;
|
|
53606
53615
|
const folder = dirname25(relativePath.replaceAll("\\", "/"));
|
|
53607
|
-
const inFolder =
|
|
53616
|
+
const inFolder = join44(projectPath, folder);
|
|
53608
53617
|
const beside = existsSync34(inFolder) ? readdirSync19(inFolder, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => `res://${folder === "." ? "" : `${folder}/`}${entry.name}`) : [];
|
|
53609
53618
|
return this.createErrorResponse(withNearestFiles(`Script file does not exist: ${wanted}`, wanted, scripts, beside));
|
|
53610
53619
|
}
|
|
@@ -54005,7 +54014,7 @@ ${error.text}`;
|
|
|
54005
54014
|
...Array.isArray(stack) ? {
|
|
54006
54015
|
stack: stack.map((frame) => ({
|
|
54007
54016
|
...frame,
|
|
54008
|
-
...projectPath !== "" && typeof frame["script"] === "string" && frame["script"].startsWith("res://") ? { path:
|
|
54017
|
+
...projectPath !== "" && typeof frame["script"] === "string" && frame["script"].startsWith("res://") ? { path: join44(projectPath, frame["script"].slice("res://".length)) } : {}
|
|
54009
54018
|
}))
|
|
54010
54019
|
} : {}
|
|
54011
54020
|
});
|
|
@@ -54350,7 +54359,7 @@ ${error.text}`;
|
|
|
54350
54359
|
return null;
|
|
54351
54360
|
}
|
|
54352
54361
|
try {
|
|
54353
|
-
return settingKeys(readFileSync37(
|
|
54362
|
+
return settingKeys(readFileSync37(join44(projectPath, "project.godot"), "utf8"));
|
|
54354
54363
|
} catch {
|
|
54355
54364
|
return null;
|
|
54356
54365
|
}
|
|
@@ -54695,7 +54704,7 @@ ${error.text}`;
|
|
|
54695
54704
|
if (!paths.ok) {
|
|
54696
54705
|
return refused(paths.reason, PATH_SOLUTIONS);
|
|
54697
54706
|
}
|
|
54698
|
-
const missing = paths.value.filter((path) => !existsSync34(
|
|
54707
|
+
const missing = paths.value.filter((path) => !existsSync34(join44(projectPath, path.slice("res://".length))));
|
|
54699
54708
|
if (missing.length > 0) {
|
|
54700
54709
|
return refused(`Nothing at ${missing.join(" and ")} in the project at ${projectPath}.`, PATH_SOLUTIONS);
|
|
54701
54710
|
}
|
|
@@ -54866,7 +54875,7 @@ ${error.text}`;
|
|
|
54866
54875
|
}
|
|
54867
54876
|
async runtimeUp(projectPath, before, budget, withArgs) {
|
|
54868
54877
|
const budgetMs = budget.ms;
|
|
54869
|
-
if (!existsSync34(
|
|
54878
|
+
if (!existsSync34(join44(projectPath, RUNTIME_SCRIPT))) {
|
|
54870
54879
|
return runtimeVerdict(null, {
|
|
54871
54880
|
addon: false,
|
|
54872
54881
|
budgetMs,
|
|
@@ -55908,7 +55917,7 @@ ${error.text}`;
|
|
|
55908
55917
|
};
|
|
55909
55918
|
const going = await this.runStillGoing(run);
|
|
55910
55919
|
const projectPath = run.projectPath;
|
|
55911
|
-
const projectGone = projectPath !== null && !existsSync34(
|
|
55920
|
+
const projectGone = projectPath !== null && !existsSync34(join44(projectPath, "project.godot"));
|
|
55912
55921
|
if (projectGone && callersName !== undefined) {
|
|
55913
55922
|
return this.createErrorResponse(`callersOf reads the project's scripts, and the run's project at ${projectPath} has no project.godot any more.`, ["editor_run profile without callersOf answers with the profile itself"]);
|
|
55914
55923
|
}
|
|
@@ -56293,7 +56302,7 @@ ${error.text}`;
|
|
|
56293
56302
|
notes.push(endedWithoutACode({
|
|
56294
56303
|
throughEditor: run.throughEditor,
|
|
56295
56304
|
announced: announced !== undefined || run.announcedPid !== undefined,
|
|
56296
|
-
couldAnnounce: run.projectPath !== null && existsSync34(
|
|
56305
|
+
couldAnnounce: run.projectPath !== null && existsSync34(join44(run.projectPath, RUNTIME_SCRIPT)),
|
|
56297
56306
|
endedHere: typeof run.endedHere === "string",
|
|
56298
56307
|
pickedUp: run.pickedUp === true
|
|
56299
56308
|
}));
|
|
@@ -57779,7 +57788,7 @@ ${error.text}`;
|
|
|
57779
57788
|
async ownRunOnItsWay(projectPath, budgetMs) {
|
|
57780
57789
|
const run = await this.currentRun();
|
|
57781
57790
|
const project = projectPath ?? run?.projectPath ?? null;
|
|
57782
|
-
if (run === null || project === null || run.announcedPid !== undefined || run.projectPath !== null && !isSameDirectory(run.projectPath, project) || !existsSync34(
|
|
57791
|
+
if (run === null || project === null || run.announcedPid !== undefined || run.projectPath !== null && !isSameDirectory(run.projectPath, project) || !existsSync34(join44(project, RUNTIME_SCRIPT)) || !await this.runStillGoing(run)) {
|
|
57783
57792
|
return null;
|
|
57784
57793
|
}
|
|
57785
57794
|
const already = runtimesAnnounced().running;
|
|
@@ -57889,7 +57898,7 @@ ${error.text}`;
|
|
|
57889
57898
|
return this.createErrorResponse(staleNote);
|
|
57890
57899
|
}
|
|
57891
57900
|
const screenshotDir = expectsScreenshot ? scratchDirectory("runtime-screenshot") : null;
|
|
57892
|
-
const screenshotPath = screenshotDir ?
|
|
57901
|
+
const screenshotPath = screenshotDir ? join44(screenshotDir, "capture.png") : null;
|
|
57893
57902
|
const refused = (message) => this.createErrorResponse(message);
|
|
57894
57903
|
const onGame = {
|
|
57895
57904
|
pid: choice.endpoint.pid,
|
|
@@ -58228,7 +58237,7 @@ init_bridge_announce();
|
|
|
58228
58237
|
init_engine_launch();
|
|
58229
58238
|
init_engine_slots();
|
|
58230
58239
|
import { existsSync as existsSync35 } from "node:fs";
|
|
58231
|
-
import { dirname as dirname26, join as
|
|
58240
|
+
import { dirname as dirname26, join as join45, resolve as resolve14 } from "node:path";
|
|
58232
58241
|
|
|
58233
58242
|
// src/error-mode.ts
|
|
58234
58243
|
import process8 from "node:process";
|
|
@@ -58268,13 +58277,13 @@ init_lsp_client();
|
|
|
58268
58277
|
init_process_children();
|
|
58269
58278
|
import { existsSync as existsSync17, readdirSync as readdirSync10, readFileSync as readFileSync16, unlinkSync as unlinkSync2 } from "node:fs";
|
|
58270
58279
|
import { connect as connect2 } from "node:net";
|
|
58271
|
-
import { join as
|
|
58280
|
+
import { join as join21, resolve as resolve7 } from "node:path";
|
|
58272
58281
|
var EDITOR_RECORD_PROTOCOL = 1;
|
|
58273
58282
|
var LSP_WAIT_SECONDS = 20;
|
|
58274
58283
|
var HOST = "127.0.0.1";
|
|
58275
58284
|
var LOOK_AGAIN_MS = 500;
|
|
58276
58285
|
function editorRecordsIn(projectPath) {
|
|
58277
|
-
const directory =
|
|
58286
|
+
const directory = join21(projectPath, ".godot", "gdharness-editors");
|
|
58278
58287
|
let names;
|
|
58279
58288
|
try {
|
|
58280
58289
|
names = readdirSync10(directory).filter((name) => /^\d+\.json$/.test(name));
|
|
@@ -58283,7 +58292,7 @@ function editorRecordsIn(projectPath) {
|
|
|
58283
58292
|
}
|
|
58284
58293
|
const records = [];
|
|
58285
58294
|
for (const name of names) {
|
|
58286
|
-
const file =
|
|
58295
|
+
const file = join21(directory, name);
|
|
58287
58296
|
try {
|
|
58288
58297
|
const said = JSON.parse(readFileSync16(file, "utf8"));
|
|
58289
58298
|
const { protocol, pid, lsp_port: lspPort, written_at_ms: writtenAtMs } = said;
|
|
@@ -58378,7 +58387,7 @@ function lspOptionsOf(args, cwd) {
|
|
|
58378
58387
|
}
|
|
58379
58388
|
}
|
|
58380
58389
|
const projectPath = resolve7(cwd, named ?? ".");
|
|
58381
|
-
if (!existsSync17(
|
|
58390
|
+
if (!existsSync17(join21(projectPath, "project.godot"))) {
|
|
58382
58391
|
throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
|
|
58383
58392
|
}
|
|
58384
58393
|
return { projectPath, port, waitSeconds };
|
|
@@ -58485,9 +58494,9 @@ init_setup();
|
|
|
58485
58494
|
init_tool_definitions();
|
|
58486
58495
|
init_tool_reference();
|
|
58487
58496
|
import { existsSync as existsSync19, mkdirSync as mkdirSync7, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync11 } from "node:fs";
|
|
58488
|
-
import { basename as basename8, dirname as dirname10, join as
|
|
58497
|
+
import { basename as basename8, dirname as dirname10, join as join23 } from "node:path";
|
|
58489
58498
|
var SKILL_NAME = "gdharness";
|
|
58490
|
-
var SHARED_SKILLS =
|
|
58499
|
+
var SHARED_SKILLS = join23(".agents", "skills");
|
|
58491
58500
|
function skillMarkdown(version) {
|
|
58492
58501
|
return `---
|
|
58493
58502
|
name: ${SKILL_NAME}
|
|
@@ -58728,27 +58737,27 @@ what they report while starting comes back under \`engine_messages_before_operat
|
|
|
58728
58737
|
function skillFiles(version) {
|
|
58729
58738
|
return new Map([
|
|
58730
58739
|
["SKILL.md", skillMarkdown(version)],
|
|
58731
|
-
[
|
|
58740
|
+
[join23("references", "tools.md"), renderToolsMarkdown()]
|
|
58732
58741
|
]);
|
|
58733
58742
|
}
|
|
58734
58743
|
function skillDirectories(harnesses, projectPath, exists) {
|
|
58735
|
-
const directories = [
|
|
58744
|
+
const directories = [join23(projectPath, SHARED_SKILLS, SKILL_NAME)];
|
|
58736
58745
|
for (const harness of harnesses) {
|
|
58737
58746
|
if (harness.skills === undefined) {
|
|
58738
58747
|
continue;
|
|
58739
58748
|
}
|
|
58740
|
-
const own =
|
|
58741
|
-
if ((!harness.skills.shared || exists(own)) && !directories.includes(
|
|
58742
|
-
directories.push(
|
|
58749
|
+
const own = join23(projectPath, harness.skills.dir);
|
|
58750
|
+
if ((!harness.skills.shared || exists(own)) && !directories.includes(join23(own, SKILL_NAME))) {
|
|
58751
|
+
directories.push(join23(own, SKILL_NAME));
|
|
58743
58752
|
}
|
|
58744
58753
|
}
|
|
58745
58754
|
return directories;
|
|
58746
58755
|
}
|
|
58747
58756
|
function everySkillDirectory(projectPath, harnesses) {
|
|
58748
|
-
const directories = new Set([
|
|
58757
|
+
const directories = new Set([join23(projectPath, SHARED_SKILLS, SKILL_NAME)]);
|
|
58749
58758
|
for (const harness of harnesses) {
|
|
58750
58759
|
if (harness.skills !== undefined) {
|
|
58751
|
-
directories.add(
|
|
58760
|
+
directories.add(join23(projectPath, harness.skills.dir, SKILL_NAME));
|
|
58752
58761
|
}
|
|
58753
58762
|
}
|
|
58754
58763
|
return [...directories];
|
|
@@ -58765,7 +58774,7 @@ function removeSkill(directories, projectPath) {
|
|
|
58765
58774
|
return removed;
|
|
58766
58775
|
}
|
|
58767
58776
|
function pruneEmpty(directory, projectPath) {
|
|
58768
|
-
const shared =
|
|
58777
|
+
const shared = join23(projectPath, ".agents");
|
|
58769
58778
|
let path = directory;
|
|
58770
58779
|
while (path !== projectPath && (basename8(path) === "skills" || path === shared)) {
|
|
58771
58780
|
if (readdirSync12(path).length > 0) {
|
|
@@ -58781,7 +58790,7 @@ function writeSkill(directories, version) {
|
|
|
58781
58790
|
const replaced = existsSync19(directory);
|
|
58782
58791
|
rmSync10(directory, { recursive: true, force: true });
|
|
58783
58792
|
for (const [name, contents] of files) {
|
|
58784
|
-
const path =
|
|
58793
|
+
const path = join23(directory, name);
|
|
58785
58794
|
mkdirSync7(dirname10(path), { recursive: true });
|
|
58786
58795
|
writeFileSync11(path, contents, "utf8");
|
|
58787
58796
|
}
|
|
@@ -58796,7 +58805,7 @@ init_setup();
|
|
|
58796
58805
|
init_suite_judge();
|
|
58797
58806
|
import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync19, rmSync as rmSync11 } from "node:fs";
|
|
58798
58807
|
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
58799
|
-
import { join as
|
|
58808
|
+
import { join as join24, resolve as resolve9 } from "node:path";
|
|
58800
58809
|
import process13 from "node:process";
|
|
58801
58810
|
var SHARE = "--gdh-share=";
|
|
58802
58811
|
var GATHER = "--gdh-share-gather=";
|
|
@@ -58836,9 +58845,9 @@ function spreadOptionsOf(args, cwd) {
|
|
|
58836
58845
|
}
|
|
58837
58846
|
const first = positional[0];
|
|
58838
58847
|
const named = first === undefined ? null : resolve9(cwd, first);
|
|
58839
|
-
const projectNamed = named !== null && existsSync20(
|
|
58848
|
+
const projectNamed = named !== null && existsSync20(join24(named, "project.godot"));
|
|
58840
58849
|
const projectPath = projectNamed ? named : resolve9(cwd);
|
|
58841
|
-
if (!existsSync20(
|
|
58850
|
+
if (!existsSync20(join24(projectPath, "project.godot"))) {
|
|
58842
58851
|
throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
|
|
58843
58852
|
}
|
|
58844
58853
|
const scenes = positional.slice(projectNamed ? 1 : 0);
|
|
@@ -58846,7 +58855,7 @@ function spreadOptionsOf(args, cwd) {
|
|
|
58846
58855
|
throw new EngineUsageError(scenes.length === 0 ? "gdharness spread needs the scene of the bench to play." : `gdharness spread plays one scene, and was given ${String(scenes.length)}: ${scenes.join(", ")}.`);
|
|
58847
58856
|
}
|
|
58848
58857
|
const scene = resPathOf(scenes[0] ?? "", projectPath, cwd);
|
|
58849
|
-
if (!existsSync20(
|
|
58858
|
+
if (!existsSync20(join24(projectPath, scene.slice("res://".length)))) {
|
|
58850
58859
|
throw new EngineUsageError(`Nothing at ${scene} in the project at ${projectPath}.`);
|
|
58851
58860
|
}
|
|
58852
58861
|
const benchArguments = dashes === -1 ? [] : args.slice(dashes + 1);
|
|
@@ -58917,14 +58926,14 @@ function shareFaults(played) {
|
|
|
58917
58926
|
return faults;
|
|
58918
58927
|
}
|
|
58919
58928
|
async function runSpreadCommand(options, godotPath) {
|
|
58920
|
-
if (!existsSync20(
|
|
58929
|
+
if (!existsSync20(join24(options.projectPath, SHARE_SCRIPT))) {
|
|
58921
58930
|
throw new EngineUsageError(`res://${SHARE_SCRIPT} is not in the project, so its bench cannot ask GdhShare for outcomes. Run gdharness setup.`);
|
|
58922
58931
|
}
|
|
58923
58932
|
const startedAt = Date.now();
|
|
58924
|
-
const spreadRuns =
|
|
58933
|
+
const spreadRuns = join24(options.projectPath, ".godot", "gdharness", "spread-runs");
|
|
58925
58934
|
sweepRunDirectories(spreadRuns);
|
|
58926
|
-
const runDirectory =
|
|
58927
|
-
const shareDirectory =
|
|
58935
|
+
const runDirectory = join24(spreadRuns, `${String(startedAt)}-${String(process13.pid)}`);
|
|
58936
|
+
const shareDirectory = join24(runDirectory, "share");
|
|
58928
58937
|
mkdirSync8(shareDirectory, { recursive: true });
|
|
58929
58938
|
const chosen = machineSlots({ directory: options.slotsDirectory, count: options.slotCount });
|
|
58930
58939
|
const slotCount = chosen.count;
|
|
@@ -58963,7 +58972,7 @@ async function runSpreadCommand(options, godotPath) {
|
|
|
58963
58972
|
share,
|
|
58964
58973
|
`${INTO}${shareDirectory}`
|
|
58965
58974
|
]);
|
|
58966
|
-
const logs = Array.from({ length: workers }, (_, index) =>
|
|
58975
|
+
const logs = Array.from({ length: workers }, (_, index) => join24(runDirectory, `worker-${String(index)}`, "engine.log"));
|
|
58967
58976
|
let done = 0;
|
|
58968
58977
|
const heartbeat = setInterval(() => {
|
|
58969
58978
|
console.log(`[spread] ${progressOf(logs)}`);
|
|
@@ -58981,7 +58990,7 @@ async function runSpreadCommand(options, godotPath) {
|
|
|
58981
58990
|
}
|
|
58982
58991
|
const faults = left.flatMap((worker) => engineFaults(worker, options.godotVersion));
|
|
58983
58992
|
const arms = left.map((_, index) => {
|
|
58984
|
-
const file =
|
|
58993
|
+
const file = join24(shareDirectory, `worker-${String(index)}.arms`);
|
|
58985
58994
|
return existsSync20(file) ? armsPlayed(readFileSync19(file, "utf8")) : [];
|
|
58986
58995
|
});
|
|
58987
58996
|
faults.push(...shareFaults(arms));
|
|
@@ -58991,7 +59000,7 @@ async function runSpreadCommand(options, godotPath) {
|
|
|
58991
59000
|
const gather = await engine("gather", `${GATHER}${String(workers)}`);
|
|
58992
59001
|
console.log(readFileSync19(gather.log, "utf8").replace(CONTROL_SEQUENCE, "").trimEnd());
|
|
58993
59002
|
const gatherFaults = engineFaults(gather, options.godotVersion);
|
|
58994
|
-
const gatheredFile =
|
|
59003
|
+
const gatheredFile = join24(shareDirectory, "gathered.arms");
|
|
58995
59004
|
const gathered = new Set((existsSync20(gatheredFile) ? armsPlayed(readFileSync19(gatheredFile, "utf8")) ?? [] : []).map((arm) => arm.arm));
|
|
58996
59005
|
const ungathered = (arms[0] ?? []).filter((arm) => !gathered.has(arm.arm)).map((arm) => arm.arm);
|
|
58997
59006
|
if (ungathered.length > 0) {
|
|
@@ -59012,9 +59021,9 @@ async function runSpreadCommand(options, godotPath) {
|
|
|
59012
59021
|
}
|
|
59013
59022
|
}
|
|
59014
59023
|
async function played(launch, slots, options, runDirectory, name, benchArguments) {
|
|
59015
|
-
const directory =
|
|
59016
|
-
mkdirSync8(
|
|
59017
|
-
const log =
|
|
59024
|
+
const directory = join24(runDirectory, name);
|
|
59025
|
+
mkdirSync8(join24(directory, "user"), { recursive: true });
|
|
59026
|
+
const log = join24(directory, "engine.log");
|
|
59018
59027
|
const args = [
|
|
59019
59028
|
"--headless",
|
|
59020
59029
|
"--audio-driver",
|
|
@@ -59097,14 +59106,14 @@ import {
|
|
|
59097
59106
|
writeFileSync as writeFileSync12
|
|
59098
59107
|
} from "node:fs";
|
|
59099
59108
|
import { availableParallelism as availableParallelism4 } from "node:os";
|
|
59100
|
-
import { dirname as dirname13, join as
|
|
59109
|
+
import { dirname as dirname13, join as join28, relative as relative5, resolve as resolve10, sep as sep4 } from "node:path";
|
|
59101
59110
|
import process14 from "node:process";
|
|
59102
59111
|
|
|
59103
59112
|
// src/suite-fingerprint.ts
|
|
59104
59113
|
init_class_cache();
|
|
59105
59114
|
import { createHash as createHash6 } from "node:crypto";
|
|
59106
59115
|
import { existsSync as existsSync21, readdirSync as readdirSync13, readFileSync as readFileSync20, statSync as statSync13 } from "node:fs";
|
|
59107
|
-
import { join as
|
|
59116
|
+
import { join as join25, posix as posix2 } from "node:path";
|
|
59108
59117
|
var RES_LITERAL = /res:\/\/[^"'\s)\]<>]*/g;
|
|
59109
59118
|
var RELATIVE_LOAD = /\b(?:pre)?load\(\s*["']((?!res:\/\/|uid:\/\/)[^"']+)["']/g;
|
|
59110
59119
|
var REACHES_AT_RUN_TIME = [
|
|
@@ -59163,7 +59172,7 @@ ${this.read(path).digest}
|
|
|
59163
59172
|
const hash = createHash6("sha256");
|
|
59164
59173
|
const walk = (directory, under) => {
|
|
59165
59174
|
for (const entry of readdirSync13(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
59166
|
-
const file =
|
|
59175
|
+
const file = join25(directory, entry.name);
|
|
59167
59176
|
if (entry.isDirectory()) {
|
|
59168
59177
|
walk(file, `${under}${entry.name}/`);
|
|
59169
59178
|
} else if (entry.isFile()) {
|
|
@@ -59172,7 +59181,7 @@ ${this.read(path).digest}
|
|
|
59172
59181
|
}
|
|
59173
59182
|
}
|
|
59174
59183
|
};
|
|
59175
|
-
const directory =
|
|
59184
|
+
const directory = join25(this.scripts.projectPath, root.slice("res://".length));
|
|
59176
59185
|
if (existsSync21(directory)) {
|
|
59177
59186
|
walk(directory, "");
|
|
59178
59187
|
}
|
|
@@ -59182,7 +59191,7 @@ ${this.read(path).digest}
|
|
|
59182
59191
|
if (PLACEHOLDER.test(path)) {
|
|
59183
59192
|
return { digest: "", reaches: [], unreadable: `${path} is filled in at run time` };
|
|
59184
59193
|
}
|
|
59185
|
-
const file =
|
|
59194
|
+
const file = join25(this.scripts.projectPath, path.slice("res://".length));
|
|
59186
59195
|
if (!existsSync21(file)) {
|
|
59187
59196
|
return { digest: "missing", reaches: [], unreadable: null };
|
|
59188
59197
|
}
|
|
@@ -59231,7 +59240,7 @@ ${this.read(path).digest}
|
|
|
59231
59240
|
}
|
|
59232
59241
|
}
|
|
59233
59242
|
function extensionsOf(projectPath) {
|
|
59234
|
-
const list =
|
|
59243
|
+
const list = join25(projectPath, ".godot", "extension_list.cfg");
|
|
59235
59244
|
return existsSync21(list) ? readFileSync20(list, "utf8").split(`
|
|
59236
59245
|
`).map((line) => line.trim()).filter((line) => line.startsWith("res://")) : [];
|
|
59237
59246
|
}
|
|
@@ -59242,13 +59251,13 @@ init_suite_plan();
|
|
|
59242
59251
|
|
|
59243
59252
|
// src/version.ts
|
|
59244
59253
|
import { readFileSync as readFileSync22 } from "node:fs";
|
|
59245
|
-
import { dirname as dirname12, join as
|
|
59254
|
+
import { dirname as dirname12, join as join27 } from "node:path";
|
|
59246
59255
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
59247
59256
|
function getLocalVersion() {
|
|
59248
59257
|
const currentDirectory = dirname12(fileURLToPath3(import.meta.url));
|
|
59249
59258
|
const packageCandidates = [
|
|
59250
|
-
|
|
59251
|
-
|
|
59259
|
+
join27(currentDirectory, "..", "package.json"),
|
|
59260
|
+
join27(currentDirectory, "..", "..", "package.json")
|
|
59252
59261
|
];
|
|
59253
59262
|
for (const packagePath of packageCandidates) {
|
|
59254
59263
|
try {
|
|
@@ -59319,9 +59328,9 @@ function testOptionsOf(args, cwd) {
|
|
|
59319
59328
|
}
|
|
59320
59329
|
const first = positional[0];
|
|
59321
59330
|
const named = first === undefined ? null : resolve10(cwd, first);
|
|
59322
|
-
const projectNamed = named !== null && existsSync23(
|
|
59331
|
+
const projectNamed = named !== null && existsSync23(join28(named, "project.godot"));
|
|
59323
59332
|
const projectPath = projectNamed ? named : resolve10(cwd);
|
|
59324
|
-
if (!existsSync23(
|
|
59333
|
+
if (!existsSync23(join28(projectPath, "project.godot"))) {
|
|
59325
59334
|
throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
|
|
59326
59335
|
}
|
|
59327
59336
|
const last = (flag) => valued.get(flag)?.at(-1);
|
|
@@ -59355,11 +59364,11 @@ function seedOf(value) {
|
|
|
59355
59364
|
return seed;
|
|
59356
59365
|
}
|
|
59357
59366
|
function rootsOf(options) {
|
|
59358
|
-
return options.roots.length > 0 ? options.roots : TEST_DIRECTORIES.filter((root) => existsSync23(
|
|
59367
|
+
return options.roots.length > 0 ? options.roots : TEST_DIRECTORIES.filter((root) => existsSync23(join28(options.projectPath, root))).map((root) => `res://${root}`);
|
|
59359
59368
|
}
|
|
59360
59369
|
function searchedRoots(options) {
|
|
59361
59370
|
return options.selected.length === 0 ? rootsOf(options) : options.selected.filter((entry) => {
|
|
59362
|
-
const directory =
|
|
59371
|
+
const directory = join28(options.projectPath, entry.slice("res://".length));
|
|
59363
59372
|
return existsSync23(directory) && statSync14(directory).isDirectory();
|
|
59364
59373
|
});
|
|
59365
59374
|
}
|
|
@@ -59376,7 +59385,7 @@ function selectedSuites(scripts, options) {
|
|
|
59376
59385
|
for (const entry of options.selected) {
|
|
59377
59386
|
const caseAt = /^(res:\/\/.*\.gd):(\w+)$/.exec(entry);
|
|
59378
59387
|
const path = caseAt?.[1] ?? entry;
|
|
59379
|
-
const directory =
|
|
59388
|
+
const directory = join28(options.projectPath, path.slice(6));
|
|
59380
59389
|
const suites = existsSync23(directory) && statSync14(directory).isDirectory() ? scripts.suitesUnder([path.replace(/\/$/, "")]) : [scripts.suite(path)].filter((suite) => suite !== null);
|
|
59381
59390
|
if (suites.length === 0) {
|
|
59382
59391
|
throw new EngineUsageError(existsSync23(directory) ? `${path} holds no gdUnit4 suite: nothing there extends GdUnitTestSuite and declares a test_ function.` : `Nothing at ${path} in the project at ${options.projectPath}.`);
|
|
@@ -59433,7 +59442,7 @@ class RunLogs {
|
|
|
59433
59442
|
return this.kept ?? this.directory;
|
|
59434
59443
|
}
|
|
59435
59444
|
named(path) {
|
|
59436
|
-
return this.kept === null ? path :
|
|
59445
|
+
return this.kept === null ? path : join28(this.kept, relative5(this.directory, path));
|
|
59437
59446
|
}
|
|
59438
59447
|
keep() {
|
|
59439
59448
|
if (this.kept === null) {
|
|
@@ -59441,8 +59450,8 @@ class RunLogs {
|
|
|
59441
59450
|
}
|
|
59442
59451
|
for (const file of readdirSync14(this.directory, { recursive: true, encoding: "utf8" })) {
|
|
59443
59452
|
if (file.endsWith(".log") && file.split(sep4).length === 2) {
|
|
59444
|
-
mkdirSync10(dirname13(
|
|
59445
|
-
copyFileSync(
|
|
59453
|
+
mkdirSync10(dirname13(join28(this.kept, file)), { recursive: true });
|
|
59454
|
+
copyFileSync(join28(this.directory, file), join28(this.kept, file));
|
|
59446
59455
|
}
|
|
59447
59456
|
}
|
|
59448
59457
|
}
|
|
@@ -59455,24 +59464,24 @@ async function runTestCommand(options, godotPath) {
|
|
|
59455
59464
|
const startedAt = Date.now();
|
|
59456
59465
|
const scripts = new ProjectScripts(options.projectPath);
|
|
59457
59466
|
const home = homeOf(options.projectPath);
|
|
59458
|
-
const state =
|
|
59459
|
-
const timesFile =
|
|
59460
|
-
const passedFile =
|
|
59461
|
-
const lastRunFile =
|
|
59467
|
+
const state = join28(home, ".godot", "gdharness");
|
|
59468
|
+
const timesFile = join28(state, "suite-times.json");
|
|
59469
|
+
const passedFile = join28(state, "suite-passed.json");
|
|
59470
|
+
const lastRunFile = join28(state, LAST_RUN_FILE);
|
|
59462
59471
|
let suites = selectedSuites(scripts, options);
|
|
59463
59472
|
const uncollected = uncollectedSaid(scripts.uncollectedUnder(searchedRoots(options)));
|
|
59464
59473
|
const wholeSuites = suites.map((suite) => scripts.suite(suite.path) ?? suite);
|
|
59465
59474
|
const declared = new Map(wholeSuites.map((suite) => [suite.path, suite.cases]));
|
|
59466
|
-
const testRuns =
|
|
59467
|
-
const keptRuns =
|
|
59475
|
+
const testRuns = join28(options.projectPath, ".godot", "gdharness", "test-runs");
|
|
59476
|
+
const keptRuns = join28(state, "test-runs");
|
|
59468
59477
|
sweepRunDirectories(testRuns);
|
|
59469
59478
|
if (keptRuns !== testRuns) {
|
|
59470
59479
|
sweepRunDirectories(keptRuns);
|
|
59471
59480
|
}
|
|
59472
59481
|
const runName = `${String(startedAt)}-${String(process14.pid)}`;
|
|
59473
|
-
const runDirectory =
|
|
59482
|
+
const runDirectory = join28(testRuns, runName);
|
|
59474
59483
|
mkdirSync10(runDirectory, { recursive: true });
|
|
59475
|
-
const logs = new RunLogs(runDirectory, keptRuns === testRuns ? null :
|
|
59484
|
+
const logs = new RunLogs(runDirectory, keptRuns === testRuns ? null : join28(keptRuns, runName));
|
|
59476
59485
|
const chosen = machineSlots({ directory: options.slotsDirectory, count: options.slotCount });
|
|
59477
59486
|
const slots = new EngineSlots(chosen.directory, chosen.count, { pid: process14.pid, started: await ownStart(), by: `gdharness test of ${options.projectPath}` }, (line) => {
|
|
59478
59487
|
console.log(line);
|
|
@@ -59680,9 +59689,9 @@ async function importProject(launch) {
|
|
|
59680
59689
|
console.log("The import was skipped: every imported file and the class cache are current.");
|
|
59681
59690
|
return null;
|
|
59682
59691
|
}
|
|
59683
|
-
const directory =
|
|
59684
|
-
mkdirSync10(
|
|
59685
|
-
const log =
|
|
59692
|
+
const directory = join28(launch.runDirectory, "import");
|
|
59693
|
+
mkdirSync10(join28(directory, "user"), { recursive: true });
|
|
59694
|
+
const log = join28(directory, "import.log");
|
|
59686
59695
|
const lock = await launch.slots.take();
|
|
59687
59696
|
try {
|
|
59688
59697
|
freeLibraryCopies(launch.projectPath);
|
|
@@ -59747,12 +59756,12 @@ async function runShares(launch, units, declared, lanes, taken, times) {
|
|
|
59747
59756
|
return (await Promise.all(Array.from({ length: lanes }, (_, at) => lane(at)))).flat().sort((a, b) => a.index - b.index);
|
|
59748
59757
|
}
|
|
59749
59758
|
async function runEngine2(launch, plan, index, times, again = "", slot = null) {
|
|
59750
|
-
const directory =
|
|
59751
|
-
mkdirSync10(
|
|
59752
|
-
const suitesFile =
|
|
59753
|
-
const skippingFile =
|
|
59754
|
-
const rowsFile =
|
|
59755
|
-
const expectedFile =
|
|
59759
|
+
const directory = join28(launch.runDirectory, `engine-${String(index)}${again === "" ? "" : `-${again}`}`);
|
|
59760
|
+
mkdirSync10(join28(directory, "user"), { recursive: true });
|
|
59761
|
+
const suitesFile = join28(directory, "suites.txt");
|
|
59762
|
+
const skippingFile = join28(directory, "skipping.txt");
|
|
59763
|
+
const rowsFile = join28(directory, "rows.txt");
|
|
59764
|
+
const expectedFile = join28(directory, "expected.json");
|
|
59756
59765
|
writeFileSync12(suitesFile, `${plan.suites.map((suite) => suite.path).join(`
|
|
59757
59766
|
`)}
|
|
59758
59767
|
`);
|
|
@@ -59779,7 +59788,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
|
|
|
59779
59788
|
...plan.windowed ? [] : ["--ignoreHeadlessMode"],
|
|
59780
59789
|
"-c",
|
|
59781
59790
|
"-rd",
|
|
59782
|
-
`res://${relative5(launch.projectPath,
|
|
59791
|
+
`res://${relative5(launch.projectPath, join28(directory, "reports")).split(sep4).join("/")}`,
|
|
59783
59792
|
"-rc",
|
|
59784
59793
|
"1",
|
|
59785
59794
|
"--",
|
|
@@ -59795,7 +59804,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
|
|
|
59795
59804
|
"--expected-out",
|
|
59796
59805
|
expectedFile
|
|
59797
59806
|
];
|
|
59798
|
-
const log =
|
|
59807
|
+
const log = join28(directory, "engine.log");
|
|
59799
59808
|
const lock = slot ?? await launch.slots.take();
|
|
59800
59809
|
const began = Date.now();
|
|
59801
59810
|
let end;
|
|
@@ -59814,7 +59823,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
|
|
|
59814
59823
|
godotVersion: launch.godotVersion
|
|
59815
59824
|
};
|
|
59816
59825
|
const judged = judgeEngine(printed, assignment, end);
|
|
59817
|
-
const written = reportsFault(
|
|
59826
|
+
const written = reportsFault(join28(directory, "reports"));
|
|
59818
59827
|
return {
|
|
59819
59828
|
index,
|
|
59820
59829
|
plan,
|
|
@@ -59828,7 +59837,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
|
|
|
59828
59837
|
}
|
|
59829
59838
|
var REPORT_FILES_NAMED = 3;
|
|
59830
59839
|
function reportsFault(reports) {
|
|
59831
|
-
const files = existsSync23(reports) ? readdirSync14(reports, { recursive: true, encoding: "utf8" }).filter((file) => statSync14(
|
|
59840
|
+
const files = existsSync23(reports) ? readdirSync14(reports, { recursive: true, encoding: "utf8" }).filter((file) => statSync14(join28(reports, file)).isFile()).sort() : [];
|
|
59832
59841
|
if (files.length === 0) {
|
|
59833
59842
|
return null;
|
|
59834
59843
|
}
|
|
@@ -59986,7 +59995,7 @@ class UsageError extends Refusal {
|
|
|
59986
59995
|
function projectArgument(at) {
|
|
59987
59996
|
const named = args.slice(at).find((value) => !value.startsWith("--"));
|
|
59988
59997
|
const projectPath = resolve14(named ?? ".");
|
|
59989
|
-
if (!existsSync35(
|
|
59998
|
+
if (!existsSync35(join45(projectPath, "project.godot"))) {
|
|
59990
59999
|
throw new UsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
|
|
59991
60000
|
}
|
|
59992
60001
|
return projectPath;
|
|
@@ -60050,7 +60059,7 @@ async function registerRuntime(godot, projectPath) {
|
|
|
60050
60059
|
}
|
|
60051
60060
|
const path = (named ?? "").replace(/^res:\/\//, "");
|
|
60052
60061
|
console.log(`${RUNTIME_AUTOLOAD.name} autoload left at ${named}, which this project registers itself`);
|
|
60053
|
-
if (!existsSync35(
|
|
60062
|
+
if (!existsSync35(join45(projectPath, path))) {
|
|
60054
60063
|
console.log(" that file is not in this project, so it boots with a missing script");
|
|
60055
60064
|
}
|
|
60056
60065
|
console.log(` ${useTheShippedLoader(RUNTIME_AUTOLOAD.name, path)}`);
|