From 017ab9790777b0b734526ba9b9c0fcee93bd5550 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Thu, 26 Sep 2024 10:00:43 +0200 Subject: [PATCH] Webdev: Look for pubspec.yaml next to .dart_tool/package_config.json instead of only current dir (#2498) --- webdev/CHANGELOG.md | 2 ++ webdev/lib/src/command/build_command.dart | 5 ++- webdev/lib/src/command/daemon_command.dart | 5 ++- webdev/lib/src/command/serve_command.dart | 5 ++- webdev/lib/src/command/shared.dart | 6 ++-- webdev/lib/src/pubspec.dart | 42 +++++++++++----------- 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/webdev/CHANGELOG.md b/webdev/CHANGELOG.md index 673f742cf..113a96acf 100644 --- a/webdev/CHANGELOG.md +++ b/webdev/CHANGELOG.md @@ -4,6 +4,8 @@ - Update `dwds` constraint to `24.1.0`. +- Support running from inside a pub workspace [#2498](https://github.com/dart-lang/webdev/pull/2498). + ## 3.5.0 - Update `dwds` constraint to `24.0.0`. diff --git a/webdev/lib/src/command/build_command.dart b/webdev/lib/src/command/build_command.dart index a3cfde49a..b4db27d1c 100644 --- a/webdev/lib/src/command/build_command.dart +++ b/webdev/lib/src/command/build_command.dart @@ -52,9 +52,8 @@ class BuildCommand extends Command { List arguments; try { - var pubspecLock = await readPubspecLock(configuration); - arguments = buildRunnerArgs(pubspecLock, configuration) - ..addAll(validExtraArgs); + await validatePubspecLock(configuration); + arguments = buildRunnerArgs(configuration)..addAll(validExtraArgs); } on PackageException catch (e) { logWriter(logging.Level.SEVERE, 'Pubspec errors: ', error: '${e.details}'); diff --git a/webdev/lib/src/command/daemon_command.dart b/webdev/lib/src/command/daemon_command.dart index 1590289fe..c5b4c34c8 100644 --- a/webdev/lib/src/command/daemon_command.dart +++ b/webdev/lib/src/command/daemon_command.dart @@ -66,9 +66,8 @@ class DaemonCommand extends Command { launchInChrome: true, debug: true, autoRun: false, release: false)); configureLogWriter(configuration.verbose); // Validate the pubspec first to ensure we are in a Dart project. - PubspecLock? pubspecLock; try { - pubspecLock = await readPubspecLock(configuration); + await validatePubspecLock(configuration); } on PackageException catch (e) { logWriter(Level.SEVERE, 'Pubspec errors: ', error: '${e.details}'); rethrow; @@ -104,7 +103,7 @@ class DaemonCommand extends Command { } }); daemon.registerDomain(daemonDomain); - var buildOptions = buildRunnerArgs(pubspecLock, configuration); + var buildOptions = buildRunnerArgs(configuration); var extraArgs = argResults?.rest ?? []; var directoryArgs = extraArgs.where((arg) => !arg.startsWith('-')).toList(); diff --git a/webdev/lib/src/command/serve_command.dart b/webdev/lib/src/command/serve_command.dart index 3ef0d5372..127b26e0e 100644 --- a/webdev/lib/src/command/serve_command.dart +++ b/webdev/lib/src/command/serve_command.dart @@ -95,16 +95,15 @@ refresh: Performs a full page refresh. Configuration configuration; configuration = Configuration.fromArgs(argResults); configureLogWriter(configuration.verbose); - PubspecLock? pubspecLock; try { - pubspecLock = await readPubspecLock(configuration); + await validatePubspecLock(configuration); } on PackageException catch (e) { logWriter(Level.SEVERE, 'Pubspec errors: ', error: '${e.details}'); rethrow; } // Forward remaining arguments as Build Options to the Daemon. // This isn't documented. Should it be advertised? - var buildOptions = buildRunnerArgs(pubspecLock, configuration) + var buildOptions = buildRunnerArgs(configuration) ..addAll(argResults!.rest.where((arg) => arg.startsWith('-')).toList()); var extraArgs = argResults?.rest ?? []; var directoryArgs = extraArgs.where((arg) => !arg.startsWith('-')).toList(); diff --git a/webdev/lib/src/command/shared.dart b/webdev/lib/src/command/shared.dart index cd89a7c69..da952ff94 100644 --- a/webdev/lib/src/command/shared.dart +++ b/webdev/lib/src/command/shared.dart @@ -79,8 +79,7 @@ void addSharedArgs(ArgParser argParser, /// Parses the provided [Configuration] to return a list of /// `package:build_runner` appropriate arguments. -List buildRunnerArgs( - PubspecLock pubspecLock, Configuration configuration) { +List buildRunnerArgs(Configuration configuration) { var arguments = []; if (configuration.release) { arguments.add('--$releaseFlag'); @@ -103,11 +102,10 @@ List buildRunnerArgs( return arguments; } -Future readPubspecLock(Configuration configuration) async { +Future validatePubspecLock(Configuration configuration) async { var pubspecLock = await PubspecLock.read(); await checkPubspecLock(pubspecLock, requireBuildWebCompilers: configuration.requireBuildWebCompilers); - return pubspecLock; } /// Checks that the normalized form of [path] is a top level directory under diff --git a/webdev/lib/src/pubspec.dart b/webdev/lib/src/pubspec.dart index 652ba503f..c2e8eda82 100644 --- a/webdev/lib/src/pubspec.dart +++ b/webdev/lib/src/pubspec.dart @@ -7,6 +7,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart'; +import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:yaml/yaml.dart'; @@ -31,12 +32,6 @@ class PackageExceptionDetails { {this.description, bool missingDependency = false}) : _missingDependency = missingDependency; - static const noPubspecLock = - PackageExceptionDetails._('`pubspec.lock` does not exist.', - description: 'Run `$appName` in a Dart package directory. ' - 'Run `dart pub get` first.', - missingDependency: true); - static PackageExceptionDetails missingDep( String pkgName, VersionConstraint constraint) => PackageExceptionDetails._( @@ -75,9 +70,26 @@ class PubspecLock { static Future read() async { await _runPubDeps(); + var dir = p.absolute(p.current); + while (true) { + final candidate = p.join( + dir, + '.dart_tool', + 'package_config.json', + ); + if (File(candidate).existsSync()) break; + final next = p.dirname(dir); + if (next == dir) { + // Give up. + dir = p.current; + break; + } + dir = next; + } - var pubspecLock = - loadYaml(await File('pubspec.lock').readAsString()) as YamlMap; + var pubspecLock = loadYaml( + await File(p.relative(p.join(dir, 'pubspec.lock'))).readAsString()) + as YamlMap; var packages = pubspecLock['packages'] as YamlMap?; return PubspecLock(packages); @@ -85,7 +97,7 @@ class PubspecLock { List checkPackage( String pkgName, VersionConstraint constraint, - {String? forArgument, bool requireDirect = true}) { + {String? forArgument}) { var issues = []; var missingDetails = PackageExceptionDetails.missingDep(pkgName, constraint); @@ -95,13 +107,6 @@ class PubspecLock { if (pkgDataMap == null) { issues.add(missingDetails); } else { - var dependency = pkgDataMap['dependency'] as String?; - if (requireDirect && - dependency != null && - !dependency.startsWith('direct ')) { - issues.add(missingDetails); - } - var source = pkgDataMap['source'] as String?; if (source == 'hosted') { // NOTE: pkgDataMap['description'] should be: @@ -133,7 +138,6 @@ Future> _validateBuildDaemonVersion( var buildDaemonIssues = pubspecLock.checkPackage( 'build_daemon', VersionConstraint.parse(buildDaemonConstraint), - requireDirect: false, ); // Only warn of build_daemon issues if they have a dependency on the package. @@ -146,8 +150,7 @@ Future> _validateBuildDaemonVersion( // used by their application. if (info.isNewer && pubspecLock - .checkPackage('build_daemon', info.buildDaemonConstraint, - requireDirect: false) + .checkPackage('build_daemon', info.buildDaemonConstraint) .isEmpty) { issues.add(PackageExceptionDetails._('$issuePreamble\n' 'A newer version of webdev is available which supports ' @@ -169,7 +172,6 @@ final buildWebCompilersConstraint = VersionConstraint.parse('^4.0.4'); Future checkPubspecLock(PubspecLock pubspecLock, {required bool requireBuildWebCompilers}) async { var issues = []; - var buildRunnerIssues = pubspecLock.checkPackage('build_runner', buildRunnerConstraint);