Commit 52a6514
fix(workflows): reject falsy non-mapping workflow-catalogs.yml top level (#3707)
* fix(workflows): reject falsy non-mapping workflow-catalogs.yml top level
WorkflowCatalog._load_catalog_config parsed the config with
`yaml.safe_load(...) or {}`, then checked `isinstance(data, dict)`. The
`or {}` coerces a FALSY non-mapping top level (`[]`, `false`, `0`, `''`) to
`{}` *before* the guard runs, so those are silently swallowed as "empty
config" and fall back to the built-in defaults -- while a TRUTHY non-mapping
(`5`, a bare list) correctly raises. Same silent-swallow inconsistency the
bundler catalog reader fixed for its own config.
Drop the `or {}` and branch on `None` (empty document / explicit `null`)
explicitly: `None` stays a valid no-op, every non-mapping (falsy or truthy)
now raises the same actionable error. Correct configs are unaffected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(workflows): describe the catalog-config fallthrough accurately
The comment said a None return means "no project catalogs, fall back to the
built-in defaults". Both halves were imprecise: _load_catalog_config serves the
project AND user configs, and get_active_catalogs falls through env -> project
-> user -> built-in, so a None from the project layer moves on to the USER
config; the built-in defaults apply only once every layer returned None.
Reword the loader comment and the mirror test docstring. Comments only -- no
behaviour change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(workflows): close the same falsy-mask gap in 'catalogs' and StepCatalog
Self-review follow-up: the top-level fix left the identical asymmetry live five
lines below, and again in this file's twin loader.
1. WorkflowCatalog._load_catalog_config: the ``catalogs`` shape check sat behind
an emptiness check, so a FALSY non-list (``catalogs: {}``/``''``/``0``/
``false``) was silently swallowed as "no catalogs" while ``catalogs: 5``
raised. Verified before this commit: ``catalogs: {}`` -> None (no error).
Shape now checked first; absent/explicit-null and empty-list stay no-ops
(matching the bundler's reader).
2. StepCatalog._load_catalog_config -- the step-catalog twin, read the same way
-- still had ``yaml.safe_load(...) or {}``, so falsy non-mappings bypassed its
isinstance guard (``[]`` -> None while ``5`` raised). Same two guards applied,
keeping the two loaders in lockstep.
Eight new parametrized cases, all failing before this commit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test(workflows): move StepCatalog guards into TestStepCatalog and add the nested case
Address three review points:
1. The StepCatalog regression tests sat inside TestWorkflowCatalog, so a
targeted `pytest ...::TestStepCatalog` run skipped them entirely. Moved into
that class, where the duplicated twin loader belongs.
2. StepCatalog had no nested-value coverage (only top-level). Added the
parametrized falsy ``catalogs:`` case, plus the absent/null/empty no-op
cases. Verified against upstream/main's catalog.py: 8 fail there, pass here.
3. Dropped the inaccurate parity parenthetical. src/specify_cli/catalogs.py
RAISES for missing/empty ``catalogs`` and coerces a null document to {}, so
it is not the behavior this loader matches -- the comment now just states
what changed (only the misreported shapes) without claiming parity.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 3dad624 commit 52a6514
2 files changed
Lines changed: 133 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
335 | 335 | | |
336 | 336 | | |
337 | 337 | | |
338 | | - | |
| 338 | + | |
339 | 339 | | |
340 | 340 | | |
341 | 341 | | |
342 | 342 | | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
343 | 353 | | |
344 | 354 | | |
345 | 355 | | |
346 | 356 | | |
347 | 357 | | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
352 | 367 | | |
353 | 368 | | |
354 | 369 | | |
355 | 370 | | |
356 | 371 | | |
357 | 372 | | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
358 | 377 | | |
359 | 378 | | |
360 | 379 | | |
| |||
1018 | 1037 | | |
1019 | 1038 | | |
1020 | 1039 | | |
1021 | | - | |
| 1040 | + | |
1022 | 1041 | | |
1023 | 1042 | | |
1024 | 1043 | | |
1025 | 1044 | | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
1026 | 1052 | | |
1027 | 1053 | | |
1028 | 1054 | | |
1029 | 1055 | | |
1030 | 1056 | | |
1031 | | - | |
1032 | | - | |
| 1057 | + | |
| 1058 | + | |
1033 | 1059 | | |
1034 | 1060 | | |
1035 | 1061 | | |
1036 | 1062 | | |
1037 | 1063 | | |
1038 | 1064 | | |
| 1065 | + | |
| 1066 | + | |
1039 | 1067 | | |
1040 | 1068 | | |
1041 | 1069 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6422 | 6422 | | |
6423 | 6423 | | |
6424 | 6424 | | |
| 6425 | + | |
| 6426 | + | |
| 6427 | + | |
| 6428 | + | |
| 6429 | + | |
| 6430 | + | |
| 6431 | + | |
| 6432 | + | |
| 6433 | + | |
| 6434 | + | |
| 6435 | + | |
| 6436 | + | |
| 6437 | + | |
| 6438 | + | |
| 6439 | + | |
| 6440 | + | |
| 6441 | + | |
| 6442 | + | |
| 6443 | + | |
| 6444 | + | |
| 6445 | + | |
| 6446 | + | |
| 6447 | + | |
| 6448 | + | |
| 6449 | + | |
| 6450 | + | |
| 6451 | + | |
| 6452 | + | |
| 6453 | + | |
| 6454 | + | |
| 6455 | + | |
| 6456 | + | |
| 6457 | + | |
| 6458 | + | |
| 6459 | + | |
| 6460 | + | |
| 6461 | + | |
| 6462 | + | |
| 6463 | + | |
| 6464 | + | |
| 6465 | + | |
| 6466 | + | |
| 6467 | + | |
| 6468 | + | |
| 6469 | + | |
| 6470 | + | |
| 6471 | + | |
| 6472 | + | |
| 6473 | + | |
| 6474 | + | |
| 6475 | + | |
6425 | 6476 | | |
6426 | 6477 | | |
6427 | 6478 | | |
| |||
7045 | 7096 | | |
7046 | 7097 | | |
7047 | 7098 | | |
| 7099 | + | |
| 7100 | + | |
| 7101 | + | |
| 7102 | + | |
| 7103 | + | |
| 7104 | + | |
| 7105 | + | |
| 7106 | + | |
| 7107 | + | |
| 7108 | + | |
| 7109 | + | |
| 7110 | + | |
| 7111 | + | |
| 7112 | + | |
| 7113 | + | |
| 7114 | + | |
| 7115 | + | |
| 7116 | + | |
| 7117 | + | |
| 7118 | + | |
| 7119 | + | |
| 7120 | + | |
| 7121 | + | |
| 7122 | + | |
| 7123 | + | |
| 7124 | + | |
| 7125 | + | |
| 7126 | + | |
| 7127 | + | |
| 7128 | + | |
| 7129 | + | |
| 7130 | + | |
| 7131 | + | |
| 7132 | + | |
| 7133 | + | |
| 7134 | + | |
| 7135 | + | |
| 7136 | + | |
| 7137 | + | |
| 7138 | + | |
| 7139 | + | |
| 7140 | + | |
| 7141 | + | |
| 7142 | + | |
| 7143 | + | |
| 7144 | + | |
7048 | 7145 | | |
7049 | 7146 | | |
7050 | 7147 | | |
| |||
0 commit comments