From a01a8023b34f9687685d1c0511701e01b0185c51 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Tue, 20 Jun 2023 11:42:20 +0000 Subject: [PATCH] Add missing await (and make downstream async) --- lib/src/command/deps.dart | 94 +++++++++++++++++++++++---------------- lib/src/entrypoint.dart | 44 ++++++++++-------- lib/src/executable.dart | 10 ++--- 3 files changed, 86 insertions(+), 62 deletions(-) diff --git a/lib/src/command/deps.dart b/lib/src/command/deps.dart index a3e2be82b..69c3225e6 100644 --- a/lib/src/command/deps.dart +++ b/lib/src/command/deps.dart @@ -93,11 +93,13 @@ class DepsCommand extends PubCommand { final visited = []; final toVisit = [entrypoint.root.name]; final packagesJson = []; + final graph = await entrypoint.packageGraph; while (toVisit.isNotEmpty) { final current = toVisit.removeLast(); if (visited.contains(current)) continue; visited.add(current); - final currentPackage = entrypoint.packageGraph.packages[current]!; + final currentPackage = + (await entrypoint.packageGraph).packages[current]!; final next = (current == entrypoint.root.name ? entrypoint.root.immediateDependencies : currentPackage.dependencies) @@ -126,7 +128,7 @@ class DepsCommand extends PubCommand { for (final package in [ entrypoint.root, ...entrypoint.root.immediateDependencies.keys - .map((name) => entrypoint.packageGraph.packages[name]) + .map((name) => graph.packages[name]) ]) ...package!.executableNames.map( (name) => package == entrypoint.root @@ -151,7 +153,7 @@ class DepsCommand extends PubCommand { ); } else { if (argResults.flag('executables')) { - _outputExecutables(buffer); + await _outputExecutables(buffer); } else { for (var sdk in sdks.values) { if (!sdk.isAvailable) continue; @@ -162,13 +164,13 @@ class DepsCommand extends PubCommand { switch (argResults['style']) { case 'compact': - _outputCompact(buffer); + await _outputCompact(buffer); break; case 'list': - _outputList(buffer); + await _outputList(buffer); break; case 'tree': - _outputTree(buffer); + await _outputTree(buffer); break; } } @@ -183,40 +185,44 @@ class DepsCommand extends PubCommand { /// For each dependency listed, *that* package's immediate dependencies are /// shown. Unlike [_outputList], this prints all of these dependencies on one /// line. - void _outputCompact( + Future _outputCompact( StringBuffer buffer, - ) { + ) async { var root = entrypoint.root; - _outputCompactPackages('dependencies', root.dependencies.keys, buffer); + await _outputCompactPackages( + 'dependencies', + root.dependencies.keys, + buffer, + ); if (_includeDev) { - _outputCompactPackages( + await _outputCompactPackages( 'dev dependencies', root.devDependencies.keys, buffer, ); } - _outputCompactPackages( + await _outputCompactPackages( 'dependency overrides', root.dependencyOverrides.keys, buffer, ); - var transitive = _getTransitiveDependencies(); - _outputCompactPackages('transitive dependencies', transitive, buffer); + var transitive = await _getTransitiveDependencies(); + await _outputCompactPackages('transitive dependencies', transitive, buffer); } /// Outputs one section of packages in the compact output. - void _outputCompactPackages( + Future _outputCompactPackages( String section, Iterable names, StringBuffer buffer, - ) { + ) async { if (names.isEmpty) return; buffer.writeln(); buffer.writeln('$section:'); for (var name in ordered(names)) { - var package = _getPackage(name); + var package = await _getPackage(name); buffer.write('- ${_labelPackage(package)}'); if (package.dependencies.isEmpty) { @@ -234,37 +240,45 @@ class DepsCommand extends PubCommand { /// /// For each dependency listed, *that* package's immediate dependencies are /// shown. - void _outputList(StringBuffer buffer) { + Future _outputList(StringBuffer buffer) async { var root = entrypoint.root; - _outputListSection('dependencies', root.dependencies.keys, buffer); + await _outputListSection('dependencies', root.dependencies.keys, buffer); if (_includeDev) { - _outputListSection('dev dependencies', root.devDependencies.keys, buffer); + await _outputListSection( + 'dev dependencies', + root.devDependencies.keys, + buffer, + ); } - _outputListSection( + await _outputListSection( 'dependency overrides', root.dependencyOverrides.keys, buffer, ); - var transitive = _getTransitiveDependencies(); + var transitive = await _getTransitiveDependencies(); if (transitive.isEmpty) return; - _outputListSection('transitive dependencies', ordered(transitive), buffer); + await _outputListSection( + 'transitive dependencies', + ordered(transitive), + buffer, + ); } /// Outputs one section of packages in the list output. - void _outputListSection( + Future _outputListSection( String name, Iterable deps, StringBuffer buffer, - ) { + ) async { if (deps.isEmpty) return; buffer.writeln(); buffer.writeln('$name:'); for (var name in deps) { - var package = _getPackage(name); + var package = await _getPackage(name); buffer.writeln('- ${_labelPackage(package)}'); for (var dep in package.dependencies.values) { @@ -279,9 +293,9 @@ class DepsCommand extends PubCommand { /// dependency), later ones are not traversed. This is done in breadth-first /// fashion so that a package will always be expanded at the shallowest /// depth that it appears at. - void _outputTree( + Future _outputTree( StringBuffer buffer, - ) { + ) async { // The work list for the breadth-first traversal. It contains the package // being added to the tree, and the parent map that will receive that // package. @@ -296,7 +310,7 @@ class DepsCommand extends PubCommand { immediateDependencies.removeAll(entrypoint.root.devDependencies.keys); } for (var name in immediateDependencies) { - toWalk.add(Pair(_getPackage(name), packageTree)); + toWalk.add(Pair(await _getPackage(name), packageTree)); } // Do a breadth-first walk to the dependency graph. @@ -317,7 +331,7 @@ class DepsCommand extends PubCommand { map[_labelPackage(package)] = childMap; for (var dep in package.dependencies.values) { - toWalk.add(Pair(_getPackage(dep.name), childMap)); + toWalk.add(Pair(await _getPackage(dep.name), childMap)); } } @@ -328,8 +342,8 @@ class DepsCommand extends PubCommand { '${log.bold(package.name)} ${package.version}'; /// Gets the names of the non-immediate dependencies of the root package. - Set _getTransitiveDependencies() { - var transitive = _getAllDependencies(); + Future> _getTransitiveDependencies() async { + var transitive = await _getAllDependencies(); var root = entrypoint.root; transitive.remove(root.name); transitive.removeAll(root.dependencies.keys); @@ -340,13 +354,16 @@ class DepsCommand extends PubCommand { return transitive; } - Set _getAllDependencies() { - if (_includeDev) return entrypoint.packageGraph.packages.keys.toSet(); + Future> _getAllDependencies() async { + final graph = await entrypoint.packageGraph; + if (_includeDev) { + return graph.packages.keys.toSet(); + } var nonDevDependencies = entrypoint.root.dependencies.keys.toList() ..addAll(entrypoint.root.dependencyOverrides.keys); return nonDevDependencies - .expand((name) => entrypoint.packageGraph.transitiveDependencies(name)) + .expand(graph.transitiveDependencies) .map((package) => package.name) .toSet(); } @@ -357,22 +374,23 @@ class DepsCommand extends PubCommand { /// It's very unlikely that the lockfile won't be up-to-date with the pubspec, /// but it's possible, since [Entrypoint.assertUpToDate]'s modification time /// check can return a false negative. This fails gracefully if that happens. - Package _getPackage(String name) { - var package = entrypoint.packageGraph.packages[name]; + Future _getPackage(String name) async { + var package = (await entrypoint.packageGraph).packages[name]; if (package != null) return package; dataError('The pubspec.yaml file has changed since the pubspec.lock file ' 'was generated, please run "$topLevelProgram pub get" again.'); } /// Outputs all executables reachable from [entrypoint]. - void _outputExecutables(StringBuffer buffer) { + Future _outputExecutables(StringBuffer buffer) async { + final graph = await entrypoint.packageGraph; var packages = [ entrypoint.root, ...(_includeDev ? entrypoint.root.immediateDependencies : entrypoint.root.dependencies) .keys - .map((name) => entrypoint.packageGraph.packages[name]!) + .map((name) => graph.packages[name]!) ]; for (var package in packages) { diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index cb1eceed5..d37c8eda1 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart @@ -167,10 +167,14 @@ class Entrypoint { /// /// Throws a [DataError] if the `.dart_tool/package_config.json` file isn't /// up-to-date relative to the pubspec and the lockfile. - PackageGraph get packageGraph => _packageGraph ??= _createPackageGraph(); - - PackageGraph _createPackageGraph() { - ensureUpToDate(); // TODO, really? + Future get packageGraph => + _packageGraph ??= _createPackageGraph(); + + Future _createPackageGraph() async { + // TODO(sigurdm): consider having [ensureUptoDate] and [AcquireDependencies] + // return the package-graph, such it by construction will always made from an + // up-to-date package-config. + await ensureUpToDate(); var packages = { for (var packageEntry in packageConfig.nonInjectedPackages) packageEntry.name: Package.load( @@ -184,7 +188,7 @@ class Entrypoint { return PackageGraph(this, packages); } - PackageGraph? _packageGraph; + Future? _packageGraph; /// Where the lock file and package configurations are to be found. /// @@ -275,7 +279,8 @@ class Entrypoint { SolveResult? solveResult, }) : rootDir = _root.dir { if (solveResult != null) { - _packageGraph = PackageGraph.fromSolveResult(this, solveResult); + _packageGraph = + Future.value(PackageGraph.fromSolveResult(this, solveResult)); } } @@ -421,7 +426,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without /// Build a package graph from the version solver results so we don't /// have to reload and reparse all the pubspecs. - _packageGraph = PackageGraph.fromSolveResult(this, result); + _packageGraph = Future.value(PackageGraph.fromSolveResult(this, result)); await writePackageConfigFile(); @@ -429,7 +434,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without if (precompile) { await precompileExecutables(); } else { - _deleteExecutableSnapshots(changed: result.changedPackages); + await _deleteExecutableSnapshots(changed: result.changedPackages); } } catch (error, stackTrace) { // Just log exceptions here. Since the method is just about acquiring @@ -446,7 +451,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without /// /// Except globally activated packages they should precompile executables from /// the package itself if they are immutable. - List get _builtExecutables { + Future> get _builtExecutables async { if (isGlobal) { if (isCached) { return root.executablePaths @@ -456,8 +461,9 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without return []; } } + final graph = await packageGraph; final r = root.immediateDependencies.keys.expand((packageName) { - final package = packageGraph.packages[packageName]!; + final package = graph.packages[packageName]!; return package.executablePaths .map((path) => Executable(packageName, path)); }).toList(); @@ -466,7 +472,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without /// Precompiles all [_builtExecutables]. Future precompileExecutables() async { - final executables = _builtExecutables; + final executables = await _builtExecutables; if (executables.isEmpty) return; @@ -524,7 +530,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without final package = executable.package; await dart.precompile( - executablePath: resolveExecutable(executable), + executablePath: await resolveExecutable(executable), outputPath: pathOfExecutable(executable), incrementalDillPath: incrementalDillPathOfExecutable(executable), packageConfigPath: packageConfigPath, @@ -572,9 +578,9 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without } /// The absolute path of [executable] resolved relative to [this]. - String resolveExecutable(Executable executable) { + Future resolveExecutable(Executable executable) async { return p.join( - packageGraph.packages[executable.package]!.dir, + (await packageGraph).packages[executable.package]!.dir, executable.relativePath, ); } @@ -583,7 +589,7 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without /// /// If [changed] is passed, only dependencies whose contents might be changed /// if one of the given packages changes will have their executables deleted. - void _deleteExecutableSnapshots({Iterable? changed}) { + Future _deleteExecutableSnapshots({Iterable? changed}) async { if (!dirExists(_snapshotPath)) return; // If we don't know what changed, we can't safely re-use any snapshots. @@ -603,15 +609,15 @@ To update `$lockFilePath` run `$topLevelProgram pub get`$suffix without deleteEntry(_snapshotPath); return; } + final graph = await packageGraph; // Clean out any outdated snapshots. for (var entry in listDir(_snapshotPath)) { if (!dirExists(entry)) continue; - var package = p.basename(entry); - if (!packageGraph.packages.containsKey(package) || - packageGraph.isPackageMutable(package) || - packageGraph + if (!graph.packages.containsKey(package) || + graph.isPackageMutable(package) || + graph .transitiveDependencies(package) .any((dep) => changedDeps.contains(dep.name))) { deleteEntry(entry); diff --git a/lib/src/executable.dart b/lib/src/executable.dart index 578966549..b54397f19 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -57,7 +57,7 @@ Future runExecutable( // entrypoint itself. if (entrypoint.root.name != executable.package && !entrypoint.root.immediateDependencies.containsKey(package)) { - if (entrypoint.packageGraph.packages.containsKey(package)) { + if ((await entrypoint.packageGraph).packages.containsKey(package)) { dataError('Package "$package" is not an immediate dependency.\n' 'Cannot run executables in transitive dependencies.'); } else { @@ -76,7 +76,7 @@ Future runExecutable( // later invocation. var useSnapshot = vmArgs.isEmpty; - var executablePath = entrypoint.resolveExecutable(executable); + var executablePath = await entrypoint.resolveExecutable(executable); if (!fileExists(executablePath)) { var message = 'Could not find ${log.bold(p.normalize(executable.relativePath))}'; @@ -93,7 +93,7 @@ Future runExecutable( await entrypoint.ensureUpToDate(); if (!fileExists(snapshotPath) || - entrypoint.packageGraph.isPackageMutable(package)) { + (await entrypoint.packageGraph).isPackageMutable(package)) { await recompile(executable); } executablePath = snapshotPath; @@ -349,7 +349,7 @@ Future getExecutableForCommand( } final executable = Executable(package, p.join('bin', '$command.dart')); - final path = entrypoint.resolveExecutable(executable); + final path = await entrypoint.resolveExecutable(executable); if (!fileExists(path)) { throw CommandResolutionFailedException._( 'Could not find `bin${p.separator}$command.dart` in package `$package`.', @@ -366,7 +366,7 @@ Future getExecutableForCommand( } else { final snapshotPath = entrypoint.pathOfExecutable(executable); if (!fileExists(snapshotPath) || - entrypoint.packageGraph.isPackageMutable(package)) { + (await entrypoint.packageGraph).isPackageMutable(package)) { try { await errorsOnlyUnlessTerminal( () => entrypoint.precompileExecutable(