dart_apitool updates

Software developmentFlutter
  |  

dart_apitool updates

Recently dart_apitool got 2 significant updates. Thanks to all the contributors that made that possible.

1. More robust preparation step

dart_apitool makes local copies of the packages it analyzes

When dart_apitool analyzes packages it has to do some preparation steps in order to make sure the analysis run doesn’t have any issues:

  1. it has to remove any analysis_options.yaml because this file can limit the scope of the analyzer.
    This is OK if you want to e.g. exclude files from linting but dart_apitool needs to see all of your files to create a complete model of your public API.
  2. it has to remove an example project as it needs to run pub get to get the dependencies prepared and up-to-date for a successful analysis run.
    Some packages have examples bundled with them that sometimes reach into packages via relative paths that live outside the package directory. Those paths are valid inside the package’s repository but are not valid outside of it. A dart_package bundles those examples which means they also live inside the downloaded package and might have invalid relative path dependencies.
    As dart_apitool is not interested in those examples it can just remove them from the package directory and run pub get to get the dependencies.

To not interfer with a local copy of the package (in the pub cache or on disk) dart_apitool makes a temporary copy of the package before manipulating it.

why this is complex and created an issue

This works really well. In the past there has been a special issue if a package was referenced on disk and contains relative path depdendencies. To solve that issue dart_apitool had a functionality to analyzse those path dependencies to determine the directory structure it needs to copy to the temporary directory making the relative path dependencies still work.

In the meantime dart (or better: pub) has a new feature: pubspec_overrides.yaml.
This is a separate file that can be used to override dependencies in a pubspec.yaml. As dart_apitool only looked into the pubspec.yaml it didn’t see those overrides and therefore didn’t know about the relative path dependencies that might be defined in there.
A potential solution to that would have been to also parse the pubspec_overrides.yaml file and take the dependencies defined in there into account.

a smart solution

via GIPHY

But Two Google employees had a much better idea: Once pub get has been run it stores its results in the `.dart_tool` directory. This directory contains a file called `package_config.json` that contains all the (resolved) information about the dependencies of a package. The idea now is that pub get is run once in the source package context and then the `package_config.json` is copied to the temporary directory. All relative paths inside that file get turned into absolute paths pointing to the source directory. This is no issue as we only manipulate the target package and not the packages it may reference via relative paths. This way dart_apitool can leverage all the pub functionality like respecting `pubspec_overrides.yaml` while still having a temporary copy of that package. Having that solution in place also made it possible to remove all the directory structure analysis and dealing logic from dart_apitool as this is no longer needed.

As a user of dart_apitool you won’t notice any of that besides the fact that now pubspec_overrides.yaml is respected and no longer causes issues.

2. new Reporting options

dart_apitool got new options for outputting the result of a diff run:

  • --report-format
    defines the output format to use (cli, json, markdown)
  • --report-file-path
    defines the output path for json and markdown reports

This means you can now more easily integrate dart_apitool into your CI/CD pipeline as you can either use the markdown format to directly incorporate the report in things like GitHub pull request comments or use the JSON format to have other tools process that result and do some additional actions based on that.