Finding Unused Files With Dart Code Metrics
Tags: dart, flutter, codequality, linter
Published: 2021-06-12 09:11:32

In our [previous article](https://dev.to/incendial/improving-code-quality-with-dart-code-metrics-31dn), we announced [Dart Code Metrics](https://github.com/dart-code-checker/dart-code-metrics), a static code analysis tool. Initially, its task was to collect and represent code metrics, as well as provide additional rules for the analyzer with a more flexible configuration. However, we decided to push it to the next level.

In this article, we’ll go over one of the first commands, `check-unused-files`, to search for unused Dart files.

```sh
$ dart run dart_code_metrics:metrics check-unused-files lib

# or for a Flutter package
$ flutter pub run dart_code_metrics:metrics check-unused-files lib
```

Full command description:


```sh
Check unused *.dart files.

Usage: metrics check-unused-files [arguments] <directories>
-h, --help                                        Print this usage information.


-r, --reporter=<console>                          The format of the output of the analysis.
                                                  [console (default), json]


    --root-folder=<./>                            Root folder.
    --exclude=<{/**.g.dart,/**.template.dart}>    File paths in Glob syntax to be excluded.
                                                  (defaults to "{/**.g.dart,/**.template.dart}")

```

When will you need to search for unused files?

Two scenarios come to mind right away:

1. When you need to do a step-by-step refactoring on a large codebase with moving files and it's difficult to know if all the files are being used correctly

2. Code generation, which creates extra files, is popular in Dart. Sometimes it can be difficult to know if these files are no longer in use.

## So what’s under the hood?

The search for unused files starts with listing the files within the passed (sub)directories. Then we check the list of imports, exports, and part-directives in each file. If the imported/exported file belongs to this package, then it’s marked accordingly: “in use.” Files with exports or the main function are separately marked as entry points and “in use.”

After that, unused files are displayed in the following format:

```sh
Unused file: <path_to_file>
   ...
Unused file: <path_to_file>

Total unused files - N
```

Let's take a project with the following structure:

```
 lib/
   src/
     entry_point.dart
     first_file.dart
     second_file.dart
```

And with file content like this:

**entry_point.dart**

```dart
import 'first_file.dart';

void main() {
  ... // some code
}
```

**first_file.dart**

```dart
class SomeClass {
  ... // some code
}
```

**second_file.dart**

```dart
import 'first_file.dart';

class SomeOtherClass {
  ... // some code
}
```

Now we can call the command:

```sh
$ dart run dart_code_metrics:metrics check-unused-files lib
```

In the first step, the algorithm will determine that there are only three files in the project and will scan them first. After **entry_point.dart** is scanned, **first_file.dart** is marked as “in use” because it’s imported into **entry_point.dart**. This will mark **entry_point.dart** as “in use” since it declares the main function. Next, the algorithm will check **first_file.dart**, which has no directives, and then **second_file.dart**. Since **second_file.dart** doesn’t import any of the previous files, it’ll be marked as unused.

We can exclude second_file.dart from the results by passing the `--exclude` option:

```sh
$ dart run dart_code_metrics:metrics check-unused-files lib --exclude=”lib/**/second_file.dart”
```
In this case, the command will output:

```sh
No unused files found!
```

The command is available during the installation of the pre-release version, 4.0.0-dev.4.

Why did we decide to make a separate command, not add a search for used files to the existing call, and not provide support for the analyzer plugin? Because finding unused files seems to be an infrequent feature, while constantly checking is definitely overhead.

The previous call to code analyzer is now also available via the `analyze` command. If you used to call CLI with:

```sh
$ dart run dart_code_mertics:metrics lib
```

It’ll now look like this:

```sh
$ dart run dart_code_mertics:metrics analyze lib.
```

In version 4.0, we have support for `dart run dart_code_mertics:metrics lib`. It’ll work at least up to version 5.0, so no changes will be required to CI after transitioning to a newer version.

We’d love to hear your feedback and ideas on the new rules, metrics, or commands! You can always reach us via the community [chat on Telegram](https://t.me/DartCodeMetrics) or post the [issue on GitHub](https://github.com/dart-code-checker/dart-code-metrics/issues).

This command is just a part of the 4.0 release, which also includes new rules. We’ll discuss them in the next article.

**P.S.** We are currently working on adding new commands and the next candidate is a command to check unused mocks in a project (might help with cases, when you keep all your mocks in a single file and they eventually become unused). Please let us know what do you think about this command, will it be useful for you?