clean_architecture_linter 1.0.10
clean_architecture_linter: ^1.0.10 copied to clipboard
A comprehensive custom lint package that automatically enforces Clean Architecture principles in Flutter projects with Riverpod state management.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.0.10 - 2025-12-10 #
β¨ Added #
- allowed_instance_variables_rule - Extended infrastructure SDK type support
- Google Mobile Ads SDK:
BannerAd,InterstitialAd,RewardedAd,NativeAd,AppOpenAd,AdWidget - In-App Purchase SDK:
InAppPurchase,ProductDetails,PurchaseDetails Subscriptiontype (StreamSubscription, etc.)- These SDK types require mutable state for lifecycle management
- Google Mobile Ads SDK:
π¨ Improved #
- Correction messages - Made all rule correction messages more concise for better VS Code PROBLEMS panel display
- Removed verbose examples from correction messages
- Focused on brief, actionable fix instructions
- Affected rules:
failure_naming_convention,model_naming_convention,exception_message_localization,presentation_no_data_exceptions,presentation_use_async_value,riverpod_provider_naming,riverpod_ref_usage,widget_no_usecase_call,widget_ref_read_then_when
1.0.9 - 2025-11-12 #
β¨ Added (1 new rule) #
- allowed_instance_variables_rule - Enforce stateless architecture in UseCase, Repository, and DataSource classes
- UseCase: Only
final/constRepository and Service dependencies allowed - Repository: Only
final/constDataSource and infrastructure dependencies (primitives, Stream, HTTP, Firebase, Database) allowed - DataSource: Only
final/constprimitives and infrastructure dependencies allowed - Mock/Fake classes can have mutable state for testing purposes
- Prevents hidden state bugs and enables testability
- Comprehensive validation with clear error messages
- Total rules: 34 (was 33)
- Cross-layer rules: 3 (was 2)
- UseCase: Only
π§ Fixed #
-
Domain Layer dart:io Support - Fixed false positive for
dart:ioimports in domain layerdomain_purity_rule: Now allowsdart:ioimports for type references (File, Directory) in domain layer method signatures- Actual I/O operations should still be implemented in data layer
- Addresses legitimate use cases where domain repositories need File type parameters
-
Database Library Support - Added proper exceptions for database libraries (ObjectBox, Realm, Isar, Drift)
layer_dependency_rule: Data layer can now importpackage:objectbox/,package:realm/,package:isar/,package:drift/datasource_abstraction_rule:- Private methods/getters (starting with
_) are now skipped from validation - Database entity types (Box<*Entity>, *ObjectBoxEntity, *RealmEntity, etc.) are allowed in return types
- Private methods/getters (starting with
model_structure_rule: Models with database annotations (@Entity, @RealmModel, @collection, etc.) are exempt from @freezed requirement- These libraries require mutable classes with their own code generation, incompatible with Freezed
π Documentation #
-
CLAUDE.md
- Added "Instance Variables & Stateless Architecture" section with comprehensive examples
- Added "Domain Layer with dart:io Types" example showing allowed usage of File type in repository signatures
- Updated Layer Dependencies section to clarify dart:io is allowed for type references
- Documented allowed infrastructure types for each layer
- Explained Mock/Fake exception for testing
- Added "Database Library Exceptions" section with comprehensive examples
- Explained why database Models don't use @freezed (mutability requirement)
- Listed all allowed database imports and annotations
-
README.md
- Updated rule count from 33 to 34
- Added allowed_instance_variables_rule to Core Clean Architecture Principles section
- Added ObjectBox example in "Good Examples" section
- Documented database library exceptions with clear note
-
README_KO.md
- Updated rule count from 29 to 34
- Synchronized with English README structure
π¨ Improved #
- exception_naming_convention_rule - More concise error messages for better VS Code PROBLEMS panel display
1.0.8 - 2025-10-30 #
π§ Changed #
- Minimum Dart SDK updated to 3.7.0
- Updated from ^3.6.0 to ^3.7.0 for better compatibility
- Downgraded lints from ^6.0.0 to ^5.1.1 for Dart 3.7.0 compatibility
- All existing features and tests remain compatible
- No breaking changes to API or functionality
1.0.6 - 2025-10-28 #
π§ Fixed #
- Fixed package dependencies structure
- Moved
analyzer,custom_lint_builder, andpathback todependencies - These packages are used in
lib/code and must be runtime dependencies custom_lint,lints, andtestremain indev_dependencies- Note: End users still add this package to
dev_dependenciesin their projects
- Moved
π¦ Dependencies #
- Runtime dependencies (used in lib/):
analyzer,custom_lint_builder,path - Dev dependencies (development only):
custom_lint,lints,test
1.0.5 - 2025-10-28 #
π§ Changed #
- Upgraded custom_lint_builder from
0.7.6to0.8.0- Ensures compatibility with riverpod_generator 3.0.0
- Upgraded custom_lint dev dependency to
0.8.0 - All 527 tests pass successfully
- No breaking API changes required
- Maintains backward compatibility
π¦ Dependencies #
custom_lint_builder: ^0.7.6 β ^0.8.0custom_lint: ^0.7.6 β ^0.8.0 (dev dependency)
1.0.4 - 2025-10-22 #
β¨ Added (2 new rules) #
-
widget_no_usecase_call rule - Enforce proper Riverpod architecture: Widget β Provider β UseCase
- Prevents widgets from directly importing or calling UseCases
- Enforces proper separation: Widgets should only interact with Providers
- Detects UseCase imports in widget/page files
- Detects direct UseCase provider calls via
ref.read()orref.watch() - Provides comprehensive correction messages with proper Riverpod patterns
- Severity: WARNING
-
widget_ref_read_then_when rule - Prevent anti-pattern of using
.when()afterref.read()- Detects
ref.read()followed by.when()in the same function - Enforces proper patterns:
ref.watch()+.when()for UI,ref.listen()for side effects - Prevents misuse of AsyncValue state management
- Explains why this pattern is incorrect (state is already settled after operation)
- Provides three correct alternatives based on use case
- Severity: WARNING
- Detects
π Changed #
-
presentation_no_throw rule - Enhanced detection capabilities
- Now checks
/providers/directory in addition to/states/and/state/ - Improved State/Notifier class detection with three methods:
- Detects
@riverpodannotation (Riverpod Generator pattern) - Detects
extends AsyncNotifier/Notifier/StateNotifier/ChangeNotifier - Detects generated classes with
_$prefix
- Detects
- More robust validation of Riverpod-based state management classes
- Better coverage of modern Riverpod code generation patterns
- Now checks
-
Total rules: 31 (was 29 in v1.0.3)
- Added: 2 new presentation layer rules
- Modified: 1 rule (presentation_no_throw)
π Documentation #
- Enhanced CLAUDE.md with comprehensive Riverpod state management patterns
- Added 3-tier provider architecture documentation
- Documented Entity Providers (AsyncNotifier), UI State Providers (Notifier), and Computed Logic Providers
- Added detailed examples of AsyncValue.when() pattern usage
- Included common violations and their solutions
- Comprehensive Widget usage examples with proper error handling
π Statistics #
- Files changed: 5 files
- 2 new rule implementations
- 1 rule enhancement
- 1 test file
- 1 main registration file
- Lines added: ~600+ lines
- widget_no_usecase_call_rule.dart: 265 lines
- widget_ref_read_then_when_rule.dart: 301 lines
- Enhanced presentation_no_throw_rule.dart
- Test coverage: Comprehensive unit tests for widget_no_usecase_call rule
1.0.3 - 2025-10-17 #
β¨ Added (3 new rules) #
-
model_entity_direct_access rule - Enforce
.toEntity()method usage instead of direct.entityproperty access in Data layer- Prevents direct
.entityaccess in Repository and DataSource implementations - Allows direct access inside extension methods (where conversion logic is implemented)
- Allows direct access in test files
- Provides clear architectural boundaries for Model β Entity conversion
- Prevents direct
-
model_naming_convention rule - Enforce naming conventions for Models in Data layer
- Models must end with
Modelsuffix - Validates proper naming in
data/models/directories - Helps maintain consistent codebase structure
- Models must end with
-
presentation_no_throw rule - Enforce no exception throwing in Presentation layer
- Presentation layer should use AsyncValue for error handling
- No direct exception throws in widgets, states, or notifiers
- Aligns with Riverpod best practices
π Changed #
-
model_conversion_methods rule - Updated to align with Dart/Freezed best practices
- Now only requires
toEntity()method in extensions (mandatory) fromEntity()implementation is optional and should use factory constructors in the Model class- Removed extension static method pattern (not idiomatic in Dart)
- Updated error messages to guide users toward factory constructor pattern
- Now only requires
-
Total rules: 29 (was 26 in v1.0.2)
- Added: 3 new rules
- Modified: 1 rule (model_conversion_methods)
π Bug Fixes #
- Fixed
exception_naming_conventionrule to skipcore/directory (framework-level exceptions) - Fixed
failure_naming_conventionrule to skipcore/directory - Fixed data file detection to correctly exclude
domain/repositories/from data layer - Fixed
model_conversion_methodsrule incorrectly requiring extension static methods - Improved error severity levels across multiple rules
π Documentation #
- Updated CLAUDE.md with comprehensive
.entityaccess control guidelines - Updated Data Layer rules README with all 3 new rules documentation
- Enhanced Model conversion pattern examples with factory constructor approach
- Added 48 new lines of documentation in CLAUDE.md
- Added 55 new lines in Data Layer README
- Updated README.md with accurate rule count
π Statistics #
- Files changed: 23 files
- Lines added: ~1,237 lines
- New test coverage: 398+ lines of new tests for new rules
- Documentation improvements: 100+ lines across multiple files
1.0.2 - 2025-10-09 #
ποΈ Removed #
- entity_business_logic rule - Removed overly strict rule requiring all entities to have business logic methods
- Not all entities need business logic (e.g., events, DTOs, value objects)
- Users reported this as too restrictive for practical use cases
- Total rules: 27 β 26
π Documentation #
- Fixed incomplete code snippet in README.md examples section
- Synchronized README_KO.md structure with README.md (removed inconsistent sections)
- Updated rule count from 27 to 26 in both English and Korean READMEs
1.0.1 - 2025-10-09 #
π Documentation #
- Updated README.md with accurate rule count (27 rules instead of 16+)
- Updated README_KO.md with accurate rule count and simplified structure
- Simplified configuration section, removed non-existent Core/Strict modes
- Reorganized rules documentation with clear categorization
- Removed unnecessary documentation files (VALIDATION_REPORT.md, ERROR_HANDLING_RULES_TODO.md)
π§ CI/CD #
- Improved publish workflow to use official OIDC-based authentication
- Added quality checks (tests, analyzer, format) before publishing
- Aligned publish workflow with CI workflow for consistency
1.0.0 - 2025-10-09 #
π Initial Release #
A comprehensive custom lint package that automatically enforces Clean Architecture principles in Flutter/Dart projects.
β¨ Added #
New Utility Infrastructure
- CleanArchitectureUtils - Centralized utility class for common Clean Architecture validations
- File path detection (isDomainFile, isDataFile, isPresentationFile)
- Component detection (isUseCaseFile, isDataSourceFile, isRepositoryFile)
- Class name validation (isUseCaseClass, isDataSourceClass, isRepositoryClass)
- Type checking (isVoidType, isResultType)
- Exception pattern recognition (isDataException, isDomainException)
- AST utilities (findParentClass, isPrivateMethod, isRethrow)
- Feature extraction (extractFeatureName)
New Mixin System
- ExceptionValidationMixin - Exception naming and validation logic
- ReturnTypeValidationMixin - Return type validation for methods
- RepositoryRuleVisitor - Repository-specific validation
π Changed #
Code Organization
- 170 lines removed (13.6% code reduction) through deduplication
- Consolidated 13 rules to use shared mixins and utilities
- Improved consistency across all validation logic
- Enhanced test coverage with 76 comprehensive tests
Refactored All 24 Rules
All lint rules were refactored to leverage the new utility and mixin infrastructure:
Cross-Layer Rules (4)
- LayerDependencyRule
- CircularDependencyRule
- BoundaryCrossingRule
- TestCoverageRule
Domain Layer Rules (4)
- DomainPurityRule
- DependencyInversionRule
- RepositoryInterfaceRule
- UseCaseNoResultReturnRule
- UseCaseMustConvertFailureRule
- ExceptionNamingConventionRule
- ExceptionMessageLocalizationRule
Data Layer Rules (7)
- ModelStructureRule
- DataSourceAbstractionRule
- DataSourceNoResultReturnRule
- RepositoryMustReturnResultRule
- RepositoryNoThrowRule
- DataSourceExceptionTypesRule
- FailureNamingConventionRule
Presentation Layer Rules (6)
- NoPresentationModelsRule
- ExtensionLocationRule
- FreezedUsageRule
- RiverpodGeneratorRule
- PresentationNoDataExceptionsRule
- PresentationUseAsyncValueRule
π Improved #
Documentation
- Added comprehensive ARCHITECTURE.md with system overview
- Created CONTRIBUTING.md with development guidelines
- Added RULE_DEVELOPMENT_GUIDE.md for contributors
- Enhanced inline documentation across all files
Testing
- 76 comprehensive tests covering all utilities and mixins
- 100% coverage of utility methods
- Extensive mixin behavior validation
Code Quality
- Eliminated 170 lines of duplicate code
- Consistent validation patterns across all rules
- Improved error messages with better context
- Enhanced maintainability through shared components
π§ Technical Details #
Dependencies
- Dart SDK: ^3.6.0
- analyzer: ^7.6.0
- custom_lint_builder: ^0.7.6
- path: ^1.9.1