From 897809acca4339da15ac13205f2d0e1f252a438a Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 10:50:44 -0700 Subject: [PATCH 1/7] Ship a command with the `devtools_extensions` package to build the extension and copy the assets to the parent package --- packages/devtools_extensions/README.md | 18 ++- .../bin/devtools_extensions.dart | 13 ++ .../lib/src/command/build_extension.dart | 139 ++++++++++++++++++ packages/devtools_extensions/pubspec.yaml | 3 + 4 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 packages/devtools_extensions/bin/devtools_extensions.dart create mode 100644 packages/devtools_extensions/lib/src/command/build_extension.dart diff --git a/packages/devtools_extensions/README.md b/packages/devtools_extensions/README.md index a3df253cc80..dddb9a5a627 100644 --- a/packages/devtools_extensions/README.md +++ b/packages/devtools_extensions/README.md @@ -106,9 +106,9 @@ to interact with DevTools. From anywhere your extension web app, you can access #### Utilize helper packages Use [package:devtools_app_shared](https://pub.dev/packages/devtools_app_shared) for access to -service managers, common widgets, DevTools theming, utilities, and more. - -TODO(kenz): link examples. +service managers, common widgets, DevTools theming, utilities, and more. See the +[devtools_app_shared/example](https://github.com/flutter/devtools/tree/master/packages/devtools_app_shared/example) +directory for sample usages of the different shared libraries from DevTools. ### Debug the extension web app @@ -154,7 +154,13 @@ To use a real DevTools environment, you will need to perform a series of setup s real DevTools environment. Build your flutter web app and copy the built assets from `your_extension_web_app/build` to your pub package's `extension/devtools/build` directory. -> Use the `build_helper.sh` script to help with this step. (TODO(kenz): create and add link to helper script). +Use the `build_extension` command from `package:devtools_extensions` to help with this step. +``` +dart pub global activate devtools_extensions; +dart run devtools_extensions build_and_copy \ + --source=path/to/your_extension_web_app \ + --dest=path/to/your_pub_package/extension/devtools +``` 2. Prepare and run a test application that depends on your pub package. You'll need to change the `pubspec.yaml` dependency to be a `path` dependency that points to your local pub package @@ -162,7 +168,9 @@ source code. Once you have done this, run `pub get`, and run the application. 3. Start DevTools: * **If you need local or unreleased changes from DevTools**, you'll need to build and run DevTools - from source. See `` for a guide on how to do this. + from source. See the DevTools [CONTRIBUTING.md]() for a guide on how to do this. + > Note: you'll need to build DevTools with the server and the front end to test extensions - see + [instructions](https://github.com/flutter/devtools/blob/master/CONTRIBUTING.md#development-devtools-server--devtools-flutter-web-app). * **If not, and if your local Dart or Flutter SDK version is >= ``**, you can launch the DevTools instance that was just started by running your app (either from a url printed to command line or from the IDE where you ran your test app). You can also run diff --git a/packages/devtools_extensions/bin/devtools_extensions.dart b/packages/devtools_extensions/bin/devtools_extensions.dart new file mode 100644 index 00000000000..b97cf885ee9 --- /dev/null +++ b/packages/devtools_extensions/bin/devtools_extensions.dart @@ -0,0 +1,13 @@ +// Copyright 2023 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:args/command_runner.dart'; +import 'package:devtools_extensions/src/command/build_extension.dart'; + +void main(List arguments) async { + final command = BuildExtensionCommand(); + final runner = CommandRunner('devtools_extensions', command.description) + ..addCommand(BuildExtensionCommand()); + await runner.run(arguments); +} diff --git a/packages/devtools_extensions/lib/src/command/build_extension.dart b/packages/devtools_extensions/lib/src/command/build_extension.dart new file mode 100644 index 00000000000..3af1051437b --- /dev/null +++ b/packages/devtools_extensions/lib/src/command/build_extension.dart @@ -0,0 +1,139 @@ +// Copyright 2023 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; + +import 'package:args/command_runner.dart'; +import 'package:io/io.dart'; +import 'package:path/path.dart' as path; + +/// Command that builds a DevTools extension and copies the built output to +/// the parent package extension location. +/// +/// Example usage: +/// +/// dart pub global activate devtools_extensions; +/// dart run devtools_extensions build_and_copy \ +/// --source=path/to/your_extension_web_app \ +/// --dest=path/to/your_pub_package/extension/devtools +class BuildExtensionCommand extends Command { + BuildExtensionCommand() { + argParser + ..addOption( + 'source', + help: 'The source location for the extension flutter web app (can be ' + 'relative or absolute)', + valueHelp: 'path/to/foo/packages/foo_devtools_extension', + ) + ..addOption( + 'dest', + help: 'The destination location for the extension build output (can be ' + 'relative or absolute)', + valueHelp: 'path/to/foo/packages/foo/extension/devtools', + ); + } + + static const _sourceKey = 'source'; + static const _destinationKey = 'dest'; + + String get _logPrefix => '[$name]'; + + @override + final name = 'build_and_copy'; + + @override + final description = + 'Command that builds a DevTools extension from source and copies the ' + 'built output to the parent package extension location.'; + + @override + Future run() async { + final source = argResults?[_sourceKey]; + final destination = argResults?[_destinationKey]; + if (source == null) { + throw ArgumentError( + 'Missing argument \'$_sourceKey\', which describes the source location ' + 'for the extension flutter web app', + _sourceKey, + ); + } + if (destination == null) { + throw ArgumentError( + 'Missing argument \'$_destinationKey\', which describes the source ' + 'location for the extension flutter web app', + _destinationKey, + ); + } + + final processManager = ProcessManager(); + + _log('building the extension flutter web app...'); + final buildProcess = await processManager.spawn( + 'flutter', + [ + 'build', + 'web', + '--web-renderer', + 'canvaskit', + '--pwa-strategy=offline-first', + '--release', + '--no-tree-shake-icons', + ], + workingDirectory: source, + ); + await buildProcess.exitCode; + + _log('setting canvaskit permissions...'); + final chmodProcess = await processManager.spawn( + 'chmod', + ['0755', 'build/web/canvaskit/canvaskit.*'], + workingDirectory: source, + ); + await chmodProcess.exitCode; + + _log('copying built output to the extension destination...'); + await _copyBuildToDestination(source: source, dest: destination); + + // Closes stdin for the entire program. + await sharedStdIn.terminate(); + } + + Future _copyBuildToDestination({ + required String source, + required String dest, + }) async { + _log('copying the extension config.json file into a temp directory...'); + final tmp = Directory.current.createTempSync(); + final tmpConfigPath = path.join(tmp.path, 'config.json'); + final destinationConfigPath = path.join(dest, 'config.json'); + File(destinationConfigPath)..copySync(tmpConfigPath); + + _log('replacing the existing extension build with the new one...'); + final sourceBuildPath = path.join(source, 'build', 'web'); + final destinationBuildPath = path.join(dest, 'build'); + Directory(destinationBuildPath)..deleteSync(recursive: true); + Directory(destinationBuildPath)..createSync(recursive: true); + await copyPath( + sourceBuildPath, + destinationBuildPath, + ); + + _log( + 'copying the extension config.json file back to the destination ' + 'directory...', + ); + File(tmpConfigPath)..copySync(destinationConfigPath); + tmp.deleteSync(recursive: true); + + _log( + 'Successfully copied extension assets from ' + '"${Directory(source).resolveSymbolicLinksSync()}" to' + '"${Directory(dest).resolveSymbolicLinksSync()}"', + ); + } + + void _log(String message) { + print('$_logPrefix $message'); + } +} diff --git a/packages/devtools_extensions/pubspec.yaml b/packages/devtools_extensions/pubspec.yaml index 85d4fc634b7..db3e20b5793 100644 --- a/packages/devtools_extensions/pubspec.yaml +++ b/packages/devtools_extensions/pubspec.yaml @@ -8,10 +8,13 @@ environment: flutter: '>=3.0.0' dependencies: + args: ^2.4.2 devtools_shared: ^3.0.0 devtools_app_shared: ^0.0.1-dev.0 flutter: sdk: flutter + io: ^1.0.4 + path: ^1.8.0 logging: ^1.1.1 vm_service: ">=10.1.0 <12.0.0" From 0f0c8912a0abf460afb9a66bfc419d065dcba009 Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 10:54:57 -0700 Subject: [PATCH 2/7] changelog --- packages/devtools_extensions/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/devtools_extensions/CHANGELOG.md b/packages/devtools_extensions/CHANGELOG.md index 8cab6f6d469..24d4b8d8dfb 100644 --- a/packages/devtools_extensions/CHANGELOG.md +++ b/packages/devtools_extensions/CHANGELOG.md @@ -1,5 +1,7 @@ ## 0.0.3-wip * Add a simulated DevTools environment that for easier development. +* Add a `build_and_copy` command to build a devtools extension and copy the output to the +parent package's extension/devtools directory. ## 0.0.2-dev.0 From f028b58b170daee4fbf628b1dfd23d3b0dab7b05 Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 10:58:10 -0700 Subject: [PATCH 3/7] move file out of lib --- .../command/build_extension.dart => bin/_build_and_copy.dart} | 0 packages/devtools_extensions/bin/devtools_extensions.dart | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/devtools_extensions/{lib/src/command/build_extension.dart => bin/_build_and_copy.dart} (100%) diff --git a/packages/devtools_extensions/lib/src/command/build_extension.dart b/packages/devtools_extensions/bin/_build_and_copy.dart similarity index 100% rename from packages/devtools_extensions/lib/src/command/build_extension.dart rename to packages/devtools_extensions/bin/_build_and_copy.dart diff --git a/packages/devtools_extensions/bin/devtools_extensions.dart b/packages/devtools_extensions/bin/devtools_extensions.dart index b97cf885ee9..68516034ec4 100644 --- a/packages/devtools_extensions/bin/devtools_extensions.dart +++ b/packages/devtools_extensions/bin/devtools_extensions.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:args/command_runner.dart'; -import 'package:devtools_extensions/src/command/build_extension.dart'; +import '_build_and_copy.dart'; void main(List arguments) async { final command = BuildExtensionCommand(); From 1df7695be1c3cdc0fe703084366f13f63bf4d7ee Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 12:09:26 -0700 Subject: [PATCH 4/7] review comments --- packages/devtools_extensions/README.md | 8 ++-- .../bin/_build_and_copy.dart | 40 ++++++------------- packages/devtools_extensions/pubspec.yaml | 3 ++ 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/packages/devtools_extensions/README.md b/packages/devtools_extensions/README.md index dddb9a5a627..e18887007dc 100644 --- a/packages/devtools_extensions/README.md +++ b/packages/devtools_extensions/README.md @@ -106,9 +106,9 @@ to interact with DevTools. From anywhere your extension web app, you can access #### Utilize helper packages Use [package:devtools_app_shared](https://pub.dev/packages/devtools_app_shared) for access to -service managers, common widgets, DevTools theming, utilities, and more. See the +service managers, common widgets, DevTools theming, utilities, and more. See [devtools_app_shared/example](https://github.com/flutter/devtools/tree/master/packages/devtools_app_shared/example) -directory for sample usages of the different shared libraries from DevTools. +for sample usages. ### Debug the extension web app @@ -156,8 +156,8 @@ real DevTools environment. Build your flutter web app and copy the built assets Use the `build_extension` command from `package:devtools_extensions` to help with this step. ``` -dart pub global activate devtools_extensions; -dart run devtools_extensions build_and_copy \ +flutter pub global activate devtools_extensions; +flutter pub global run devtools_extensions build_and_copy \ --source=path/to/your_extension_web_app \ --dest=path/to/your_pub_package/extension/devtools ``` diff --git a/packages/devtools_extensions/bin/_build_and_copy.dart b/packages/devtools_extensions/bin/_build_and_copy.dart index 3af1051437b..dd973d904c3 100644 --- a/packages/devtools_extensions/bin/_build_and_copy.dart +++ b/packages/devtools_extensions/bin/_build_and_copy.dart @@ -10,13 +10,13 @@ import 'package:path/path.dart' as path; /// Command that builds a DevTools extension and copies the built output to /// the parent package extension location. -/// +/// /// Example usage: -/// +/// /// dart pub global activate devtools_extensions; /// dart run devtools_extensions build_and_copy \ /// --source=path/to/your_extension_web_app \ -/// --dest=path/to/your_pub_package/extension/devtools +/// --dest=path/to/your_pub_package/extension/devtools class BuildExtensionCommand extends Command { BuildExtensionCommand() { argParser @@ -25,50 +25,36 @@ class BuildExtensionCommand extends Command { help: 'The source location for the extension flutter web app (can be ' 'relative or absolute)', valueHelp: 'path/to/foo/packages/foo_devtools_extension', + mandatory: true, ) ..addOption( 'dest', help: 'The destination location for the extension build output (can be ' 'relative or absolute)', valueHelp: 'path/to/foo/packages/foo/extension/devtools', + mandatory: true, ); } static const _sourceKey = 'source'; static const _destinationKey = 'dest'; - String get _logPrefix => '[$name]'; - @override - final name = 'build_and_copy'; + String get name => 'build_and_copy'; @override - final description = + String get description => 'Command that builds a DevTools extension from source and copies the ' 'built output to the parent package extension location.'; @override Future run() async { - final source = argResults?[_sourceKey]; - final destination = argResults?[_destinationKey]; - if (source == null) { - throw ArgumentError( - 'Missing argument \'$_sourceKey\', which describes the source location ' - 'for the extension flutter web app', - _sourceKey, - ); - } - if (destination == null) { - throw ArgumentError( - 'Missing argument \'$_destinationKey\', which describes the source ' - 'location for the extension flutter web app', - _destinationKey, - ); - } + final source = argResults?[_sourceKey]!; + final destination = argResults?[_destinationKey]!; final processManager = ProcessManager(); - _log('building the extension flutter web app...'); + _log('Building the extension Flutter web app...'); final buildProcess = await processManager.spawn( 'flutter', [ @@ -84,7 +70,7 @@ class BuildExtensionCommand extends Command { ); await buildProcess.exitCode; - _log('setting canvaskit permissions...'); + _log('Setting canvaskit permissions...'); final chmodProcess = await processManager.spawn( 'chmod', ['0755', 'build/web/canvaskit/canvaskit.*'], @@ -133,7 +119,5 @@ class BuildExtensionCommand extends Command { ); } - void _log(String message) { - print('$_logPrefix $message'); - } + void _log(String message) => print('[$name] $message'); } diff --git a/packages/devtools_extensions/pubspec.yaml b/packages/devtools_extensions/pubspec.yaml index db3e20b5793..5e7600d2571 100644 --- a/packages/devtools_extensions/pubspec.yaml +++ b/packages/devtools_extensions/pubspec.yaml @@ -7,6 +7,9 @@ environment: sdk: '>=3.0.0 <4.0.0' flutter: '>=3.0.0' +executables: + devtools_extensions: devtools_extensions + dependencies: args: ^2.4.2 devtools_shared: ^3.0.0 From 38445948f97ec417efbb5924633775ceeb52b448 Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 12:10:41 -0700 Subject: [PATCH 5/7] version --- packages/devtools_extensions/CHANGELOG.md | 2 +- packages/devtools_extensions/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devtools_extensions/CHANGELOG.md b/packages/devtools_extensions/CHANGELOG.md index 24d4b8d8dfb..d33308fa4bd 100644 --- a/packages/devtools_extensions/CHANGELOG.md +++ b/packages/devtools_extensions/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.0.3-wip +## 0.0.3 * Add a simulated DevTools environment that for easier development. * Add a `build_and_copy` command to build a devtools extension and copy the output to the parent package's extension/devtools directory. diff --git a/packages/devtools_extensions/pubspec.yaml b/packages/devtools_extensions/pubspec.yaml index 5e7600d2571..e6134457f52 100644 --- a/packages/devtools_extensions/pubspec.yaml +++ b/packages/devtools_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: devtools_extensions description: A package for building and supporting extensions for Dart DevTools. -version: 0.0.3-wip +version: 0.0.3 repository: https://github.com/flutter/devtools/tree/master/packages/devtools_extensions environment: From 62578a200794706d057ffdfd2a947e09910f5bb9 Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 12:13:30 -0700 Subject: [PATCH 6/7] capitals --- packages/devtools_extensions/bin/_build_and_copy.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/devtools_extensions/bin/_build_and_copy.dart b/packages/devtools_extensions/bin/_build_and_copy.dart index dd973d904c3..aa6de837dc5 100644 --- a/packages/devtools_extensions/bin/_build_and_copy.dart +++ b/packages/devtools_extensions/bin/_build_and_copy.dart @@ -78,7 +78,7 @@ class BuildExtensionCommand extends Command { ); await chmodProcess.exitCode; - _log('copying built output to the extension destination...'); + _log('Copying built output to the extension destination...'); await _copyBuildToDestination(source: source, dest: destination); // Closes stdin for the entire program. @@ -89,13 +89,13 @@ class BuildExtensionCommand extends Command { required String source, required String dest, }) async { - _log('copying the extension config.json file into a temp directory...'); + _log('Copying the extension config.json file into a temp directory...'); final tmp = Directory.current.createTempSync(); final tmpConfigPath = path.join(tmp.path, 'config.json'); final destinationConfigPath = path.join(dest, 'config.json'); File(destinationConfigPath)..copySync(tmpConfigPath); - _log('replacing the existing extension build with the new one...'); + _log('Replacing the existing extension build with the new one...'); final sourceBuildPath = path.join(source, 'build', 'web'); final destinationBuildPath = path.join(dest, 'build'); Directory(destinationBuildPath)..deleteSync(recursive: true); @@ -106,7 +106,7 @@ class BuildExtensionCommand extends Command { ); _log( - 'copying the extension config.json file back to the destination ' + 'Copying the extension config.json file back to the destination ' 'directory...', ); File(tmpConfigPath)..copySync(destinationConfigPath); From 1a47029c9c134a4668c0af51d98c2c87ba5a87f3 Mon Sep 17 00:00:00 2001 From: Kenzie Schmoll Date: Mon, 28 Aug 2023 12:53:01 -0700 Subject: [PATCH 7/7] fix instructions --- packages/devtools_extensions/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/devtools_extensions/README.md b/packages/devtools_extensions/README.md index e18887007dc..6ec3ac81aa8 100644 --- a/packages/devtools_extensions/README.md +++ b/packages/devtools_extensions/README.md @@ -156,8 +156,9 @@ real DevTools environment. Build your flutter web app and copy the built assets Use the `build_extension` command from `package:devtools_extensions` to help with this step. ``` -flutter pub global activate devtools_extensions; -flutter pub global run devtools_extensions build_and_copy \ +cd your_extension_web_app && +flutter pub get && +dart run devtools_extensions build_and_copy \ --source=path/to/your_extension_web_app \ --dest=path/to/your_pub_package/extension/devtools ```