diff --git a/.gitignore b/.gitignore index 03e2596b9c6..0ca4695bfae 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,6 @@ runtime/tools/heapsnapshot/.dart_tool .cipd .gclient .gclient_* + +# Gemini CLI +.gemini diff --git a/pkg/dart2native/lib/generate.dart b/pkg/dart2native/lib/generate.dart index 3596c447a01..e66f5128d83 100644 --- a/pkg/dart2native/lib/generate.dart +++ b/pkg/dart2native/lib/generate.dart @@ -5,6 +5,9 @@ import 'dart:io'; import 'package:code_assets/code_assets.dart' show OS; +// ignore: implementation_imports (This file is imported in other packages.) +import 'package:front_end/src/api_prototype/compiler_options.dart' + show Verbosity; import 'package:path/path.dart' as path; import 'dart2native.dart'; @@ -304,7 +307,9 @@ class _Generator { } } - print('Generated: $outputPath'); + if (_verbosity != Verbosity.error.name) { + print('Generated: $outputPath'); + } } Future _concatenateAssetsToKernel(String? nativeAssets) async { diff --git a/pkg/dart2native/pubspec.yaml b/pkg/dart2native/pubspec.yaml index a396ef380b3..f660fec250c 100644 --- a/pkg/dart2native/pubspec.yaml +++ b/pkg/dart2native/pubspec.yaml @@ -15,6 +15,7 @@ executables: dependencies: code_assets: any collection: any + front_end: any kernel: any path: any diff --git a/pkg/dartdev/lib/src/commands/build.dart b/pkg/dartdev/lib/src/commands/build.dart index 9742e3ced4d..f50354821c2 100644 --- a/pkg/dartdev/lib/src/commands/build.dart +++ b/pkg/dartdev/lib/src/commands/build.dart @@ -252,13 +252,20 @@ See documentation on https://dart.dev/interop/c-interop#native-assets. verbose: verbose, dataAssetsExperimentEnabled: dataAssetsExperimentEnabled, ); - final buildResult = await progress( - 'Running build hooks', - builder.buildNativeAssetsAOT, - ); - if (buildResult == null) { - stderr.writeln('Running build hooks failed.'); - return 255; + final showProgress = verbosity != Verbosity.error.name; + BuildResult? buildResult; + final hasHooks = await builder.hasHooks(); + if (hasHooks) { + buildResult = await (showProgress + ? progress( + 'Running build hooks', + builder.buildNativeAssetsAOT, + ) + : builder.buildNativeAssetsAOT()); + if (buildResult == null) { + stderr.writeln('Running build hooks failed.'); + return 255; + } } final tempDir = Directory.systemTemp.createTempSync(); @@ -296,22 +303,31 @@ See documentation on https://dart.dev/interop/c-interop#native-assets. if (first) { // Multiple executables are only supported with recorded uses // disabled, so don't re-invoke link hooks. - linkResult = await progress( - 'Running link hooks', - () => builder.linkNativeAssetsAOT( - recordedUsagesPath: recordedUsagesPath, - buildResult: buildResult, - ), - ); - } - if (linkResult == null) { - stderr.writeln('Running link hooks failed.'); - return 255; + if (hasHooks) { + linkResult = await (showProgress + ? progress( + 'Running link hooks', + () => builder.linkNativeAssetsAOT( + recordedUsagesPath: recordedUsagesPath, + buildResult: buildResult!, + ), + ) + : builder.linkNativeAssetsAOT( + recordedUsagesPath: recordedUsagesPath, + buildResult: buildResult!, + )); + if (linkResult == null) { + stderr.writeln('Running link hooks failed.'); + return 255; + } + } } final allAssets = [ - ...buildResult.encodedAssets, - ...linkResult.encodedAssets + if (hasHooks) ...[ + ...buildResult!.encodedAssets, + ...linkResult!.encodedAssets + ] ]; final staticAssets = allAssets diff --git a/pkg/dartdev/lib/src/commands/install.dart b/pkg/dartdev/lib/src/commands/install.dart index d206bd17e0e..abf6cc26a0d 100644 --- a/pkg/dartdev/lib/src/commands/install.dart +++ b/pkg/dartdev/lib/src/commands/install.dart @@ -7,6 +7,8 @@ import 'dart:io'; import 'package:dartdev/src/commands/build.dart'; import 'package:dartdev/src/install/file_system.dart'; import 'package:dartdev/src/install/pub_formats.dart'; +import 'package:front_end/src/api_prototype/compiler_options.dart' + show Verbosity; import 'package:path/path.dart' as p; import 'package:pub/pub.dart'; import 'package:pub_formats/pub_formats.dart'; @@ -260,6 +262,7 @@ You can specify three different values for the argument: File helperPackageConfigFile, File sourcePackagePubspecFile, bool verbose, + String verbosity, ) async { // TODO(https://github.com/dart-lang/native/issues/2465): Add a test for // user-defines in the source package pubspec. @@ -272,7 +275,7 @@ You can specify three different values for the argument: recordUseEnabled: false, dataAssetsExperimentEnabled: false, verbose: verbose, - verbosity: 'all', + verbosity: verbosity, ); if (buildResult != 0) { installException('Build failed.', exitCode: buildResult); @@ -536,12 +539,14 @@ You can specify three different values for the argument: final buildDirectory = Directory.fromUri(tempDirectory.uri.resolve('build/')); + await doBuild( executables, buildDirectory, helperPackageConfigFile, sourcePackagePubspecFile, verbose, + Verbosity.all.name, ); _uniinstallAllPackageVersions(packageName); diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart index a554566fa99..298ac7fb64d 100644 --- a/pkg/dartdev/lib/src/commands/run.dart +++ b/pkg/dartdev/lib/src/commands/run.dart @@ -664,7 +664,8 @@ Usage: dart [vm-options] run [arguments] [||` uses `dart install` under the hood ' @@ -793,12 +794,14 @@ Usage: dart [vm-options] run [arguments] [|| args) async { expect(firstRunResult.stdout, contains('Hello World')); expect(firstRunResult.exitCode, 0); expect(firstRunResult.stdout, contains('Generated: ')); + // No hooks. + expect(firstRunResult.stdout, isNot(contains('Running build hooks'))); + expect(firstRunResult.stdout, isNot(contains('Running link hooks'))); // 4. Second run - should be cached final secondRunResult = await _runDartdev( @@ -352,6 +355,63 @@ void main(List args) async { expect(secondRunResult.stdout, isNot(contains('Generated: '))); }); }); + + for (final verbosityError in [true, false]) { + final testName = verbosityError ? ' --verbosity=error' : ''; + test('dart run from git with build hook$testName', timeout: longTimeout, + () async { + await inTempDir((tempUri) async { + const packageName = 'test_app_with_hook'; + final (gitUri, gitRef) = await _setupGitRepoWithHook( + tempUri, + packageName: packageName, + ); + + final arguments = [ + if (verbosityError) '--verbosity=error', + '--git-ref', + gitRef, + '${gitUri.toFilePath()}:$packageName', + 'ignored', + 'arguments', + ]; + + final dartDataHome = tempUri.resolve('dart_home/'); + await Directory.fromUri(dartDataHome).create(); + final binDir = Directory.fromUri(dartDataHome.resolve('install/bin')); + + final environment = { + _dartDirectoryEnvKey: dartDataHome.toFilePath(), + 'PATH': + '${binDir.path}$_pathEnvVarSeparator${Platform.environment['PATH']!}', + }; + + print(environment); + print('dart run ${arguments.join(' ')}'); + final runResult = await _runDartdev( + fromDartdevSource, + 'run', + arguments, + null, + environment, + ); + + expect(runResult.stdout, contains('Hello World')); + expect(runResult.exitCode, 0); + if (verbosityError) { + expect(runResult.stdout, isNot(contains('Running build hooks'))); + expect(runResult.stdout, isNot(contains('Running link hooks'))); + expect(runResult.stdout, isNot(contains('Generated: '))); + // Should have no other output then the program. + expect(runResult.stdout.trim(), equals('Hello World')); + } else { + expect(runResult.stdout, contains('Running build hooks')); + expect(runResult.stdout, contains('Running link hooks')); + expect(runResult.stdout, contains('Generated: ')); + } + }); + }); + } } Future<(Uri gitUri, String gitRef)> _setupGitRepo( @@ -394,6 +454,57 @@ Future<(Uri gitUri, String gitRef)> _setupGitRepo( return (gitUri, gitRef); } +Future<(Uri gitUri, String gitRef)> _setupGitRepoWithHook( + Uri tempUri, { + String packageName = 'test_app_with_hook', +}) async { + return await _setupGitRepo( + tempUri, + repoName: '$packageName.git', + files: { + 'pubspec.yaml': jsonEncode(PubspecYamlFileSyntax( + name: packageName, + environment: EnvironmentSyntax( + sdk: '^3.8.0', + ), + executables: { + packageName: null, + }, + dependencies: { + // Git dependencies can't have path dependencies outside the git repo + // so use a published dependency. + 'hooks': HostedDependencySourceSyntax( + version: '^1.0.0', + ), + }, + ).json), + 'bin/$packageName.dart': ''' +void main(List args) { + print('Hello World'); +} +''', + 'hook/build.dart': ''' +import 'package:hooks/hooks.dart'; + +void main(List args) async { + await build(args, (input, output) async { + // Succeeds. + }); +} +''', + 'hook/link.dart': ''' +import 'package:hooks/hooks.dart'; + +void main(List args) async { + await link(args, (input, output) async { + // Succeeds. + }); +} +''', + }, + ); +} + Future<(Uri gitUri, String gitRef)> _setupSimpleGitRepo(Uri tempUri) async { return await _setupGitRepo( tempUri,