Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Commit

Permalink
feat: add experimental monorepo support for check-unused-code (#659)
Browse files Browse the repository at this point in the history
* feat: add experimental monorepo support for check-unused-code

* fix: analyze all not analyzed files if in monorepo mode

* fix: fix how context folders are resolved

* chore: update changelog

* chore: fix test and update the docs

* docs: add info about limitations

* docs: add no-congratulate flag
  • Loading branch information
incendial authored Jan 31, 2022
1 parent d9f7d35 commit 8b714dc
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* fix: make `check-unused-l10n` also cover supertype member calls.
* fix: cyclomatic complexity calculation for functions with internal lambdas.
* chore: restrict `analyzer` version to `>=2.4.0 <3.3.0`.
* feat: support monorepos for `check-unused-code` command.

## 4.10.0-dev.2

Expand Down
14 changes: 9 additions & 5 deletions lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ class UnusedCodeAnalyzer {
}
}

codeUsages.exports.forEach(publicCode.remove);
if (!config.isMonorepo) {
codeUsages.exports.forEach(publicCode.remove);
}

return _getReports(codeUsages, publicCode, rootFolder);
}
Expand All @@ -115,10 +117,12 @@ class UnusedCodeAnalyzer {
String rootFolder,
Iterable<Glob> excludes,
) {
final contextFolders = folders
.where((path) => normalize(join(rootFolder, path))
.startsWith(context.contextRoot.root.path))
.toList();
final contextFolders = folders.where((path) {
final newPath = normalize(join(rootFolder, path));

return newPath == context.contextRoot.root.path ||
context.contextRoot.root.path.startsWith('$newPath/');
}).toList();

return extractDartFilesFromFolders(contextFolders, rootFolder, excludes);
}
Expand Down
10 changes: 9 additions & 1 deletion lib/src/analyzers/unused_code_analyzer/unused_code_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import '../../config_builder/models/analysis_options.dart';
class UnusedCodeConfig {
final Iterable<String> excludePatterns;
final Iterable<String> analyzerExcludePatterns;
final bool isMonorepo;

const UnusedCodeConfig({
required this.excludePatterns,
required this.analyzerExcludePatterns,
required this.isMonorepo,
});

/// Creates the config from analysis [options].
Expand All @@ -16,13 +18,18 @@ class UnusedCodeConfig {
excludePatterns: const [],
analyzerExcludePatterns:
options.readIterableOfString(['analyzer', 'exclude']),
isMonorepo: false,
);

/// Creates the config from cli args.
factory UnusedCodeConfig.fromArgs(Iterable<String> excludePatterns) =>
factory UnusedCodeConfig.fromArgs(
Iterable<String> excludePatterns, {
required bool isMonorepo,
}) =>
UnusedCodeConfig(
excludePatterns: excludePatterns,
analyzerExcludePatterns: const [],
isMonorepo: isMonorepo,
);

/// Merges two configs into a single one.
Expand All @@ -35,5 +42,6 @@ class UnusedCodeConfig {
...analyzerExcludePatterns,
...overrides.analyzerExcludePatterns,
},
isMonorepo: isMonorepo || overrides.isMonorepo,
);
}
14 changes: 7 additions & 7 deletions lib/src/cli/cli_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ class CliRunner extends CommandRunner<void> {
/// Main entry point for running a command
@override
Future<void> run(Iterable<String> args) async {
final results = parse(args);
final showVersion = results[FlagNames.version] as bool;
try {
final results = parse(args);
final showVersion = results[FlagNames.version] as bool;

if (showVersion) {
_output.writeln('Dart Code Metrics version: $packageVersion');
if (showVersion) {
_output.writeln('Dart Code Metrics version: $packageVersion');

return;
}
return;
}

try {
await super.run(_addDefaultCommand(args));
} on UsageException catch (e) {
_output
Expand Down
17 changes: 15 additions & 2 deletions lib/src/cli/commands/check_unused_code_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ class CheckUnusedCodeCommand extends BaseCommand {
final folders = argResults.rest;
final excludePath = argResults[FlagNames.exclude] as String;
final reporterName = argResults[FlagNames.reporter] as String;

final isMonorepo = argResults[FlagNames.isMonorepo] as bool;
final noCongratulate = argResults[FlagNames.noCongratulate] as bool;

final config = ConfigBuilder.getUnusedCodeConfigFromArgs([excludePath]);
final config = ConfigBuilder.getUnusedCodeConfigFromArgs(
[excludePath],
isMonorepo: isMonorepo,
);

final unusedCodeResult = await _analyzer.runCliAnalysis(
folders,
Expand Down Expand Up @@ -63,6 +66,7 @@ class CheckUnusedCodeCommand extends BaseCommand {
void _addFlags() {
_usesReporterOption();
addCommonFlags();
_usesIsMonorepoOption();
_usesExitOption();
}

Expand All @@ -82,6 +86,15 @@ class CheckUnusedCodeCommand extends BaseCommand {
);
}

void _usesIsMonorepoOption() {
argParser
..addSeparator('')
..addFlag(
FlagNames.isMonorepo,
help: 'Treats all exported code as unused by default.',
);
}

void _usesExitOption() {
argParser
..addSeparator('')
Expand Down
1 change: 1 addition & 0 deletions lib/src/cli/models/flag_names.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class FlagNames {
static const reporter = 'reporter';
static const rootFolder = 'root-folder';
static const sdkPath = 'sdk-path';
static const isMonorepo = 'monorepo';
static const version = 'version';

static const consoleReporter = ConsoleReporter.id;
Expand Down
7 changes: 4 additions & 3 deletions lib/src/config_builder/config_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ class ConfigBuilder {

/// Creates a raw unused code config from given [excludePatterns].
static UnusedCodeConfig getUnusedCodeConfigFromArgs(
Iterable<String> excludePatterns,
) =>
UnusedCodeConfig.fromArgs(excludePatterns);
Iterable<String> excludePatterns, {
required bool isMonorepo,
}) =>
UnusedCodeConfig.fromArgs(excludePatterns, isMonorepo: isMonorepo);

/// Creates a raw unused code config from given [options].
static UnusedCodeConfig getUnusedCodeConfigFromOption(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,5 @@ UnusedCodeConfig _createConfig({
UnusedCodeConfig(
excludePatterns: const [],
analyzerExcludePatterns: analyzerExcludePatterns,
isMonorepo: false,
);
3 changes: 3 additions & 0 deletions test/src/cli/commands/check_unused_code_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const _usage = 'Check unused code in *.dart files.\n'
" --no-congratulate Don't show output even when there are no issues.\n"
'\n'
'\n'
' --[no-]monorepo Treats all exported code as unused by default.\n'
'\n'
'\n'
' --[no-]fatal-unused Treat find unused file as fatal.\n'
'\n'
'Run "metrics help" to see global options.';
Expand Down
14 changes: 13 additions & 1 deletion website/docs/cli/check-unused-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Checks unused classes, functions, top level variables, extensions, enums, mixins and type aliases.

**Note:** current implementation doesn't check for particular class methods usage. Also, it treats code, that is imported with not named conditional imports as unused. This will be fixed in the future releases.

To execute the command, run

```sh
Expand Down Expand Up @@ -31,9 +33,19 @@ Usage: metrics check-unused-code [arguments] <directories>
(defaults to "{/**.g.dart,/**.template.dart}")
--[no-]fatal-unused Treat find unused l10n as fatal.
--no-congratulate Don't show output even when there are no issues.
--[no-]monorepo Treats all exported code as unused by default.
--[no-]fatal-unused Treat find unused file as fatal.
```

## Monorepo support

By default the command treats all code that exported from the package as used. To disable this behavior use `--monorepo` flag. This might be useful when all the packages in your repository only unused inside this repository and not published to pub.

## Output example {#output-example}

### Console {#console}
Expand Down

0 comments on commit 8b714dc

Please sign in to comment.