Fix MissingCheckInConfig missing unused checks (#1278)#1285
Fix MissingCheckInConfig missing unused checks (#1278)#1285dl-alexandre wants to merge 3 commits into
Conversation
`Credo.Check.all_loaded_checks/0` was sourcing its result through `Credo.Code.loaded_modules_implementing/1`, which iterates `:code.all_loaded/0`. Because nothing references an unused check module, the BEAM never loads it — so it never appeared in the result, and `MissingCheckInConfig` silently failed to flag it. The bug was hidden in credo's own test suite, where every check module is loaded incidentally. Source credo's own checks from the curated `standard_checks/0` list instead. That has the side benefit of excluding helper checks like `Credo.Check.Warning.UnusedOperation` from the warning — they do nothing without explicit configuration and shouldn't be flagged as "missing from config" (per @rrrene's note on rrrene#1278). Supplement with check modules from any other loaded application (plugins, custom check libraries) by reading their module list from `:application.get_key/2`, which doesn't depend on prior code loading. Refs rrrene#1278.
|
Hi, thx for trying to solve this. But isn't this approach (going |
|
Hi René, thanks for the question. The key distinction is the source of the candidate modules, not the loading step.
For Credo's own checks we skip dynamic discovery entirely and use the static If you'd prefer to avoid any loading side-effects for plugins, we could switch that path to Does that address the concern? |
|
We can't load the chunks because we can not assume the project is compiled. Could you explain in your own words what the new test from your last commit actually tests? |
This reverts commit 036fa1c.
|
You're right, the The test I added there only proved that a compiled module listed in an I think the core fix here is still the static |
Closes #1278.
Credo.Check.all_loaded_checks/0was sourcing its result viaCredo.Code.loaded_modules_implementing/1, which iterates:code.all_loaded/0. Because nothing references an unused check module, the BEAM never loads it — so it never appeared in the result, andMissingCheckInConfigsilently failed to flag it. The bug is hidden in credo's own test suite, where every check module gets loaded incidentally; the reporter (@PragTob) diagnosed this correctly in the issue.This sources credo's own checks from the curated
standard_checks/0list instead. Two side benefits beyond fixing the original bug:UnusedOperationis no longer flagged as missing. It's not instandard_checks/0(it's a generic check that does nothing withoutmodules: [...]configuration), so it falls out naturally. That matches @rrrene's note on the issue ("I'd also probably exclude it from being warned about, as the check does nothing without configuration").Plugin checks are now discovered without depending on load order. A new private
external_check_modules/0walksApplication.loaded_applications/0and reads each app's module list from:application.get_key/2, then filters to modules implementing theCredo.Checkbehaviour. That doesn't depend on:code.all_loaded/0either, so plugin checks show up whether or not anything has referenced them yet.The only caller of
Credo.Check.all_loaded_checks/0inlib/isMissingCheckInConfig, so the contract change is well-scoped.Added a small unit test asserting that
all_loaded_checks/0returns a superset ofstandard_checks/0regardless of load order, and that the result has no duplicates. CI will verify the full matrix.