forPath static method
Creates a PackageGraph for the package whose top level directory lives
at packagePath
(no trailing slash).
Implementation
static Future<PackageGraph> forPath(String packagePath) async {
/// Read in the pubspec file and parse it as yaml.
final pubspec = File(p.join(packagePath, 'pubspec.yaml'));
if (!pubspec.existsSync()) {
throw StateError(
'Unable to generate package graph, no `pubspec.yaml` found. '
'This program must be ran from the root directory of your package.');
}
final rootPubspec = _pubspecForPath(packagePath);
final rootPackageName = rootPubspec['name'] as String?;
if (rootPackageName == null) {
throw StateError('The current package has no name, please add one to the '
'pubspec.yaml.');
}
final packageConfig =
await findPackageConfig(Directory(packagePath), recurse: false);
if (packageConfig == null) {
throw StateError(
'Unable to find package config for package at $packagePath.');
}
final dependencyTypes = _parseDependencyTypes(packagePath);
final nodes = <String, PackageNode>{};
// A consistent package order _should_ mean a consistent order of build
// phases. It's not a guarantee, but also not required for correctness, only
// an optimization.
final consistentlyOrderedPackages = packageConfig.packages.toList()
..sort((a, b) => a.name.compareTo(b.name));
for (final package in consistentlyOrderedPackages) {
var isRoot = package.name == rootPackageName;
nodes[package.name] = PackageNode(
package.name,
package.root.toFilePath(),
isRoot ? DependencyType.path : dependencyTypes[package.name],
package.languageVersion,
isRoot: isRoot);
}
PackageNode packageNode(String package, {String? parent}) {
final node = nodes[package];
if (node == null) {
throw StateError(
'Dependency $package ${parent != null ? 'of $parent ' : ''}not '
'present, please run `dart pub get` or `flutter pub get` to fetch '
'dependencies.');
}
return node;
}
final rootNode = packageNode(rootPackageName);
rootNode.dependencies.addAll(_depsFromYaml(rootPubspec, isRoot: true)
.map((n) => packageNode(n, parent: rootPackageName)));
final packageDependencies = _parsePackageDependencies(
packageConfig.packages.where((p) => p.name != rootPackageName));
for (final packageName in packageDependencies.keys) {
packageNode(packageName).dependencies.addAll(
packageDependencies[packageName]!
.map((n) => packageNode(n, parent: packageName)));
}
return PackageGraph._(rootNode, nodes);
}