gdharness 1.1.30 → 1.1.32
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 +1950 -157
- package/build/godot/addons/gdharness_editor/bridge_client.gd +6 -0
- package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +9 -0
- package/build/godot/operations/godot_operations.gd +5 -0
- package/build/godot/operations/rename_checks.gd +80 -0
- package/build/index.js +1989 -213
- package/package.json +1 -1
|
@@ -25,6 +25,10 @@ const MAX_RECONNECT_DELAY: float = 30.0
|
|
|
25
25
|
## What a server closes with when the editor that said hello belongs to another project. Kept in
|
|
26
26
|
## step with `OTHER_PROJECT_CLOSE_CODE` in src/godot-bridge.ts.
|
|
27
27
|
const ELSEWHERE_CLOSE_CODE: int = 4001
|
|
28
|
+
## What a server closes with when this process is one job that quits, such as a gate's `--import`,
|
|
29
|
+
## rather than an editor: dialling in again changes nothing for the rest of the run. Kept in step
|
|
30
|
+
## with `ONE_SHOT_CLOSE_CODE` in src/godot-bridge.ts.
|
|
31
|
+
const ONE_SHOT_CLOSE_CODE: int = 4002
|
|
28
32
|
|
|
29
33
|
## Where Godot keeps the three ports an editor serves. None of them is per editor: the settings
|
|
30
34
|
## file is one for every editor of this engine version on the machine, so two open at once want the
|
|
@@ -447,6 +451,8 @@ func _read_marker(path: String) -> String:
|
|
|
447
451
|
func _handle_disconnect() -> void:
|
|
448
452
|
_is_connected = false
|
|
449
453
|
_said_elsewhere()
|
|
454
|
+
if socket.get_close_code() == ONE_SHOT_CLOSE_CODE:
|
|
455
|
+
_should_reconnect = false
|
|
450
456
|
disconnected.emit()
|
|
451
457
|
|
|
452
458
|
if _should_reconnect:
|
|
@@ -63,6 +63,15 @@ func rescan_filesystem(args: Dictionary) -> Dictionary:
|
|
|
63
63
|
var uids: Dictionary = {"reread": [], "duplicated": []}
|
|
64
64
|
if not Read.as_bool(args.get("statusOnly", false)) and not busy:
|
|
65
65
|
uids = _reread_changed_uids(filesystem)
|
|
66
|
+
# Files the caller has just written, moved or deleted, read again one by one. The scan finds a
|
|
67
|
+
# script that appeared and leaves the global class of one that has gone in the editor's list,
|
|
68
|
+
# which it then writes back into the class cache at a path that is not there; reading the gone
|
|
69
|
+
# path again is what drops it.
|
|
70
|
+
var named: Variant = args.get("updateFiles", [])
|
|
71
|
+
if named is Array:
|
|
72
|
+
var paths: Array = named
|
|
73
|
+
for path: Variant in paths:
|
|
74
|
+
filesystem.update_file(str(path))
|
|
66
75
|
filesystem.scan()
|
|
67
76
|
# Whether the scan ran, read off the editor rather than assumed. `scan()` returns without
|
|
68
77
|
# a word while the thread of the scan before is still to be joined, which is a frame or
|
|
@@ -26,6 +26,7 @@ const Log = preload("logger.gd")
|
|
|
26
26
|
const Plugins = preload("plugins.gd")
|
|
27
27
|
const ProjectConfig = preload("project_config.gd")
|
|
28
28
|
const ProjectDiagnostics = preload("project_diagnostics.gd")
|
|
29
|
+
const RenameChecks = preload("rename_checks.gd")
|
|
29
30
|
const ResourceFiles = preload("resource_files.gd")
|
|
30
31
|
|
|
31
32
|
var _log: Log
|
|
@@ -171,6 +172,10 @@ func _run(operation: String, params: Dictionary) -> Dictionary:
|
|
|
171
172
|
payload = GdscriptAuthoring.new(_log).modify_gdscript(params)
|
|
172
173
|
"get_script_info":
|
|
173
174
|
payload = GdscriptAnalysis.new(_log).get_gdscript_info(params)
|
|
175
|
+
"names_taken":
|
|
176
|
+
payload = RenameChecks.new(_log).names_taken(params)
|
|
177
|
+
"check_scripts":
|
|
178
|
+
payload = RenameChecks.new(_log).check_scripts(params)
|
|
174
179
|
|
|
175
180
|
# Plugins and input
|
|
176
181
|
"list_plugins":
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
extends RefCounted
|
|
2
|
+
|
|
3
|
+
const GdscriptAuthoring = preload("gdscript_authoring.gd")
|
|
4
|
+
const Log = preload("logger.gd")
|
|
5
|
+
|
|
6
|
+
var _log: Log
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
func _init(p_log: Log) -> void:
|
|
10
|
+
_log = p_log
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# What each of the names asked about already is to the engine, and which class in the native
|
|
14
|
+
# chain from the base asked about declares it. A file cannot answer either: the native classes, the
|
|
15
|
+
# built-in types and the singletons are compiled into the engine, and a rename onto one of them is
|
|
16
|
+
# a script that no longer compiles, or one that quietly overrides an engine method.
|
|
17
|
+
func names_taken(params: Dictionary) -> Dictionary:
|
|
18
|
+
var names: Array = params.get("names", [])
|
|
19
|
+
var base: String = str(params.get("base", ""))
|
|
20
|
+
var built_in_types: Array[String] = []
|
|
21
|
+
for type: int in range(TYPE_MAX):
|
|
22
|
+
built_in_types.append(type_string(type))
|
|
23
|
+
var singletons: PackedStringArray = Engine.get_singleton_list()
|
|
24
|
+
var taken: Dictionary = {}
|
|
25
|
+
for value: Variant in names:
|
|
26
|
+
var name: String = str(value)
|
|
27
|
+
var as_what: Array[String] = []
|
|
28
|
+
if ClassDB.class_exists(name):
|
|
29
|
+
as_what.append("a native class")
|
|
30
|
+
if name in built_in_types:
|
|
31
|
+
as_what.append("a built-in type")
|
|
32
|
+
if singletons.has(name):
|
|
33
|
+
as_what.append("an engine singleton")
|
|
34
|
+
var entry: Dictionary = {"as": as_what, "declaredBy": null}
|
|
35
|
+
var declared_by: String = _declared_in_chain(base, name)
|
|
36
|
+
if not declared_by.is_empty():
|
|
37
|
+
entry["declaredBy"] = declared_by
|
|
38
|
+
taken[name] = entry
|
|
39
|
+
return {"taken": taken}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# The native class from [param base] upwards that declares [param name] as a method, property,
|
|
43
|
+
# signal, constant or enum, or empty when none does. Methods are read off the method list rather
|
|
44
|
+
# than asked with class_has_method, which answers false for a virtual such as Node._ready: those
|
|
45
|
+
# are the names a script most often overrides and the engine calls by name.
|
|
46
|
+
func _declared_in_chain(base: String, name: String) -> String:
|
|
47
|
+
var current: String = base
|
|
48
|
+
while not current.is_empty() and ClassDB.class_exists(current):
|
|
49
|
+
if (
|
|
50
|
+
_named(ClassDB.class_get_method_list(current, true), name)
|
|
51
|
+
or ClassDB.class_has_enum(current, name, true)
|
|
52
|
+
or _named(ClassDB.class_get_property_list(current, true), name)
|
|
53
|
+
or _named(ClassDB.class_get_signal_list(current, true), name)
|
|
54
|
+
or ClassDB.class_get_integer_constant_list(current, true).has(name)
|
|
55
|
+
):
|
|
56
|
+
return current
|
|
57
|
+
current = str(ClassDB.get_parent_class(current))
|
|
58
|
+
return ""
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
static func _named(entries: Array[Dictionary], name: String) -> bool:
|
|
62
|
+
for entry: Dictionary in entries:
|
|
63
|
+
if str(entry.get("name", "")) == name:
|
|
64
|
+
return true
|
|
65
|
+
return false
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Whether each script compiles in a fresh engine, which reads the class cache as it starts and so
|
|
69
|
+
# resolves every class the cache lists. The engine's reasons go to stderr and come back with the
|
|
70
|
+
# answer.
|
|
71
|
+
func check_scripts(params: Dictionary) -> Dictionary:
|
|
72
|
+
var paths: Array = params.get("paths", [])
|
|
73
|
+
var failed: Array[String] = []
|
|
74
|
+
for value: Variant in paths:
|
|
75
|
+
var path: String = str(value)
|
|
76
|
+
var script: Script = ResourceLoader.load(path, "Script", ResourceLoader.CACHE_MODE_IGNORE)
|
|
77
|
+
if not GdscriptAuthoring._parses(script):
|
|
78
|
+
_log.error("Does not compile: " + path)
|
|
79
|
+
failed.append(path)
|
|
80
|
+
return {"checked": paths.size(), "failed": failed}
|