-
-
Notifications
You must be signed in to change notification settings - Fork 216
Description
Problem Description
Currently, report_exclude only supports excluding entire files or directories, which excludes ALL types of unused declarations from the results. There is no way to selectively exclude specific kinds of unused declarations (e.g., unused function, unused property) while keeping others for the same files/directories.
This limitation makes it difficult to manage analysis results in projects with mixed requirements, where certain unused types should be ignored in specific directories, while others should still be reported.
Expected Behavior
I would like to be able to specify exclusion rules based on both path patterns AND unused declaration kinds, similar to how some linters allow rule-specific exclusions.
Proposed syntax in .periphery.yml:
report_exclude:
# Exclude unused functions in SharedKit directory
- path: "**/SharedKit/**"
kinds:
- unused.function
- unused.function.parameter
# Exclude all unused declarations in GeneratedCode
- path: "**/GeneratedCode/**"
# Alternative single-line syntax
- "**/SharedKit/**:unused.function,unused.function.parameter"With this configuration:
- ✅ Unused properties in
SharedKit/would still be reported - ❌ Unused functions in
SharedKit/would be excluded from results - ❌ All unused declarations in
GeneratedCode/would be excluded
Current Behavior
Currently, the only way to exclude results from a directory consists to add granular comments periphery:ignore or:
report_exclude:
- "**/SharedKit/**"This excludes ALL types of unused declarations (functions, properties, classes, etc.) from the results, which is too aggressive when you only want to filter specific kinds.
Use Case Examples
Example 1: Shared Framework with Mixed Requirements
Consider a shared framework (SharedKit) that:
- Contains utility functions that are intentionally unused in the main app but used by other modules
- Has properties that should be validated for actual usage
Current situation:
// SharedKit/Utilities.swift
struct Utilities {
static func helperFunction() { /* unused but needed for other modules */ }
static var unusedProperty: String = "test" // Should be detected!
}With current report_exclude:
report_exclude:
- "**/SharedKit/**"Result: Both helperFunction and unusedProperty are excluded from results ❌
Desired result with granular filtering:
report_exclude:
- path: "**/SharedKit/**"
kinds:
- unused.functionResult:
helperFunctionis excluded ✅unusedPropertyis still reported as unused ✅
Example 2: Code Pending Migration to External Library
Consider a directory containing code that will be extracted into a separate library but currently lives in the main project:
// FutureLibrary/NetworkingUtils.swift
// This will become a standalone library soon
struct NetworkingUtils {
// Used by future library consumers, not by current project
static func parseHeaders(_ headers: [String: String]) -> [Header] { /* ... */ }
// Actually unused and should be cleaned up
static var deprecatedEndpoint: String = "https://old.api.com"
}Problem: These functions aren't used in the current project, but they will be needed once extracted into a library. However, truly unused code (like deprecatedEndpoint) should still be detected.
With current report_exclude:
report_exclude:
- "**/FutureLibrary/**"Result: Both parseHeaders and deprecatedEndpoint are excluded ❌
Desired result with granular filtering:
report_exclude:
- path: "**/FutureLibrary/**"
kinds:
- unused.function
- unused.function.parameterResult:
parseHeadersis excluded (will be used in the library) ✅deprecatedEndpointis still reported as unused (can be cleaned up now) ✅
This allows teams to:
- Keep unused functions that represent the future library's public API
- Still detect and clean up unused properties, types, and other declarations before migration
- Maintain code quality during refactoring phases
Workarounds Considered
- Comment commands (
// periphery:ignore): Works but requires adding comments to every function we want to ignore, which doesn't scale well - Post-processing with
jq: Adds complexity to CI/CD pipelines index_exclude: Too aggressive, removes files entirely from analysis
None of these provide a clean, declarative configuration solution.
Additional Context
This feature would greatly improve Periphery's flexibility for projects with:
- Shared frameworks with public APIs
- Code being refactored/extracted into separate libraries
- Generated code in specific directories
- Mixed Objective-C/Swift codebases where certain patterns should be ignored
- Monorepos with different analysis requirements per module
The proposed syntax is inspired by similar features in other linters (SwiftLint, ESLint) that allow rule-specific exclusions.