Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ship a build_and_copy command with the devtools_extensions package #6259

Merged
merged 8 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/devtools_extensions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
18 changes: 13 additions & 5 deletions packages/devtools_extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
directory for sample usages of the different shared libraries from DevTools.

### Debug the extension web app

Expand Down Expand Up @@ -154,15 +154,23 @@ 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;
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
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
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 `<TODO: insert instructions>` 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 >= `<TODO: insert version>`**,
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
Expand Down
139 changes: 139 additions & 0 deletions packages/devtools_extensions/bin/_build_and_copy.dart
Original file line number Diff line number Diff line change
@@ -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(
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
'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';
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved

@override
final description =
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
'Command that builds a DevTools extension from source and copies the '
'built output to the parent package extension location.';

@override
Future<void> run() async {
final source = argResults?[_sourceKey];
final destination = argResults?[_destinationKey];
if (source == null) {
throw ArgumentError(
'Missing argument \'$_sourceKey\', which describes the source location '
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
'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...');
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
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<void> _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');
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
}
}
13 changes: 13 additions & 0 deletions packages/devtools_extensions/bin/devtools_extensions.dart
Original file line number Diff line number Diff line change
@@ -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<String> arguments) async {
final command = BuildExtensionCommand();
final runner = CommandRunner('devtools_extensions', command.description)
..addCommand(BuildExtensionCommand());
await runner.run(arguments);
}
3 changes: 3 additions & 0 deletions packages/devtools_extensions/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
Loading