unreachablePackages method

(Set<String>, Set<String>) unreachablePackages(
  1. Iterable<String> packageNames
)

Returns package names in this graph that are not reachable as regular dependencies from packageNames, and package names that remain reachable but change from a direct root dependency to a transitive-only dependency of packageNames.

Only follows PgPackage.dependencies (dev dependencies are ignored). Throws if any name in packageNames is not a root package in this graph.

Implementation

(Set<String> unreachable, Set<String> demotedToTransitive)
unreachablePackages(final Iterable<String> packageNames) {
  final rootsByName = {for (final root in roots) root.name: root};

  final startPackages = <PgPackage>[];
  for (final name in packageNames) {
    final root = rootsByName[name];
    if (root == null) {
      throw ArgumentError.value(
        name,
        'packageNames',
        'Package is not a "root" package in the workspace PackageGraph',
      );
    }
    startPackages.add(root);
  }

  final specifiedNames = {for (final package in startPackages) package.name};
  final allPackages = _collectAllPackages(true);
  final reachable = _reachableViaDependencies(startPackages);

  final directDepsOfAnyRoot = {
    for (final root in roots)
      for (final dependency in root.dependencies) dependency.name,
  };
  final directDepsOfSpecified = {
    for (final root in startPackages)
      for (final dependency in root.dependencies) dependency.name,
  };

  return (
    {
      for (final package in allPackages)
        if (!reachable.contains(package.name)) package.name,
    },
    {
      for (final name in reachable)
        if (directDepsOfAnyRoot.contains(name) &&
            !directDepsOfSpecified.contains(name) &&
            !specifiedNames.contains(name))
          name,
    },
  );
}