Dependencies can be more than imports or used binaries
From the README:
Some packages are not imported by any dart files but are used for their executables.
Based on this sentence I'm assuming that only import statements are found programatically. There is another way that a dependency can sneak in that you might want to consider, or at least warn in the readme so it can be treated the same way as executables.
If a class is returned from an API that isn't defined in the package, you can silently be depending on a method signature defined in some other package that you might not import.
import 'package:b/b.dart' as b;
// no import to package:c
void main() {
b.someBMethod().someCMethod();
// If someBMethod returned a class from C I have an implicit dependency on C
}
Here package:b could plausibly move to a new version of package:c without a breaking change version bump.
With type inference this 'type leaking' can happen in sneaker ways:
import 'package:b/b.dart' as b;
// no import to package:c
void main() {
// Assume someBMethod has the signature: int someBMethod(C c)
var x = someBMethod;
x = (value) => value.someCMethod();
// due to type inference I got autocomplete and would now break if someCMethod is renamed.
}
Hmm, that's interesting. I don't see this as an issue because if you are using package c's API through package b you are really just using package b's API. And it would be up to package b to not introduce breaking changes when consuming those API members that it exposes through package c.
There are definitely multiple ways to view this. If we consider that b's API encompasses everything reachable using type inference it can cause the 'apparent' API to expand very big very fast, and if we ask package authors to consider anything across this entire surface their responsibility I think the number of breaking change version bumps would escalate higher than is useful.
It's also interesting to note that with small tweaks to the code the import to c becomes necessary and we'd suggest adding to the dependency, without meaningfully changing the code.
The following snippets are equivalent:
b.someBMethod().someCMethod();
var c = b.someBMethod();
c.someCMethod();
C c = b.someBMethod();
c.someCMethod();
Only the last requires the import to c. It feels odd to me that adding an explicit type also changes your dependencies.