resolvePackages static method
Future<PackageMap>
resolvePackages({
- required String workspacePath,
- required List<
Glob> packages, - required List<
Glob> ignore, - required MelosLogger logger,
Implementation
static Future<PackageMap> resolvePackages({
required String workspacePath,
required List<Glob> packages,
required List<Glob> ignore,
required MelosLogger logger,
}) async {
final packageMap = <String, Package>{};
final dartToolGlob =
createGlob('**/.dart_tool', currentDirectoryPath: workspacePath);
// Flutter symlinked plugins for iOS/macOS should not be included in the package list.
final symlinksPluginsGlob = createGlob(
'**/.symlinks/plugins',
currentDirectoryPath: workspacePath,
);
// Flutter version manager should not be included in the package list.
final fvmGlob = createGlob(
'**/.fvm',
currentDirectoryPath: workspacePath,
);
// Ephemeral plugin symlinked packages should not be included in the package
// list.
final pluginSymlinksGlob = createGlob(
'**/.plugin_symlinks',
currentDirectoryPath: workspacePath,
);
final pubspecsByResolvedPath =
HashMap<String, File>(equals: p.equals, hashCode: p.hash);
Stream<FileSystemEntity> allWorkspaceEntities() async* {
final workspaceDir = Directory(workspacePath);
yield workspaceDir;
yield* workspaceDir.listConditionallyRecursive(
recurseCondition: (dir) {
final path = dir.path;
return !dartToolGlob.matches(path) &&
!symlinksPluginsGlob.matches(path) &&
!fvmGlob.matches(path) &&
!pluginSymlinksGlob.matches(path);
},
);
}
await for (final entity in allWorkspaceEntities()) {
final path = entity.path;
late final isIncluded = packages.any((glob) => glob.matches(path)) &&
!ignore.any((glob) => glob.matches(path));
if (entity is File && p.basename(path) == 'pubspec.yaml' && isIncluded) {
final resolvedPath = await entity.resolveSymbolicLinks();
pubspecsByResolvedPath[resolvedPath] = entity;
} else if (entity is Directory &&
isPackageDirectory(entity.path) &&
isIncluded) {
final pubspecPath = p.join(path, 'pubspec.yaml');
pubspecsByResolvedPath[pubspecPath] = File(pubspecPath);
}
}
final allPubspecs = pubspecsByResolvedPath.values;
await Future.wait<void>(
allPubspecs.map((pubspecFile) async {
final pubspecDirPath = pubspecFile.parent.path;
final pubSpec = await PubSpec.load(pubspecFile.parent);
final name = pubSpec.name!;
if (packageMap.containsKey(name)) {
throw MelosConfigException(
'''
Multiple packages with the name `$name` found in the workspace, which is unsupported.
To fix this problem, consider renaming your packages to have a unique name.
The packages that caused the problem are:
- $name at ${printablePath(relativePath(pubspecDirPath, workspacePath))}
- $name at ${printablePath(relativePath(packageMap[name]!.path, workspacePath))}
''',
);
}
packageMap[name] = Package(
name: name,
path: pubspecDirPath,
pathRelativeToWorkspace: relativePath(pubspecDirPath, workspacePath),
version: pubSpec.version ?? Version.none,
publishTo: pubSpec.publishTo,
packageMap: packageMap,
dependencies: pubSpec.dependencies.keys.toList(),
devDependencies: pubSpec.devDependencies.keys.toList(),
dependencyOverrides: pubSpec.dependencyOverrides.keys.toList(),
pubSpec: pubSpec,
);
}),
);
return PackageMap(packageMap, logger);
}