Skip to content

EasyAudit as a repo

Choose a tag to compare

@ChristopheFerreboeuf ChristopheFerreboeuf released this 14 May 06:22
· 2 commits to main since this release
e03646e

Added

  • SpecificClassInjection — statefulBuilderInjection rule: flags direct constructor injection of stateful Magento framework builders (Magento\Framework\Api\FilterBuilder, Magento\Framework\Api\Search\FilterGroupBuilder, Magento\Framework\Api\SortOrderBuilder). Recommends the matching *Factory + create() per-method pattern. SearchCriteriaBuilder is intentionally excluded as the canonical public API. Severity: note.
  • Glossary system (data/{lang}/glossary.json + src/Core/Glossary/GlossaryLoader): language-indexed concept definitions (term, Magento-contextualized shortDefinition, optional links). Ships en only — unavailable languages fall back to en (GlossaryLoader::FALLBACK_LANGUAGE); LanguageNotAvailableException is only thrown when the fallback itself is missing. The free repo emits concepts annotations on rule output but does not consume them in any reporter; sponsor reporters (MD, glossary HTML) pick them up via upstream sync.
  • Per-rule concept annotations on processors: AbstractProcessor exposes a CONCEPTS constant projected into the default getReport(). AroundPlugins, CountOnCollection, ProxyForHeavyClasses, and SpecificClassInjection are annotated. Multi-rule processors emit per-rule slugs (via RULE_CONFIGS entries or a per-ruleId map). tests/Unit/Core/Glossary/GlossaryIntegrityTest walks every processor by reflection and asserts that every referenced slug exists in data/en/glossary.json.
  • Reporter configuration (config/easyaudit.json + src/Service/Config.php): runtime registry mapping output format → reporter FQCN, plus a defaultFormat key. Config::load() validates that each FQCN implements ReporterInterface and caches the result. PHAR build now bundles the config/ directory (box.json).
  • HtmlReporter::renderLongDescription(string $escapedText, array $rule): string: no-op extension hook that sponsor's GlossaryHtmlReporter overrides to inject autolinked concept tooltips into already-escaped paragraph text. The escape-then-inject ordering is mandatory.
  • FixerInterface (src/Service/FixerInterface.php): backend abstraction for the fix pipeline. Api now implements it; FixApply depends on the interface instead of the concrete class. getRemainingCredits() may return null to signal that the active backend does not track credits — FixApply then skips credit prompts, balance display, and the post-run cost summary. Enables local/offline fixers to plug in without touching FixApply.
  • Configurable command registry and fixer in bin/easyaudit: command list and fixer FQCN are now read from Config::load() (commands and fixer keys), with the same built-in defaults as before. Sponsor overlays can register additional commands or swap the fixer backend without forking the entry point.
  • Composer-aware autoloader in bin/easyaudit: prefers vendor/autoload.php when installed as a Composer dependency (vendor/crealoz/easyaudit-cli/bin/easyaudit) or from a source checkout. Falls back to the hand-rolled PSR-4 loader for the PHAR build, where Composer's vendor/ is not bundled. Combined with the composer.json changes, this allows installing the CLI as composer require crealoz/easyaudit-cli.
  • Scanner::getMode() / Scanner::setMode(?string): scan-mode signal that commands set before calling Scanner::run(). Processors can read it to tune behavior for a specific feature (e.g. amplifying severity on checkout-critical files in a checkout-audit run). null is the default, general-purpose scan.
  • Paths::cacheDir(string $subdir = ''): XDG_CACHE_HOME-aware cache directory helper. Resolves to $XDG_CACHE_HOME/easyaudit (falling back to $HOME/.cache/easyaudit, then the system temp dir), creates the optional sub-directory on first use with mode 0700, and throws RuntimeException on failure.
  • SARIF multi-location findings: SarifReporter now splits a finding whose file field contains comma-separated path:line segments into one SARIF location per segment. The outer startLine is 0 in that case and each segment carries its own line. Used by AroundPlugins::deepPluginStack so SARIF consumers see one location per plugin di.xml declaration.
  • AbstractPreparer::getMappedRule(): reintroduced as a protected helper returning the mapped rule name for a given ruleId. Was removed in 1.2.0 as unused; now used by the fixer code path.

Changed

  • Scan command — reporter dispatch is now config-driven: the hardcoded match($format) over JsonReporter|SarifReporter|HtmlReporter is replaced by new $class() against the config/easyaudit.json map. Allowed --format values, the default format, and --help text are all derived from the loaded config. Adding a new reporter is now a one-line edit to config/easyaudit.json — no change to Scan.php or any other core file is required. This is also the extension point sponsor builds use to swap in GlossaryHtmlReporter / register MdReporter without forking Scan.php.
  • composer.json — package metadata for distribution: type changed from project to library, license changed from proprietary to MIT, and a bin entry (bin/easyaudit) was added. The CLI can now be installed as a Composer dependency and exposes the easyaudit executable via vendor/bin/easyaudit.
  • AroundPlugins::deepPluginStack — per-plugin di.xml locations with line numbers: previously the finding pointed at the first di.xml file with line: 1. It now emits the full list of di.xml declarations that participate in the stack — every <plugin> node on the target across global/frontend/adminhtml scopes — encoded as comma-separated diFile:lineNo segments. The message format also tightened from … — plugins: … to … Plugins: ….
  • PluginRegistry — DOM-based parsing: rewritten from SimpleXMLElement to DOMDocument/DOMXPath so each <plugin> entry now carries its source line (getLineNo()). The plugin entry shape gained a required line: int field. Only direct <plugin> children of each <type> are collected (xpath was already constrained, but the DOM walk makes it explicit).
  • FixApply — credit-aware UX is now optional: $creditsRemaining is nullable; when the active fixer returns null from getRemainingCredits(), credit prompts, the "Credits remaining" line, and the real-cost summary are all suppressed. checkCreditsAndConfirm() return type is now int|false|null. The totalFiles count is computed before calculateCost() so cost estimation sees the correct total.
  • HtmlReporter — line column for multi-location findings: when startLine is 0 (multi-location finding such as deepPluginStack), the Line cell now renders instead of a misleading 0. Long-description rendering also receives the rule array so the renderLongDescription extension hook has the concept slugs.
  • Api::getRemainingCredits() return type tightened: now declared ?array to match the FixerInterface contract. Docblocks on requestFilefix, getRemainingCredits, and getAllowedType were aligned with the interface's array{…} shapes.
  • docs/processors.md: rule count updated from 37 to 38; SpecificClassInjection severity row gains Note for the new builder rule.
  • psalm.xml issue handlers: UnusedClass suppression extended to src/Core/Report/ and src/Core/Glossary/ (reporter and glossary classes are resolved by FQCN strings); PossiblyUnusedMethod suppression extended to src/Core/Report/, src/Service/Config.php, and src/Service/Paths.php.

Full Changelog: v1.2.0...v1.3.0