diff --git a/packages/devtools_extensions/CHANGELOG.md b/packages/devtools_extensions/CHANGELOG.md index 8cab6f6d469..d33308fa4bd 100644 --- a/packages/devtools_extensions/CHANGELOG.md +++ b/packages/devtools_extensions/CHANGELOG.md @@ -1,5 +1,7 @@ -## 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. ## 0.0.2-dev.0 diff --git a/packages/devtools_extensions/README.md b/packages/devtools_extensions/README.md index a3df253cc80..6ec3ac81aa8 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 +[devtools_app_shared/example](https://github.com/flutter/devtools/tree/master/packages/devtools_app_shared/example) +for sample usages. ### Debug the extension web app @@ -154,7 +154,14 @@ 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. +``` +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 +``` 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 +169,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/_build_and_copy.dart b/packages/devtools_extensions/bin/_build_and_copy.dart new file mode 100644 index 00000000000..aa6de837dc5 --- /dev/null +++ b/packages/devtools_extensions/bin/_build_and_copy.dart @@ -0,0 +1,123 @@ +// 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', + 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'; + + @override + String get name => 'build_and_copy'; + + @override + 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]!; + + 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('[$name] $message'); +} diff --git a/packages/devtools_extensions/bin/devtools_extensions.dart b/packages/devtools_extensions/bin/devtools_extensions.dart new file mode 100644 index 00000000000..68516034ec4 --- /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 '_build_and_copy.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/pubspec.yaml b/packages/devtools_extensions/pubspec.yaml index 85d4fc634b7..e6134457f52 100644 --- a/packages/devtools_extensions/pubspec.yaml +++ b/packages/devtools_extensions/pubspec.yaml @@ -1,17 +1,23 @@ 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: 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 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"