@openmixer/plugin-qualify 0.20.0 → 0.20.3

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 (117) hide show
  1. package/bin/plugin-qualify-records-package.mjs +9 -7
  2. package/bin/plugin-qualify-sync.mjs +1 -0
  3. package/bin/plugin-qualify.mjs +34 -0
  4. package/catalogs/ca.json +8 -0
  5. package/dist/clap-loader.js +2 -1
  6. package/dist/clap-loader.js.map +1 -1
  7. package/dist/clap-qualify.d.ts +11 -0
  8. package/dist/clap-qualify.js +16 -0
  9. package/dist/clap-qualify.js.map +1 -1
  10. package/dist/distributed-records.d.ts +16 -3
  11. package/dist/distributed-records.js +38 -4
  12. package/dist/distributed-records.js.map +1 -1
  13. package/dist/host-admission.d.ts +25 -0
  14. package/dist/host-admission.js +41 -5
  15. package/dist/host-admission.js.map +1 -1
  16. package/dist/hostd-search-path.d.ts +38 -0
  17. package/dist/hostd-search-path.js +58 -0
  18. package/dist/hostd-search-path.js.map +1 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/jack-registry.js +1 -1
  23. package/dist/judged-layer.d.ts +91 -0
  24. package/dist/judged-layer.js +144 -0
  25. package/dist/judged-layer.js.map +1 -0
  26. package/dist/judgement-line.d.ts +6 -0
  27. package/dist/judgement-line.js +20 -0
  28. package/dist/judgement-line.js.map +1 -0
  29. package/dist/lv2-loader.d.ts +33 -1
  30. package/dist/lv2-loader.js +82 -19
  31. package/dist/lv2-loader.js.map +1 -1
  32. package/dist/measurement/cli.d.ts +2 -0
  33. package/dist/measurement/cli.js +25 -2
  34. package/dist/measurement/cli.js.map +1 -1
  35. package/dist/measurement/format.d.ts +2 -0
  36. package/dist/measurement/format.js +5 -0
  37. package/dist/measurement/format.js.map +1 -1
  38. package/dist/measurement/vocabulary.js +3 -3
  39. package/dist/measurement/vocabulary.js.map +1 -1
  40. package/dist/measurement-grid.d.ts +1 -1
  41. package/dist/measurement-grid.js +5 -3
  42. package/dist/measurement-grid.js.map +1 -1
  43. package/dist/pins-file.d.ts +3 -2
  44. package/dist/pins-file.js +3 -2
  45. package/dist/pins-file.js.map +1 -1
  46. package/dist/probe-judge.js +5 -0
  47. package/dist/probe-judge.js.map +1 -1
  48. package/dist/probe-output.d.ts +10 -0
  49. package/dist/probe-output.js +16 -0
  50. package/dist/probe-output.js.map +1 -1
  51. package/dist/probe-runner.js +24 -5
  52. package/dist/probe-runner.js.map +1 -1
  53. package/dist/qualification-record.d.ts +13 -0
  54. package/dist/qualification-record.js +25 -3
  55. package/dist/qualification-record.js.map +1 -1
  56. package/dist/qualify-adapter-pass.d.ts +1 -2
  57. package/dist/qualify-adapter-pass.js +6 -6
  58. package/dist/qualify-adapter-pass.js.map +1 -1
  59. package/dist/qualify-declarations.d.ts +23 -6
  60. package/dist/qualify-declarations.js +25 -6
  61. package/dist/qualify-declarations.js.map +1 -1
  62. package/dist/qualify-isolated.d.ts +14 -3
  63. package/dist/qualify-isolated.js +22 -9
  64. package/dist/qualify-isolated.js.map +1 -1
  65. package/dist/qualify-pool.js +4 -3
  66. package/dist/qualify-pool.js.map +1 -1
  67. package/dist/qualify-rejudge.js +3 -3
  68. package/dist/qualify-rejudge.js.map +1 -1
  69. package/dist/qualify-sync.d.ts +18 -6
  70. package/dist/qualify-sync.js +68 -38
  71. package/dist/qualify-sync.js.map +1 -1
  72. package/dist/records-package.d.ts +31 -4
  73. package/dist/records-package.js +149 -24
  74. package/dist/records-package.js.map +1 -1
  75. package/dist/run-home.d.ts +4 -0
  76. package/dist/run-home.js +26 -0
  77. package/dist/run-home.js.map +1 -0
  78. package/fixtures/records-rpi5-0.19.1/http___drumkv1.sourceforge.net_lv2@0.2-7d179bdcf9e5.default.probe.json +58 -0
  79. package/fixtures/records-rpi5-0.19.1/http___drumkv1.sourceforge.net_lv2@0.2-7d179bdcf9e5.default.qualification.json +305 -0
  80. package/fixtures/records-rpi5-0.19.1/http___samplv1.sourceforge.net_lv2@0.2-c9cd8fb3102f.default.probe.json +58 -0
  81. package/fixtures/records-rpi5-0.19.1/http___samplv1.sourceforge.net_lv2@0.2-c9cd8fb3102f.default.qualification.json +301 -0
  82. package/package.json +7 -5
  83. package/schema/codes.json +15 -0
  84. package/src/clap-loader.ts +2 -1
  85. package/src/clap-qualify.ts +25 -0
  86. package/src/distributed-records.ts +41 -4
  87. package/src/host-admission.ts +52 -5
  88. package/src/hostd-search-path.ts +85 -0
  89. package/src/index.ts +2 -0
  90. package/src/jack-registry.ts +1 -1
  91. package/src/judged-layer.ts +197 -0
  92. package/src/judgement-line.ts +22 -0
  93. package/src/lv2-loader.ts +89 -17
  94. package/src/measurement/cli.ts +26 -2
  95. package/src/measurement/format.ts +8 -0
  96. package/src/measurement/vocabulary.ts +3 -3
  97. package/src/measurement-grid.ts +5 -3
  98. package/src/pins-file.ts +3 -2
  99. package/src/probe-judge.ts +5 -0
  100. package/src/probe-output.ts +23 -0
  101. package/src/probe-runner.ts +25 -4
  102. package/src/qualification-record.ts +32 -3
  103. package/src/qualify-adapter-pass.ts +6 -5
  104. package/src/qualify-declarations.ts +27 -6
  105. package/src/qualify-isolated.ts +24 -9
  106. package/src/qualify-pool.ts +4 -3
  107. package/src/qualify-rejudge.ts +3 -3
  108. package/src/qualify-sync.ts +74 -41
  109. package/src/records-package.ts +156 -25
  110. package/src/run-home.ts +28 -0
  111. package/tools/_declarations.py +2 -1
  112. package/tools/descriptors.py +40 -3
  113. package/tools/gen-python-declarations.mjs +1 -0
  114. package/tools/isolated-step.mjs +24 -3
  115. package/tools/lv2-measure.mjs +21 -2
  116. package/tools/mod-host-admit.mjs +57 -1
  117. package/tools/scan.py +29 -5
package/tools/scan.py CHANGED
@@ -30,6 +30,7 @@ import json
30
30
  import os
31
31
  import subprocess
32
32
  import sys
33
+ from urllib.parse import unquote, urlparse
33
34
 
34
35
  import descriptors as desc
35
36
  from lv2_presets import read_presets
@@ -142,8 +143,9 @@ def bundle_path(plugin):
142
143
  if uri is None:
143
144
  return None
144
145
  p = str(uri)
145
- if p.startswith("file://"):
146
- p = p[len("file://"):]
146
+ if p.startswith("file:"):
147
+ # a file: URI's path is percent-decoded, as lilv and serd read it (`My%20Plugins` is `My Plugins` on the disk)
148
+ p = unquote(urlparse(p).path)
147
149
  return p.rstrip("/") or None
148
150
 
149
151
 
@@ -169,6 +171,8 @@ def owning_rpm(path, run=subprocess.run):
169
171
 
170
172
 
171
173
  class Scanner:
174
+ refusals = () # (uri, code, problem, args) of each plugin the last `descriptors` refused
175
+
172
176
  def __init__(self):
173
177
  # lilv is imported here, not at module load: the owner mapping and the pure helpers
174
178
  # (test_scan.py) run on a host without the bindings, the way benchmark.py's worker does.
@@ -338,6 +342,10 @@ class Scanner:
338
342
  # a DECLARED fact like the comment above, read off the bundle and judged against the params
339
343
  # just read. Always present on a scanned plugin — `[]` is "ships none", never "not read".
340
344
  out["presets"] = read_presets(self.w, plugin, params)
345
+ # a plugin the scan refuses to describe stays listed, with its code, args and sentence (plugin-qualify#27)
346
+ refusal = self.port_refusal(plugin)
347
+ if refusal is not None:
348
+ out["refused"] = {"code": refusal.code, "args": refusal.code_args, "text": refusal.problem}
341
349
  # Record the latency port symbol if the plugin reports one. The actual frame
342
350
  # value is filled later by the on-rig benchmark (benchmark.py); a plugin with
343
351
  # no latency port carries no `latency` key → host treats it as unknown, not 0.
@@ -418,6 +426,10 @@ class Scanner:
418
426
  if group:
419
427
  c["group"] = group
420
428
  meaning = self.designation_meaning(port)
429
+ # a toggle named bypass with no designation of its own is the plugin's bypass (EQ10Q's eq1qm..eq10qm): a
430
+ # panel leaves it to the header, which draws one bypass per panel (plugin-qualify#27)
431
+ if c["kind"] == "toggle" and sym.lower() == "bypass" and meaning in ("unknown", None):
432
+ meaning = "bypass"
421
433
  if meaning is not None:
422
434
  c["meaning"] = meaning
423
435
  if self.has(port, PP + "notOnGUI"):
@@ -427,9 +439,18 @@ class Scanner:
427
439
  c["source"] = {"from": f"{link}#{desc.link_symbol(sym)}"}
428
440
  return c
429
441
 
442
+ def port_refusal(self, plugin):
443
+ """The refusal a plugin's ports earn before any descriptor is drawn, else None: two ports with one symbol."""
444
+ dup = desc.duplicate_symbol(str(plugin.get_port_by_index(i).get_symbol()) for i in range(plugin.get_num_ports()))
445
+ return desc.refused(desc.DESCRIPTOR_CODE_DUPLICATE_SYMBOL, symbol=dup) if dup is not None else None
446
+
430
447
  def descriptor(self, plugin):
431
- """The plugin as a scanned descriptor, and the SHA-256 of its binary: `(doc, sha256)`."""
448
+ """The plugin as a scanned descriptor, and the SHA-256 of its binary: `(doc, sha256)`. A plugin whose ports
449
+ cannot be addressed raises its refusal (`port_refusal`): it is not repaired."""
432
450
  uri = str(plugin.get_uri())
451
+ refusal = self.port_refusal(plugin)
452
+ if refusal is not None:
453
+ raise refusal
433
454
  bundle = bundle_path(plugin) or ""
434
455
  lib = plugin.get_library_uri()
435
456
  lib_path = lib.get_path() if lib is not None else None
@@ -524,16 +545,19 @@ class Scanner:
524
545
  return d, sha256
525
546
 
526
547
  def descriptors(self, uris=None):
527
- """`(doc, sha256)` for every plugin `scan` would describe."""
548
+ """`(doc, sha256)` for every plugin `scan` would describe. A plugin refused here is kept in `self.refusals`,
549
+ `(uri, code, problem, args)`, and reported, never silently dropped (its catalog row says why, `describe`)."""
528
550
  plugins = self.w.get_all_plugins()
529
551
  chosen = [plugins.get_by_uri(self.w.new_uri(u)) for u in uris] if uris else list(plugins)
530
552
  out = []
553
+ self.refusals = []
531
554
  for p in chosen:
532
555
  if p is None:
533
556
  continue
534
557
  try:
535
558
  out.append(self.descriptor(p))
536
559
  except desc.DescriptorRefused as e:
560
+ self.refusals.append((str(p.get_uri()), e.code, e.problem, e.code_args))
537
561
  sys.stderr.write(f"descriptor refused: {p.get_uri()}: {e.code}: {e.problem}\n")
538
562
  except Exception as e: # noqa: BLE001 - one plugin's bad data never stops the scan
539
563
  line = e.__traceback__.tb_next.tb_lineno if e.__traceback__ and e.__traceback__.tb_next else "?"
@@ -657,7 +681,7 @@ def main():
657
681
  sys.exit(f"{e.code}: {e.problem}")
658
682
  directory = desc.descriptor_dir(args.descriptor_dir, args.system)
659
683
  written, bad = desc.write_all(directory, scanner.descriptors(args.uris or None), validator)
660
- refused = len(bad)
684
+ refused = len(bad) + len(scanner.refusals)
661
685
  sys.stderr.write(f"wrote {len(written)} descriptors -> {directory}\n")
662
686
  text = json.dumps(catalog, indent=2, ensure_ascii=False)
663
687
  if args.out: