Repository navigation
Releases: boundwize/structarmed
Release list
Released: StructArmed 0.18.1
What's Changed
- perf: Skip garbage collection during analyse() by @samsonasik in #466
- refactor: Reuse rule-returned RuleViolation in Analyser by @samsonasik in #467
- fix: Add static to closures declaring a trait or enum that reads $this on AddStaticAnonymousFunctionVisitor by @samsonasik in #469
Full Changelog: 0.18.0...0.18.1
Released: StructArmed 0.18.0
StructArmed 0.18.0 improves CI integration and expands YAGNI analysis to named functions.
This release introduces:
- GitHub Actions annotations with the new
--report=github; - path exclusions for
Architecture::layer(); - better control over the PHPUnit extension in CI;
Boundwize\StructArmed\Rule\UsedFunctionAwareRuleInterfaceand the new fixableMustBeUsedFunctionRule.
GitHub Actions Report
StructArmed can now report violations directly as GitHub Actions annotations:
vendor/bin/structarmed analyse --report=githubEach violation is emitted as a GitHub workflow error annotation, so violations appear directly on affected files and lines in pull requests.
The regular console report is appended after the annotations, so View details still opens a readable StructArmed report in the job log.
For example:
- name: Run StructArmed
run: vendor/bin/structarmed analyse --report=githubThe GitHub report intentionally exits with 0, allowing violations to be surfaced as annotations without failing the job itself.
Use the regular console or json report when violations should fail the job.
The github and json reports also disable the progress bar automatically.
Exclude Paths From Layers
Architecture::layer() now supports excluding one or more nested paths from a layer.
For example:
return Architecture::define()
->layer(
'Logger',
'src/Logger/',
excludePath: 'src/Logger/Factory/',
)
->layer('Factory', 'src/Logger/Factory/');Files under src/Logger/Factory/ now belong to Factory without also belonging to Logger.
Multiple paths can be excluded:
->layer(
'Logger',
'src/Logger/',
excludePath: [
'src/Logger/Factory/',
'src/Logger/Formatter/',
],
)The exclusion only applies to that particular layer. A file may still resolve to another matching path layer, namespace-pattern layer, or the automatically registered Source layer.
This mirrors the existing exclusion support in layerPattern() and makes nested architecture boundaries easier to express without changing the directory structure.
YAGNI For Named Functions
The YAGNI preset can now detect unused named functions.
A new rule:
MustBeUsedFunctionRulechecks whether a function is called or otherwise referenced within the scanned code.
For example:
-function legacy_helper(): string
-{
- return 'unused';
-}The rule understands usages including:
- regular function calls;
- first-class callable references;
- function-name strings such as
'App\helper'; - calls from top-level code.
A function that only recursively calls itself still counts as unused.
MustBeUsedFunctionRule supports --fix, removing the unused function automatically. It can also clean up an empty surrounding if (! function_exists(...)) guard and remove the file when only boilerplate remains.
The rule is enabled automatically by:
Preset::YAGNI()As with the other YAGNI rules, only usages inside the scanned paths are known. Functions intended as public extension points for external consumers can be excluded with skipRule() or skip paths.
UsedFunctionAwareRuleInterface
Custom function rules can opt into function-usage analysis through the new:
Boundwize\StructArmed\Rule\UsedFunctionAwareRuleInterfaceIt extends FunctionRuleInterface and makes the usage state available through:
$functionNode->isReferencedFor example:
final readonly class CustomRule implements UsedFunctionAwareRuleInterface
{
public function appliesTo(FunctionNode $functionNode): bool
{
return $functionNode->isInLayer('Source');
}
public function evaluate(FunctionNode $functionNode): ?RuleViolation
{
if ($functionNode->isReferenced) {
return null;
}
// ...
}
}Usage analysis is opt-in: StructArmed performs the additional work only when at least one active rule implements UsedFunctionAwareRuleInterface.
PHPUnit Extension Controls
The PHPUnit extension is now easier to control in CI.
Disable StructArmed For One PHPUnit Run
Set:
STRUCTARMED_DISABLED=1 vendor/bin/phpunitStructArmed remains configured in phpunit.xml, but the extension skips architecture analysis for that run.
This is useful when StructArmed already runs as a dedicated CI step.
Disable Progress Output
PHPUnit's own --no-progress now also disables the StructArmed progress bar:
vendor/bin/phpunit --no-progressTo disable only StructArmed's progress output while preserving PHPUnit's progress display:
<extensions>
<bootstrap class="Boundwize\StructArmed\PHPUnit\StructArmedExtension">
<parameter name="progress" value="false"/>
bootstrap>
extensions>Dependency Update
StructArmed now requires:
"nikic/php-parser": "^5.9"What's Changed
- feat: Add GithubReport for Github output with
--report=githubin #445 - Bump nikic/php-parser version to
^5.9in #448 - feat: Support
excludePathinArchitecture::layer()in #450 - feat: Append console report to github report output and exit 0 in #458
- feat: Add
STRUCTARMED_DISABLEDenv to disable the PHPUnit extension in #459 - feat: Allow disabling progress bar in PHPUnit extension in #460
- feat: Add
UsedFunctionAwareRuleInterfaceandMustBeUsedFunctionRulefor YAGNI preset in #462 - Handle top-level function usage in #463
Full Changelog: 0.17.12...0.18.0
What's Changed
- feat: Add GithubReport for Github output with --report=github by @samsonasik in #445
- Bump nikic/php-parser version to ^5.9 by @samsonasik in #448
- feat: Support excludePath in Architecture::layer() by @samsonasik in #450
- feat: Append console report to github report output and exit 0 by @samsonasik in #458
- feat: Add STRUCTARMED_DISABLED env to disable the PHPUnit extension by @samsonasik in #459
- feat: Allow disabling progress bar in PHPUnit extension: StructArmedExtension via progress config or PHPUnit --no-progress by @samsonasik in #460
- feat: Add UsedFunctionAwareRuleInterface and MustBeUsedFunctionRule for YAGNI preset by @samsonasik in #462
- handle top level function usage by @samsonasik in #463
- Prepare for 0.18.0 by @samsonasik in #447
Full Changelog: 0.17.12...0.18.0
Released: StructArmed 0.17.12
What's Changed
- perf: Merge same layer check into allowed layers loop by @samsonasik in #455
- doc: Clarify dependency layer resolution comments by @samsonasik in #457
Full Changelog: 0.17.11...0.17.12
Released: StructArmed 0.17.11
What's Changed
- Fix enum protected-to-private fixer producing invalid "final private" members by @samsonasik in #453
- fix: Keep newline after line comment when removing anonymous class parentheses by @samsonasik in #454
Full Changelog: 0.17.10...0.17.11
Released: StructArmed 0.17.10
What's Changed
- fix: Prefer specific layer over equally specific Source layer in NamespaceLayerResolver by @samsonasik in #449
Full Changelog: 0.17.9...0.17.10
Released: StructArmed 0.17.9
What's Changed
- refactor: Merge loadAnalysisNodesWithFileAnalysis into loadAnalysisNodes via $withFileAnalysis flag by @samsonasik in #440
- perf: iterate pending workers directly during polling by @samsonasik in #441
- perf: reuse collector's declared function names in FileAnalysisProvider by @samsonasik in #442
- fix: Handle missing files gracefully in FileHashProvider by @samsonasik in #443
Full Changelog: 0.17.8...0.17.9
Released: StructArmed 0.17.8
What's Changed
- fix: Resolve same-file function calls only against unconditionally declared functions by @samsonasik in #439
Full Changelog: 0.17.7...0.17.8
Released: StructArmed 0.17.7
What's Changed
- fix: Resolve names before PSR-1 file-state analysis, reusing the extractor's AST by @samsonasik in #438
Full Changelog: 0.17.6...0.17.7
Released: StructArmed 0.17.6
What's Changed
- perf: Optimize object-bound anonymous-function detection hot path by @samsonasik in #433
- [docs] Update documentation about usage of ExtendedClassAwareRuleInterface by @samsonasik in #435
- perf: Skip file path in analysis node cache metadata by @samsonasik in #436
- fix: Resolve same-namespace function calls case-insensitively by @samsonasik in #437
Full Changelog: 0.17.5...0.17.6
Released: StructArmed 0.17.5
What's Changed
- perf: Optimize baseline generation and filtering performance by @samsonasik in #431
- fix: Prevent static conversion of object-bound anonymous functions by @samsonasik in #432
Full Changelog: 0.17.4...0.17.5