diff --git a/CHANGELOG.md b/CHANGELOG.md index ec3fabed6a..b211ed56bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * chore: restrict `analyzer_plugin` version to `>=0.8.0 <0.10.0`. * feat: support extensions and static getters for check-unused-l10n. * feat: improve `prefer-correct-type-name` rule. +* feat: add `delete-files` flag to `check-unused-files` command. * build: activate check_unused_files on CI. ## 4.8.1 diff --git a/lib/src/analyzers/lint_analyzer/lint_analyzer.dart b/lib/src/analyzers/lint_analyzer/lint_analyzer.dart index 994b7cd77a..7c70318b6d 100644 --- a/lib/src/analyzers/lint_analyzer/lint_analyzer.dart +++ b/lib/src/analyzers/lint_analyzer/lint_analyzer.dart @@ -34,7 +34,7 @@ class LintAnalyzer { /// Returns a reporter for the given [name]. Use the reporter /// to convert analysis reports to console, JSON or other supported format. - Reporter? getReporter({ + Reporter? getReporter({ required String name, required IOSink output, required String reportFolder, diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporter_factory.dart b/lib/src/analyzers/lint_analyzer/reporters/reporter_factory.dart index 43ca6aa52d..6257c78445 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporter_factory.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporter_factory.dart @@ -13,8 +13,12 @@ import 'reporters_list/github/lint_github_reporter.dart'; import 'reporters_list/html/lint_html_reporter.dart'; import 'reporters_list/json/lint_json_reporter.dart'; -final _implementedReports = Function(IOSink output, String reportFolder)>{ +final _implementedReports = < + String, + Reporter Function( + IOSink output, + String reportFolder, +)>{ ConsoleReporter.id: (output, _) => LintConsoleReporter(output), ConsoleReporter.verboseId: (output, _) => LintConsoleReporter(output, reportAll: true), @@ -26,7 +30,7 @@ final _implementedReports = ? reporter({ +Reporter? reporter({ required String name, required IOSink output, required String reportFolder, diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/lint_code_climate_reporter.dart b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/lint_code_climate_reporter.dart index cc90330d0c..a5d8c9e85d 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/lint_code_climate_reporter.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/code_climate/lint_code_climate_reporter.dart @@ -19,7 +19,7 @@ import 'models/code_climate_issue_severity.dart'; /// /// Use it to create reports in Code Climate format. class LintCodeClimateReporter extends CodeClimateReporter> { + SummaryLintReportRecord, void> { LintCodeClimateReporter(IOSink output, {bool gitlabCompatible = false}) : super( output, @@ -30,6 +30,7 @@ class LintCodeClimateReporter extends CodeClimateReporter report( Iterable records, { Iterable> summary = const [], + void additionalParams, }) async { if (records.isEmpty) { return; diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/console/lint_console_reporter.dart b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/console/lint_console_reporter.dart index d9bbb26b1d..87912628e4 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/console/lint_console_reporter.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/console/lint_console_reporter.dart @@ -13,8 +13,8 @@ import 'lint_console_reporter_helper.dart'; /// Lint console reporter. /// /// Use it to create reports in console format. -class LintConsoleReporter - extends ConsoleReporter> { +class LintConsoleReporter extends ConsoleReporter, void> { /// If true will report info about all files even if they're not above warning threshold final bool reportAll; @@ -26,6 +26,7 @@ class LintConsoleReporter Future report( Iterable records, { Iterable> summary = const [], + void additionalParams, }) async { var hasReportData = false; diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/github/lint_github_reporter.dart b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/github/lint_github_reporter.dart index 89367de047..36b2e06e0b 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/github/lint_github_reporter.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/github/lint_github_reporter.dart @@ -14,14 +14,15 @@ const _deprecationMessage = /// /// **Note:** this reporter is deprecated and should not be used. /// Consider using Dart Code Metrics GitHub Action instead. -class LintGitHubReporter - extends GitHubReporter> { +class LintGitHubReporter extends GitHubReporter, void> { const LintGitHubReporter(IOSink output) : super(output); @override Future report( Iterable records, { Iterable> summary = const [], + void additionalParams, }) async { if (records.isEmpty) { return; diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/lint_html_reporter.dart b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/lint_html_reporter.dart index 8ddb36f0c5..d4a94a89f2 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/lint_html_reporter.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/html/lint_html_reporter.dart @@ -52,14 +52,15 @@ const _designIssues = 'Design issues'; /// Lint HTML reporter. /// /// Use it to create reports in HTML format. -class LintHtmlReporter - extends HtmlReporter> { +class LintHtmlReporter extends HtmlReporter, void> { LintHtmlReporter(String reportFolder) : super(reportFolder); @override Future report( Iterable records, { Iterable> summary = const [], + void additionalParams, }) async { await super.report(records); diff --git a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart index 5071ce3564..828ccb4f27 100644 --- a/lib/src/analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart +++ b/lib/src/analyzers/lint_analyzer/reporters/reporters_list/json/lint_json_reporter.dart @@ -17,14 +17,15 @@ import '../../../models/summary_lint_report_record.dart'; /// /// Use it to create reports in JSON format. @immutable -class LintJsonReporter - extends JsonReporter> { +class LintJsonReporter extends JsonReporter, void> { const LintJsonReporter(IOSink output) : super(output, 2); @override Future report( Iterable records, { Iterable> summary = const [], + void additionalParams, }) async { if (records.isEmpty) { return; diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart b/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart index 69177c1d20..39a07b3822 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_factory.dart @@ -66,7 +66,7 @@ final _implementedRules = )>{ AvoidUnnecessaryTypeCastsRule.ruleId: (config) => AvoidUnnecessaryTypeCastsRule(config), AvoidUnrelatedTypeAssertionsRule.ruleId: (config) => - AvoidUnnecessaryTypeAssertionsRule(config), + AvoidUnrelatedTypeAssertionsRule(config), AvoidUnusedParametersRule.ruleId: (config) => AvoidUnusedParametersRule(config), AvoidWrappingInPaddingRule.ruleId: (config) => diff --git a/lib/src/analyzers/unused_files_analyzer/reporters/report_params.dart b/lib/src/analyzers/unused_files_analyzer/reporters/report_params.dart new file mode 100644 index 0000000000..92b9e03a6b --- /dev/null +++ b/lib/src/analyzers/unused_files_analyzer/reporters/report_params.dart @@ -0,0 +1,6 @@ +/// Represents additional reporter params +class ReportParams { + final bool deleteUnusedFiles; + + const ReportParams({this.deleteUnusedFiles = false}); +} diff --git a/lib/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart b/lib/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart index a1b242ee7f..c85c8df321 100644 --- a/lib/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart +++ b/lib/src/analyzers/unused_files_analyzer/reporters/reporter_factory.dart @@ -4,16 +4,20 @@ import '../../../reporters/models/console_reporter.dart'; import '../../../reporters/models/json_reporter.dart'; import '../../../reporters/models/reporter.dart'; import '../models/unused_files_file_report.dart'; +import 'report_params.dart'; import 'reporters_list/console/unused_files_console_reporter.dart'; import 'reporters_list/json/unused_files_json_reporter.dart'; -final _implementedReports = - Function(IOSink output)>{ +final _implementedReports = < + String, + Reporter Function( + IOSink output, +)>{ ConsoleReporter.id: (output) => UnusedFilesConsoleReporter(output), JsonReporter.id: (output) => UnusedFilesJsonReporter(output), }; -Reporter? reporter({ +Reporter? reporter({ required String name, required IOSink output, }) { diff --git a/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart b/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart index e96b3eeac2..3742a4e43a 100644 --- a/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart +++ b/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/console/unused_files_console_reporter.dart @@ -2,18 +2,20 @@ import 'dart:io'; import '../../../../../reporters/models/console_reporter.dart'; import '../../../models/unused_files_file_report.dart'; +import '../../report_params.dart'; /// Unused files console reporter. /// /// Use it to create reports in console format. class UnusedFilesConsoleReporter - extends ConsoleReporter { + extends ConsoleReporter { UnusedFilesConsoleReporter(IOSink output) : super(output); @override Future report( Iterable records, { Iterable summary = const [], + ReportParams? additionalParams, }) async { if (records.isEmpty) { output.writeln('${okPen('✔')} no unused files found!'); @@ -26,14 +28,18 @@ class UnusedFilesConsoleReporter for (final analysisRecord in sortedRecords) { output.writeln( - '${warnigPen('⚠')} unused file: ${analysisRecord.relativePath}', + '${warningPen('⚠')} unused file: ${analysisRecord.relativePath}', ); } + final filesCount = alarmPen(sortedRecords.length); + + final outputRecord = (additionalParams?.deleteUnusedFiles ?? false) + ? '${okPen('✔')} $filesCount files were successfully deleted' + : '${alarmPen('✖')} total unused files - $filesCount'; + output ..writeln('') - ..writeln( - '${alarmPen('✖')} total unused files - ${alarmPen(sortedRecords.length)}', - ); + ..writeln(outputRecord); } } diff --git a/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart b/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart index cb0120ed6f..a501c82287 100644 --- a/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart +++ b/lib/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart @@ -5,19 +5,21 @@ import 'package:meta/meta.dart'; import '../../../../../reporters/models/json_reporter.dart'; import '../../../models/unused_files_file_report.dart'; +import '../../report_params.dart'; /// Unused files JSON reporter. /// /// Use it to create reports in JSON format. @immutable class UnusedFilesJsonReporter - extends JsonReporter { + extends JsonReporter { const UnusedFilesJsonReporter(IOSink output) : super(output, 2); @override Future report( Iterable records, { Iterable summary = const [], + ReportParams? additionalParams, }) async { if (records.isEmpty) { return; @@ -27,6 +29,7 @@ class UnusedFilesJsonReporter 'formatVersion': formatVersion, 'timestamp': getTimestamp(), 'unusedFiles': records.map(_analysisRecordToJson).toList(), + 'automaticallyDeleted': additionalParams?.deleteUnusedFiles ?? false, }); output.write(encodedReport); diff --git a/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart b/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart index 9fb0f2d5df..d41610102c 100644 --- a/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart +++ b/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart @@ -10,6 +10,7 @@ import '../../reporters/models/reporter.dart'; import '../../utils/analyzer_utils.dart'; import '../../utils/file_utils.dart'; import 'models/unused_files_file_report.dart'; +import 'reporters/report_params.dart'; import 'reporters/reporter_factory.dart'; import 'unused_files_config.dart'; import 'unused_files_visitor.dart'; @@ -20,7 +21,7 @@ class UnusedFilesAnalyzer { /// Returns a reporter for the given [name]. Use the reporter /// to convert analysis reports to console, JSON or other supported format. - Reporter? getReporter({ + Reporter? getReporter({ required String name, required IOSink output, }) => @@ -95,6 +96,12 @@ class UnusedFilesAnalyzer { }).toSet(); } + void deleteAllUnusedFiles(Iterable reports) { + for (final report in reports) { + File(report.path).deleteSync(); + } + } + Iterable _analyzeFile(String filePath, SomeResolvedUnitResult unit) { if (unit is ResolvedUnitResult) { final visitor = UnusedFilesVisitor(filePath); diff --git a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart index 946a9bf653..68b1a0efe7 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporter_factory.dart @@ -7,13 +7,13 @@ import '../models/unused_l10n_file_report.dart'; import 'reporters_list/console/unused_l10n_console_reporter.dart'; import 'reporters_list/json/unused_l10n_json_reporter.dart'; -final _implementedReports = - Function(IOSink output)>{ +final _implementedReports = Function(IOSink output)>{ ConsoleReporter.id: (output) => UnusedL10nConsoleReporter(output), JsonReporter.id: (output) => UnusedL10nJsonReporter(output), }; -Reporter? reporter({ +Reporter? reporter({ required String name, required IOSink output, }) { diff --git a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart index 012df5f43d..f5cc94ff84 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/console/unused_l10n_console_reporter.dart @@ -7,13 +7,14 @@ import '../../../models/unused_l10n_file_report.dart'; /// /// Use it to create reports in console format. class UnusedL10nConsoleReporter - extends ConsoleReporter { + extends ConsoleReporter { UnusedL10nConsoleReporter(IOSink output) : super(output); @override Future report( Iterable records, { Iterable summary = const [], + void additionalParams, }) async { if (records.isEmpty) { output.writeln('${okPen('✔')} no unused localization found!'); @@ -38,7 +39,7 @@ class UnusedL10nConsoleReporter final pathOffset = offset.padRight(5); output - ..writeln('$offset ${warnigPen('⚠')} unused ${issue.memberName}') + ..writeln('$offset ${warningPen('⚠')} unused ${issue.memberName}') ..writeln('$pathOffset at $path:$line:$column'); } diff --git a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart index df2fc3a489..9bd21df487 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/reporters/reporters_list/json/unused_l10n_json_reporter.dart @@ -11,13 +11,15 @@ import '../../../models/unused_l10n_issue.dart'; /// /// Use it to create reports in JSON format. @immutable -class UnusedL10nJsonReporter extends JsonReporter { +class UnusedL10nJsonReporter + extends JsonReporter { const UnusedL10nJsonReporter(IOSink output) : super(output, 2); @override Future report( Iterable records, { Iterable summary = const [], + void additionalParams, }) async { if (records.isEmpty) { return; diff --git a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart index d4ef5c7de6..eb64586fd7 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart @@ -25,7 +25,7 @@ class UnusedL10nAnalyzer { /// Returns a reporter for the given [name]. Use the reporter /// to convert analysis reports to console, JSON or other supported format. - Reporter? getReporter({ + Reporter? getReporter({ required String name, required IOSink output, }) => diff --git a/lib/src/cli/commands/check_unused_files_command.dart b/lib/src/cli/commands/check_unused_files_command.dart index 1168b82f4f..8475c8358d 100644 --- a/lib/src/cli/commands/check_unused_files_command.dart +++ b/lib/src/cli/commands/check_unused_files_command.dart @@ -2,6 +2,7 @@ import 'dart:io'; +import '../../analyzers/unused_files_analyzer/reporters/report_params.dart'; import '../../analyzers/unused_files_analyzer/unused_files_analyzer.dart'; import '../../config_builder/config_builder.dart'; import '../models/flag_names.dart'; @@ -30,6 +31,7 @@ class CheckUnusedFilesCommand extends BaseCommand { final folders = argResults.rest; final excludePath = argResults[FlagNames.exclude] as String; final reporterName = argResults[FlagNames.reporter] as String; + final deleteFiles = argResults[FlagNames.deleteFiles] as bool; final config = ConfigBuilder.getUnusedFilesConfigFromArgs([excludePath]); @@ -40,12 +42,19 @@ class CheckUnusedFilesCommand extends BaseCommand { sdkPath: findSdkPath(), ); + if (deleteFiles) { + _analyzer.deleteAllUnusedFiles(unusedFilesResult); + } + await _analyzer .getReporter( name: reporterName, output: stdout, ) - ?.report(unusedFilesResult); + ?.report( + unusedFilesResult, + additionalParams: ReportParams(deleteUnusedFiles: deleteFiles), + ); if (unusedFilesResult.isNotEmpty && (argResults[FlagNames.fatalOnUnused] as bool)) { @@ -57,6 +66,7 @@ class CheckUnusedFilesCommand extends BaseCommand { _usesReporterOption(); addCommonFlags(); _usesExitOption(); + _usesDeleteUnusedFiles(); } void _usesReporterOption() { @@ -85,4 +95,14 @@ class CheckUnusedFilesCommand extends BaseCommand { // defaultsTo: true, ); } + + void _usesDeleteUnusedFiles() { + argParser + ..addSeparator('') + ..addFlag( + FlagNames.deleteFiles, + abbr: 'd', + help: 'Delete all unused files.', + ); + } } diff --git a/lib/src/cli/models/flag_names.dart b/lib/src/cli/models/flag_names.dart index 5e08067108..faed213374 100644 --- a/lib/src/cli/models/flag_names.dart +++ b/lib/src/cli/models/flag_names.dart @@ -28,4 +28,5 @@ class FlagNames { static const l10nClassPattern = 'class-pattern'; static const fatalOnUnused = 'fatal-unused'; + static const deleteFiles = 'delete-files'; } diff --git a/lib/src/reporters/models/code_climate_reporter.dart b/lib/src/reporters/models/code_climate_reporter.dart index 058d104ec9..9e0aab30a1 100644 --- a/lib/src/reporters/models/code_climate_reporter.dart +++ b/lib/src/reporters/models/code_climate_reporter.dart @@ -8,8 +8,8 @@ import 'reporter.dart'; // Code Climate Engine Specification https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md /// Creates reports in Code Climate format widely understood by various CI and analysis tools -abstract class CodeClimateReporter - extends Reporter { +abstract class CodeClimateReporter + extends Reporter { static const String id = 'codeclimate'; static const String alternativeId = 'gitlab'; diff --git a/lib/src/reporters/models/console_reporter.dart b/lib/src/reporters/models/console_reporter.dart index c316a9dbab..77a4fa27af 100644 --- a/lib/src/reporters/models/console_reporter.dart +++ b/lib/src/reporters/models/console_reporter.dart @@ -7,12 +7,13 @@ import 'file_report.dart'; import 'reporter.dart'; /// Plain terminal reporter -abstract class ConsoleReporter extends Reporter { +abstract class ConsoleReporter + extends Reporter { static const String id = 'console'; static const String verboseId = 'console-verbose'; final AnsiPen alarmPen = AnsiPen()..rgb(r: 0.88, g: 0.32, b: 0.36); - final AnsiPen warnigPen = AnsiPen()..rgb(r: 0.98, g: 0.68, b: 0.4); + final AnsiPen warningPen = AnsiPen()..rgb(r: 0.98, g: 0.68, b: 0.4); final AnsiPen okPen = AnsiPen()..rgb(r: 0.08, g: 0.11, b: 0.81); @protected diff --git a/lib/src/reporters/models/github_reporter.dart b/lib/src/reporters/models/github_reporter.dart index 7e38392fc8..b957c7db93 100644 --- a/lib/src/reporters/models/github_reporter.dart +++ b/lib/src/reporters/models/github_reporter.dart @@ -7,7 +7,8 @@ import 'file_report.dart'; import 'reporter.dart'; /// Creates report about issues in pull request based on GitHub Actions Workflow commands. -abstract class GitHubReporter extends Reporter { +abstract class GitHubReporter + extends Reporter { static const String id = 'github'; static final commands = GitHubWorkflowCommands(); diff --git a/lib/src/reporters/models/html_reporter.dart b/lib/src/reporters/models/html_reporter.dart index 327614e920..d063e68566 100644 --- a/lib/src/reporters/models/html_reporter.dart +++ b/lib/src/reporters/models/html_reporter.dart @@ -8,7 +8,8 @@ import 'file_report.dart'; import 'reporter.dart'; /// HTML-doc reporter -abstract class HtmlReporter extends Reporter { +abstract class HtmlReporter + extends Reporter { static const String id = 'html'; @protected @@ -21,6 +22,7 @@ abstract class HtmlReporter extends Reporter { Future report( Iterable records, { Iterable summary = const [], + P? additionalParams, }) async { if (records.isEmpty) { return; diff --git a/lib/src/reporters/models/json_reporter.dart b/lib/src/reporters/models/json_reporter.dart index 66807cfa82..011bab76de 100644 --- a/lib/src/reporters/models/json_reporter.dart +++ b/lib/src/reporters/models/json_reporter.dart @@ -6,7 +6,8 @@ import 'file_report.dart'; import 'reporter.dart'; /// Machine-readable report in JSON format -abstract class JsonReporter extends Reporter { +abstract class JsonReporter + extends Reporter { static const String id = 'json'; @protected diff --git a/lib/src/reporters/models/reporter.dart b/lib/src/reporters/models/reporter.dart index 257d80b6a3..068e649db5 100644 --- a/lib/src/reporters/models/reporter.dart +++ b/lib/src/reporters/models/reporter.dart @@ -1,8 +1,12 @@ import 'file_report.dart'; /// Abstract reporter interface. -abstract class Reporter { - Future report(Iterable records, {Iterable summary = const []}); +abstract class Reporter { + Future report( + Iterable records, { + Iterable summary = const [], + Params? additionalParams, + }); const Reporter(); } diff --git a/test/src/analyzers/lint_analyzer/rules/rules_factory_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_factory_test.dart index e81a8f6005..49c487e820 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_factory_test.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_factory_test.dart @@ -42,6 +42,7 @@ void main() { 'avoid-missing-enum-constant-in-map': {}, 'avoid-throw-in-catch-block': {}, 'prefer-correct-type-name': {}, + 'avoid-unrelated-type-assertions': {}, }).map((rule) => rule.id), equals([ 'always-remove-listener', @@ -54,6 +55,7 @@ void main() { 'avoid-returning-widgets', 'avoid-throw-in-catch-block', 'avoid-unnecessary-setstate', + 'avoid-unrelated-type-assertions', 'avoid-unused-parameters', 'avoid-wrapping-in-padding', 'binary-expression-operand-order', diff --git a/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter_test.dart b/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter_test.dart new file mode 100644 index 0000000000..e5e1140374 --- /dev/null +++ b/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter_test.dart @@ -0,0 +1,78 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:dart_code_metrics/src/analyzers/unused_files_analyzer/models/unused_files_file_report.dart'; +import 'package:dart_code_metrics/src/analyzers/unused_files_analyzer/reporters/report_params.dart'; +import 'package:dart_code_metrics/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:test/test.dart'; + +class IOSinkMock extends Mock implements IOSink {} + +void main() { + group('UnusedFilesJsonReporter reports', () { + const fullPath = '/home/developer/work/project/example.dart'; + + // ignore: close_sinks + late IOSinkMock _output; + late UnusedFilesJsonReporter _reporter; + + setUp(() { + _output = IOSinkMock(); + + _reporter = UnusedFilesJsonReporter(_output); + }); + + test('no unused files', () async { + await _reporter.report([]); + + verifyNever(() => _output.write(captureAny())); + }); + + group('unused files', () { + const record = + UnusedFilesFileReport(path: fullPath, relativePath: 'example.dart'); + + test('', () async { + await _reporter.report([record]); + + final captured = verify( + () => _output.write(captureAny()), + ).captured.first as String; + final report = json.decode(captured) as Map; + + expect(report, contains('unusedFiles')); + expect( + report['unusedFiles'], + equals([ + {'path': 'example.dart'}, + ]), + ); + expect(report, contains('automaticallyDeleted')); + expect(report['automaticallyDeleted'], isFalse); + }); + + test('and about delete them', () async { + await _reporter.report( + [record], + additionalParams: const ReportParams(deleteUnusedFiles: true), + ); + + final captured = verify( + () => _output.write(captureAny()), + ).captured.first as String; + final report = json.decode(captured) as Map; + + expect(report, contains('unusedFiles')); + expect( + report['unusedFiles'], + equals([ + {'path': 'example.dart'}, + ]), + ); + expect(report, contains('automaticallyDeleted')); + expect(report['automaticallyDeleted'], isTrue); + }); + }); + }); +} diff --git a/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/unused_files_json_reporter_test.dart b/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/unused_files_json_reporter_test.dart deleted file mode 100644 index b15ab6a59c..0000000000 --- a/test/src/analyzers/unused_files_analyzer/reporters/reporters_list/unused_files_json_reporter_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:dart_code_metrics/src/analyzers/unused_files_analyzer/models/unused_files_file_report.dart'; -import 'package:dart_code_metrics/src/analyzers/unused_files_analyzer/reporters/reporters_list/json/unused_files_json_reporter.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:test/test.dart'; - -class IOSinkMock extends Mock implements IOSink {} - -void main() { - group('UnusedFilesJsonReporter reports', () { - const fullPath = '/home/developer/work/project/example.dart'; - - // ignore: close_sinks - late IOSinkMock _output; - late UnusedFilesJsonReporter _reporter; - - setUp(() { - _output = IOSinkMock(); - - _reporter = UnusedFilesJsonReporter(_output); - }); - - test('no unused files', () async { - await _reporter.report([]); - - verifyNever(() => _output.write(captureAny())); - }); - - test('unused files', () async { - const record = - UnusedFilesFileReport(path: fullPath, relativePath: 'example.dart'); - - await _reporter.report([record]); - - final captured = verify( - () => _output.write(captureAny()), - ).captured.first as String; - final report = json.decode(captured) as Map; - - expect(report, contains('unusedFiles')); - expect( - report['unusedFiles'], - equals([ - { - 'path': 'example.dart', - }, - ]), - ); - }); - }); -} diff --git a/test/src/cli/commands/check_unused_files_command_test.dart b/test/src/cli/commands/check_unused_files_command_test.dart index 0c7d1bfb74..84ca720777 100644 --- a/test/src/cli/commands/check_unused_files_command_test.dart +++ b/test/src/cli/commands/check_unused_files_command_test.dart @@ -22,6 +22,9 @@ const _usage = 'Check unused *.dart files.\n' '\n' ' --[no-]fatal-unused Treat find unused file as fatal.\n' '\n' + '\n' + '-d, --[no-]delete-files Delete all unused files.\n' + '\n' 'Run "metrics help" to see global options.'; void main() { diff --git a/website/docs/cli/check-unused-files.md b/website/docs/cli/check-unused-files.md index 3a5551a7aa..d6fd0ee919 100644 --- a/website/docs/cli/check-unused-files.md +++ b/website/docs/cli/check-unused-files.md @@ -30,6 +30,8 @@ Usage: metrics check-unused-files [arguments...] --[no-]fatal-unused Treat find unused file as fatal. + +-d, --[no-]delete-files Delete all unused files. ``` ## Output example {#output-example} @@ -49,6 +51,7 @@ The reporter prints a single JSON object containing meta information and the unu - `formatVersion` - an integer representing the format version (will be incremented each time the serialization format changes) - `timestamp` - a creation time of the report in YYYY-MM-DD HH:MM:SS format - `unusedFiles` - an array of [unused files](#the-unusedFiles-object-fields-are) +- `automaticallyDeleted` - an indication of unused files being automatically deleted ```JSON { @@ -64,7 +67,8 @@ The reporter prints a single JSON object containing meta information and the unu { ... } - ] + ], + "automaticallyDeleted": false } ```