gdharness 1.3.42 → 1.3.44

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.
Files changed (106) hide show
  1. package/build/cli.js +383 -243
  2. package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
  3. package/build/godot/addons/gdharness_editor/animation_reads.gd +55 -33
  4. package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
  5. package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +83 -42
  7. package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
  8. package/build/godot/addons/gdharness_editor/headless_check.gd +68 -44
  9. package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
  10. package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
  11. package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
  12. package/build/godot/addons/gdharness_editor/reading.gd +51 -17
  13. package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/scene_file.gd +127 -80
  15. package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
  16. package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
  17. package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
  18. package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
  19. package/build/godot/addons/gdharness_editor/tools/animation_states.gd +37 -27
  20. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +79 -49
  21. package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
  22. package/build/godot/addons/gdharness_editor/tools/class_tools.gd +65 -42
  23. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
  24. package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
  25. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
  26. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
  27. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +166 -107
  28. package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
  29. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +68 -41
  30. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
  31. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
  32. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +12 -5
  33. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +113 -67
  34. package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
  35. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
  36. package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
  37. package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
  38. package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
  39. package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
  40. package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
  41. package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
  42. package/build/godot/addons/gdharness_runtime/reading.gd +51 -17
  43. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
  44. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +149 -147
  45. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
  46. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
  47. package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
  48. package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
  49. package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
  50. package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
  51. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
  52. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +34 -17
  53. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
  54. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
  55. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
  56. package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
  57. package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
  58. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
  59. package/build/godot/addons/gdharness_runtime/runtime_touch.gd +15 -15
  60. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
  61. package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
  62. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
  63. package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
  64. package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
  65. package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
  66. package/build/godot/addons/gdharness_tests/bench.gd +4 -5
  67. package/build/godot/addons/gdharness_tests/event.gd +10 -5
  68. package/build/godot/addons/gdharness_tests/share.gd +38 -18
  69. package/build/godot/addons/gdharness_tests/suites.gd +3 -3
  70. package/build/godot/addons/gdharness_tests/wait.gd +3 -2
  71. package/build/godot/loader/loader.gd +9 -9
  72. package/build/godot/operations/animation_reads.gd +55 -33
  73. package/build/godot/operations/audio_buses.gd +48 -19
  74. package/build/godot/operations/class_cache.gd +16 -11
  75. package/build/godot/operations/classdb_queries.gd +89 -44
  76. package/build/godot/operations/declared_values.gd +68 -32
  77. package/build/godot/operations/dependencies.gd +190 -109
  78. package/build/godot/operations/editor_tools.gd +10 -10
  79. package/build/godot/operations/export_presets.gd +100 -54
  80. package/build/godot/operations/file_reads.gd +83 -42
  81. package/build/godot/operations/file_walk.gd +12 -5
  82. package/build/godot/operations/gdscript_analysis.gd +86 -65
  83. package/build/godot/operations/gdscript_authoring.gd +83 -36
  84. package/build/godot/operations/godot_operations.gd +17 -11
  85. package/build/godot/operations/import_pipeline.gd +110 -59
  86. package/build/godot/operations/input_actions.gd +62 -39
  87. package/build/godot/operations/patterns.gd +3 -1
  88. package/build/godot/operations/plugins.gd +36 -16
  89. package/build/godot/operations/project_config.gd +61 -32
  90. package/build/godot/operations/project_diagnostics.gd +24 -11
  91. package/build/godot/operations/project_file.gd +16 -16
  92. package/build/godot/operations/project_validation.gd +71 -44
  93. package/build/godot/operations/property_paths.gd +22 -12
  94. package/build/godot/operations/property_values.gd +143 -78
  95. package/build/godot/operations/reading.gd +51 -17
  96. package/build/godot/operations/rename_checks.gd +2 -2
  97. package/build/godot/operations/resource_files.gd +11 -9
  98. package/build/godot/operations/same_values.gd +4 -4
  99. package/build/godot/operations/scene_connections.gd +27 -13
  100. package/build/godot/operations/script_check.gd +52 -49
  101. package/build/godot/operations/serialisation.gd +75 -51
  102. package/build/godot/operations/setting_reads.gd +7 -6
  103. package/build/godot/operations/value_shapes.gd +5 -6
  104. package/build/godot/tests/listed.gd +321 -268
  105. package/build/keeper.js +43 -43
  106. package/package.json +1 -1
@@ -5,13 +5,14 @@ const GdhRead = preload("reading.gd")
5
5
  const GdhLog = preload("logger.gd")
6
6
  const GdhPatterns = preload("patterns.gd")
7
7
  const GdhScriptCheck = preload("script_check.gd")
8
-
9
- const MODIFICATION_TYPES: Array[String] = ["add_constant", "add_variable", "add_signal", "add_function"]
8
+ const MODIFICATION_TYPES: Array[String] = [
9
+ "add_constant", "add_variable", "add_signal", "add_function",
10
+ ]
10
11
  ## The class each template's code is written for, and the base a script made from it extends
11
12
  ## when given none: the resource template's code is a Resource's, and on the default of Node it
12
13
  ## does not parse.
13
14
  const TEMPLATE_BASES: Dictionary = {
14
- "singleton": "Node", "state_machine": "Node", "component": "Node", "resource": "Resource"
15
+ "singleton": "Node", "state_machine": "Node", "component": "Node", "resource": "Resource",
15
16
  }
16
17
  const BLANKS_AROUND_FUNCTIONS: int = 2
17
18
 
@@ -35,7 +36,8 @@ func create_gdscript(params: Dictionary) -> Dictionary:
35
36
  _log.info("Creating GDScript: " + script_path)
36
37
 
37
38
  # Content is the whole file, so a header written above it would be a second one: a content that
38
- # starts with its own `extends` did not parse, and one without it was not the file that was sent.
39
+ # starts with its own `extends` did not parse, and one without it was not the file that was
40
+ # sent.
39
41
  if not content.is_empty():
40
42
  var alongside: Array[String] = []
41
43
  for name: String in ["class_name", "extends", "template"]:
@@ -64,8 +66,8 @@ func create_gdscript(params: Dictionary) -> Dictionary:
64
66
  "Script file already exists: " + full_script_path + ". script_edit modify adds to it."
65
67
  )
66
68
 
67
- # Content is left to the parse below: two scripts that name each other are written one at a time,
68
- # and the first does not compile until the second exists.
69
+ # Content is left to the parse below: two scripts that name each other are written one at a
70
+ # time, and the first does not compile until the second exists.
69
71
  if content.is_empty():
70
72
  var header: String = _header_refusal(cls_name_param, extends_class)
71
73
  if header.is_empty() and not template.is_empty():
@@ -79,7 +81,9 @@ func create_gdscript(params: Dictionary) -> Dictionary:
79
81
  _log.debug("Creating directory: " + script_dir)
80
82
  var error: Error = dir.make_dir_recursive(script_dir.substr(6))
81
83
  if error != OK:
82
- return _log.failure("Failed to create directory: " + script_dir + ", error: " + str(error))
84
+ return _log.failure(
85
+ "Failed to create directory: " + script_dir + ", error: " + str(error)
86
+ )
83
87
 
84
88
  var script_content: String = content
85
89
  if content.is_empty():
@@ -104,7 +108,9 @@ func create_gdscript(params: Dictionary) -> Dictionary:
104
108
  # project is imported, so a script made here was missing from every check tracking the sidecars.
105
109
  var uid: String = _uid_beside(full_script_path)
106
110
 
107
- var written: Script = ResourceLoader.load(full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE)
111
+ var written: Script = ResourceLoader.load(
112
+ full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE
113
+ )
108
114
  var parses: bool = _parses(written)
109
115
  var answer: Dictionary = {
110
116
  "success": true,
@@ -162,7 +168,7 @@ static func _not_gdscript(path: String, doing: String) -> String:
162
168
  ## extends extends RefCounted, and one with no class_name answers null for it, as an absent name
163
169
  ## does everywhere else rather than as a name that is empty.
164
170
  static func _header_written(text: String) -> Dictionary:
165
- var header: Dictionary = {"extends": "RefCounted", "class_name": null}
171
+ var header: Dictionary = { "extends": "RefCounted", "class_name": null }
166
172
  for line: String in text.split("\n"):
167
173
  # An inner class's extends is indented, and is not the script's.
168
174
  if line.begins_with(" ") or line.begins_with("\t"):
@@ -208,15 +214,18 @@ func modify_gdscript(params: Dictionary) -> Dictionary:
208
214
 
209
215
  var lines: Array[String] = []
210
216
  lines.assign(original_content.split("\n"))
211
- # Loaded only to learn whether it parsed as it was. What the engine says of that file carries its
212
- # old line numbers, and beside the errors of the file written it named lines that had moved.
217
+ # Loaded only to learn whether it parsed as it was. What the engine says of that file carries
218
+ # its old line numbers, and beside the errors of the file written it named lines that had moved.
213
219
  printerr(GdhLog.ASIDE)
214
- var before: Script = ResourceLoader.load(full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE)
220
+ var before: Script = ResourceLoader.load(
221
+ full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE
222
+ )
215
223
  printerr(GdhLog.RESUMED)
216
224
  var parsed_before: bool = _parses(before)
217
225
 
218
- # All of them checked before any is made, so a call is made whole or not at all: one skipped for a
219
- # missing name used to leave the rest written and the answer saying success over an empty list.
226
+ # All of them checked before any is made, so a call is made whole or not at all: one skipped for
227
+ # a missing name used to leave the rest written and the answer saying success over an empty
228
+ # list.
220
229
  var declared: Dictionary = _declared(lines)
221
230
  var problems: Array[String] = _modification_problems(modifications, declared)
222
231
  if not problems.is_empty():
@@ -247,14 +256,22 @@ func modify_gdscript(params: Dictionary) -> Dictionary:
247
256
  at = _add_function(lines, fields, placed)
248
257
  if at == -1:
249
258
  return _log.failure(
250
- "Nothing was changed: " + mod_type + " " + str(fields.get("name")) + " could not be placed"
259
+ (
260
+ "Nothing was changed: "
261
+ + mod_type
262
+ + " "
263
+ + str(fields.get("name"))
264
+ + " could not be placed"
265
+ )
251
266
  )
252
- placed.append({"type": mod_type, "name": str(fields.get("name")), "index": at})
267
+ placed.append({ "type": mod_type, "name": str(fields.get("name")), "index": at })
253
268
 
254
269
  var modifications_applied: Array[Dictionary] = []
255
270
  for entry: Dictionary in placed:
256
271
  var index: int = entry["index"]
257
- modifications_applied.append({"type": entry["type"], "name": entry["name"], "line": index + 1})
272
+ modifications_applied.append(
273
+ { "type": entry["type"], "name": entry["name"], "line": index + 1 }
274
+ )
258
275
 
259
276
  file = FileAccess.open(full_script_path, FileAccess.WRITE)
260
277
  if not file:
@@ -267,7 +284,9 @@ func modify_gdscript(params: Dictionary) -> Dictionary:
267
284
 
268
285
  var caught: GdhScriptCheck.GdhCaught = GdhScriptCheck.GdhCaught.new()
269
286
  OS.add_logger(caught)
270
- var made: Script = ResourceLoader.load(full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE)
287
+ var made: Script = ResourceLoader.load(
288
+ full_script_path, "Script", ResourceLoader.CACHE_MODE_IGNORE
289
+ )
271
290
  OS.remove_logger(caught)
272
291
  var parses: bool = _parses(made)
273
292
  # The names checked above are the script's own, and a member the base class declares, or a body
@@ -281,7 +300,10 @@ func modify_gdscript(params: Dictionary) -> Dictionary:
281
300
  file.close()
282
301
  if not restored:
283
302
  return _log.failure(
284
- "%s would not parse with these additions, and could not be put back as it was" % script_path
303
+ (
304
+ "%s would not parse with these additions, and could not be put back as it was"
305
+ % script_path
306
+ )
285
307
  )
286
308
  return _log.failure(
287
309
  (
@@ -319,12 +341,15 @@ static func _header_refusal(named: String, base: String) -> String:
319
341
  var declared: Dictionary = _declared_classes()
320
342
  if not named.is_empty():
321
343
  if ClassDB.class_exists(named):
322
- return "class_name %s is the name of an engine class, which a script cannot take." % named
344
+ return (
345
+ "class_name %s is the name of an engine class, which a script cannot take." % named
346
+ )
323
347
  if declared.has(named):
324
348
  return (
325
349
  (
326
- "class_name %s is taken: %s declares it, and a second script of that name does not "
327
- + "compile. Give this one another class_name, or script_edit rename the first."
350
+ "class_name %s is taken: %s declares it, and a second script of that name does "
351
+ + "not compile. Give this one another class_name, or script_edit rename the "
352
+ + "first."
328
353
  )
329
354
  % [named, declared[named]]
330
355
  )
@@ -333,7 +358,8 @@ static func _header_refusal(named: String, base: String) -> String:
333
358
  if ClassDB.class_exists(base) or declared.has(base):
334
359
  return ""
335
360
  var said: String = (
336
- "extends names %s, which is neither an engine class nor a class_name this project declares" % base
361
+ "extends names %s, which is neither an engine class nor a class_name this project declares"
362
+ % base
337
363
  )
338
364
  var close: PackedStringArray = GdhRead.nearest(base, PackedStringArray(declared.keys()))
339
365
  if close.is_empty():
@@ -390,7 +416,9 @@ static func _declared_classes() -> Dictionary:
390
416
  declared[str(entry.get("class", ""))] = path
391
417
  for path: String in GdhFileWalk.new().find_files("res://", ".gd"):
392
418
  for line: String in FileAccess.get_file_as_string(path).split("\n"):
393
- var found: RegExMatch = GdhPatterns.declared_class(GdhPatterns.without_annotations(line))
419
+ var found: RegExMatch = GdhPatterns.declared_class(
420
+ GdhPatterns.without_annotations(line)
421
+ )
394
422
  if found != null and not declared.has(found.get_string(1)):
395
423
  declared[found.get_string(1)] = path
396
424
  return declared
@@ -425,20 +453,31 @@ static func _modification_problems(modifications: Array, declared: Dictionary) -
425
453
  )
426
454
  )
427
455
  if mod_type == "add_constant" and str(fields.get("defaultValue", "")).is_empty():
428
- problems.append(which + " is a constant with no defaultValue, and a constant needs a value")
456
+ problems.append(
457
+ which + " is a constant with no defaultValue, and a constant needs a value"
458
+ )
429
459
  if (
430
460
  not str(fields.get("exportHint", "")).is_empty()
431
461
  and fields.has("isExport")
432
462
  and not GdhRead.as_bool(fields["isExport"])
433
463
  ):
434
- problems.append(
435
- which + " has an exportHint and isExport false, and a hint is written only on an export"
464
+ (
465
+ problems
466
+ . append(
467
+ (
468
+ which
469
+ + " has an exportHint and isExport false, and a hint is written only on an "
470
+ + "export"
471
+ )
472
+ )
436
473
  )
437
474
  if mod_name.is_empty():
438
475
  problems.append(which + " has no name")
439
476
  continue
440
477
  if not mod_name.is_valid_unicode_identifier():
441
- problems.append(which + " is named '" + mod_name + "', which GDScript does not accept as a name")
478
+ problems.append(
479
+ which + " is named '" + mod_name + "', which GDScript does not accept as a name"
480
+ )
442
481
  continue
443
482
  if declared.has(mod_name):
444
483
  var existing: Dictionary = declared[mod_name]
@@ -449,7 +488,9 @@ static func _modification_problems(modifications: Array, declared: Dictionary) -
449
488
  )
450
489
  )
451
490
  elif added.has(mod_name):
452
- problems.append("%s adds %s, which modification %d adds too" % [which, mod_name, added[mod_name]])
491
+ problems.append(
492
+ "%s adds %s, which modification %d adds too" % [which, mod_name, added[mod_name]]
493
+ )
453
494
  else:
454
495
  added[mod_name] = index + 1
455
496
  return problems
@@ -477,11 +518,12 @@ static func _declared(lines: Array[String]) -> Dictionary:
477
518
  continue
478
519
  var matched: RegExMatch = declaration.search(GdhPatterns.without_annotations(raw))
479
520
  if matched != null and not found.has(matched.get_string(2)):
480
- found[matched.get_string(2)] = {"kind": matched.get_string(1), "line": i + 1}
521
+ found[matched.get_string(2)] = { "kind": matched.get_string(1), "line": i + 1 }
481
522
  return found
482
523
 
483
524
 
484
- # Inserts [param new_lines] at [param at] and moves every placed line at or below it down by as many.
525
+ # Inserts [param new_lines] at [param at] and moves every placed line at or below it down by as
526
+ # many.
485
527
  static func _insert(
486
528
  lines: Array[String], at: int, new_lines: Array[String], placed: Array[Dictionary]
487
529
  ) -> bool:
@@ -552,7 +594,8 @@ func _add_constant(lines: Array[String], mod: Dictionary, placed: Array[Dictiona
552
594
  return after + block.find(const_line) if _insert(lines, after, block, placed) else -1
553
595
 
554
596
 
555
- # Inserts the declaration and answers with its zero-based index, or -1 for one that could not be placed.
597
+ # Inserts the declaration and answers with its zero-based index, or -1 for one that could not be
598
+ # placed.
556
599
  func _add_variable(lines: Array[String], mod: Dictionary, placed: Array[Dictionary]) -> int:
557
600
  var var_name: String = str(mod.get("name", ""))
558
601
  var var_type: String = str(mod.get("varType", ""))
@@ -639,7 +682,7 @@ func _add_signal(lines: Array[String], mod: Dictionary, placed: Array[Dictionary
639
682
  # Answers with the zero-based index of the `func` line, below the blank lines that separate it.
640
683
  #
641
684
  # Two blank lines on each side, counting those already there, because that is the spacing GDScript's
642
- # style guide gives functions and the one gdformat writes and gdlint checks: one blank line passed
685
+ # style guide gives functions and the one gdstyle and gdformat write: one blank line passed
643
686
  # the engine and failed every project gating on either. A function last in the file ends it with a
644
687
  # newline, which the file is written with only when its last line is empty.
645
688
  func _add_function(lines: Array[String], mod: Dictionary, placed: Array[Dictionary]) -> int:
@@ -803,9 +846,9 @@ func _line_after_function(lines: Array[String], prefix: String) -> int:
803
846
 
804
847
 
805
848
  # The first line belonging to the declaration on [param at]: the comments and the lines holding only
806
- # annotations directly above it, at its indentation. A function placed on [param at] itself takes the
807
- # next function's doc comment, which then documents the wrong one, and its `@rpc` line, which then
808
- # annotates it. A comment indented further is the end of the body above, and stays with it.
849
+ # annotations directly above it, at its indentation. A function placed on [param at] itself takes
850
+ # the next function's doc comment, which then documents the wrong one, and its `@rpc` line, which
851
+ # then annotates it. A comment indented further is the end of the body above, and stays with it.
809
852
  static func _start_of_declaration(lines: Array[String], at: int) -> int:
810
853
  var indent: String = _indentation(lines[at])
811
854
  var start: int = at
@@ -835,6 +878,8 @@ func _ready() -> void:
835
878
  \tpass
836
879
  """
837
880
  "state_machine":
881
+ # The made script's first line, which is under the limit in the file it is written to.
882
+ # gdstyle:ignore=format/max-line-length
838
883
  return """## A finite state machine: one state at a time, entered and left through change_state.
839
884
 
840
885
  signal state_changed(old_state: String, new_state: String)
@@ -886,6 +931,7 @@ func _call_state(state_name: String, method: String, args: Array) -> void:
886
931
  \t\tstate.callv(method, args)
887
932
  """
888
933
  "component":
934
+ # gdstyle:ignore=format/max-line-length
889
935
  return """## A component: a child node that adds one behaviour to its parent, switched off with disable().
890
936
 
891
937
  @export var enabled: bool = true
@@ -916,6 +962,7 @@ func disable() -> void:
916
962
  \tset_physics_process(false)
917
963
  """
918
964
  "resource":
965
+ # gdstyle:ignore=format/max-line-length
919
966
  return """## Data kept in a .tres file, which resource_edit create makes and the game loads.
920
967
 
921
968
  @export var id: String = ""
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env -S godot --headless --script
2
2
  extends SceneTree
3
3
 
4
- # The command line the server runs is `godot --headless --path <project> --script <this>
5
- # <operation> @file:<params.json> <answer.json>`, and the one JSON object written to the answer
6
- # file is the answer. Everything an operation does lives in a sibling module; this file is the
7
- # command table and the wire format.
4
+ # The command line the server runs is
5
+ # `godot --headless --path <project> --script <this> <operation> @file:<params.json> <answer.json>`,
6
+ # and the one JSON object written to the answer file is the answer. Everything an operation does
7
+ # lives in a sibling module; this file is the command table and the wire format.
8
8
  #
9
9
  # A file rather than a line on stdout, because the project's autoloads run after `_init` and print
10
10
  # into the same stream: an autoload printing a dictionary in `_process` was the last JSON line out
@@ -34,17 +34,14 @@ const GdhRead = preload("reading.gd")
34
34
  const GdhRenameChecks = preload("rename_checks.gd")
35
35
  const GdhResourceFiles = preload("resource_files.gd")
36
36
  const GdhScriptCheck = preload("script_check.gd")
37
-
38
37
  ## Printed once the answer is written, after which the engine runs the project's autoloads. Kept in
39
38
  ## step with `ANSWERED` in src/headless.ts.
40
39
  const ANSWERED: String = "[gdharness] answered"
41
-
42
40
  ## Printed in `_init` by an operation that runs once the project's autoloads are in the tree, and
43
41
  ## when it begins there. Kept in step with `WAITING` and `BEGUN` in src/headless.ts, which files
44
42
  ## what the autoloads print in between as theirs rather than the operation's.
45
43
  const WAITING: String = "[gdharness] waiting for the autoloads"
46
44
  const BEGUN: String = "[gdharness] begun"
47
-
48
45
  ## The operations that compile the project's scripts. The engine knows an autoload's name only once
49
46
  ## the autoload is in the tree, which is after `_init`, so a script naming one compiled here failed
50
47
  ## with "Identifier not found" while the game and the editor ran it. A scene tool, and a read of a
@@ -116,7 +113,9 @@ func _init() -> void:
116
113
  _answer(operation, params, answer_path)
117
114
 
118
115
 
119
- func _answer_after_the_autoloads(operation: String, params: Dictionary, answer_path: String) -> void:
116
+ func _answer_after_the_autoloads(
117
+ operation: String, params: Dictionary, answer_path: String
118
+ ) -> void:
120
119
  printerr(BEGUN)
121
120
  _answer(operation, params, answer_path)
122
121
 
@@ -131,7 +130,12 @@ func _answer(operation: String, params: Dictionary, answer_path: String) -> void
131
130
  var answer: FileAccess = FileAccess.open(answer_path, FileAccess.WRITE)
132
131
  if answer == null:
133
132
  _log.error(
134
- "Could not write the answer to " + answer_path + ": " + error_string(FileAccess.get_open_error())
133
+ (
134
+ "Could not write the answer to "
135
+ + answer_path
136
+ + ": "
137
+ + error_string(FileAccess.get_open_error())
138
+ )
135
139
  )
136
140
  quit(1)
137
141
  return
@@ -168,7 +172,9 @@ func _read_params(argument: String) -> Variant:
168
172
  var json: JSON = JSON.new()
169
173
  if json.parse(params_json) != OK:
170
174
  _log.error("Failed to parse JSON parameters: " + params_json)
171
- _log.error("JSON Error: " + json.get_error_message() + " at line " + str(json.get_error_line()))
175
+ _log.error(
176
+ "JSON Error: " + json.get_error_message() + " at line " + str(json.get_error_line())
177
+ )
172
178
  return null
173
179
 
174
180
  var params: Variant = json.get_data()
@@ -338,7 +344,7 @@ func _editor_tool(params: Dictionary) -> Dictionary:
338
344
  var path: String = own.resource_path.get_base_dir().path_join("editor_tools.gd")
339
345
  var tools: Script = ResourceLoader.load(path, "Script")
340
346
  if tools == null or not tools.can_instantiate():
341
- return {"ok": false, "error": "The editor tools did not load from %s." % path}
347
+ return { "ok": false, "error": "The editor tools did not load from %s." % path }
342
348
  var answer: Dictionary = tools.call("run", params)
343
349
  return answer
344
350