clonescope is a Dart CLI that finds structurally duplicated Dart and Flutter code.
It parses source files with the Dart analyzer, normalizes identifiers and literals, clusters matching method and function bodies, and ranks the results so higher-risk duplicates show up first.
The current ranking model favors:
- data-layer and service-layer duplication
- async flows, error handling, and branching logic
- duplicates spread across different files or folders
It de-prioritizes:
build()-heavy UI duplication- short boilerplate methods such as
copyWith() - test files, unless explicitly included
dart pub global activate clonescopeThen run:
clonescope /path/to/flutter_or_dart_repoclonescope <path> [--min-lines N] [--min-tokens N] [--top N] [--include-tests] [--include-boilerplate] [--json]Examples:
clonescope ~/projects/orchard/realaf-app
clonescope ~/projects/orchard/realaf-app --top 50
clonescope ~/projects/orchard/realaf-app --include-tests --jsonExample output:
Found 45 duplicate groups in 703 Dart files.
[score 796] 2 occurrences, 60 lines, 330 normalized tokens
why: base=590, architecture+95, logic+111
shape: async { try { if ( id . id . id == id . id ) return null
- lib/data/leaderboard_repo.dart:202 (method getUserWeeklyRank)
- lib/data/leaderboard_repo.dart:264 (method getUserMonthlyRank)
clonescope currently:
- Walks a Dart or Flutter repository recursively.
- Ignores generated files such as
.g.dart,.freezed.dart, and build output. - Parses each Dart file with
package:analyzer. - Extracts function and method bodies.
- Normalizes identifiers, strings, and numeric literals into stable token shapes.
- Groups exact normalized matches.
- Ranks the groups using architecture-aware heuristics.
Current architecture hints include:
lib/data/lib/services/lib/usecases/lib/core/lib/navigation/lib/ui/lib/ui/widgets/lib/models/test/
This is an early version focused on exact normalized matches.
Planned improvements:
- near-clone detection with small inserted or removed statements
- richer Flutter folder-architecture heuristics
- machine-readable output for CI reporting
- analyzer plugin integration for inline diagnostics
Run locally:
dart analyze
dart test
dart run bin/clonescope.dart /path/to/repoBefore publishing to pub.dev, run:
dart pub publish --dry-runThen publish:
dart pub publish