Skip to content

Update builder logic for the Dart Debug Extension #1717

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

Merged
merged 22 commits into from
Aug 19, 2022

Conversation

elliette
Copy link
Contributor

@elliette elliette commented Aug 11, 2022

  • Adds a shell script for building the extension
  • Builds the dart2js-compiled app to build/web_prod directory instead of web (this new directory is gitignored so the generated files will never be committed to github)
  • Builds all dart files, not just background.dart (currently background.dart is the only dart file, but with the Manifest v3 migration there will be more)
  • Copies the Google developer key (from a gitignored extension_key.txt file) into the manifest.json in the /build directory so that it is never accidentally committed
  • For tests that load the debug extension, we first build the extension (because the generated files are no longer checked into github)

@elliette elliette requested a review from annagrin August 11, 2022 23:58
@elliette elliette requested a review from natebosch August 12, 2022 17:29
@elliette
Copy link
Contributor Author

elliette commented Aug 12, 2022

Adding @natebosch for advice on improving builder logic, thanks!

Copy link
Member

@natebosch natebosch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Builder implementation looks good - using the known 1:1 correlation between the input and output defined in buildExtensions looks like a nice way to handle this.

final allowedOutputs = buildStep.allowedOutputs;

if (allowedOutputs.isEmpty) {
print('Skipping ${inputAsset.path} which has no output options.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these temporary? I think we typically expect builders to be silent unless there is a user actionable problem.

Have you hit these lines in practice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't hit them in practice! Removed

Comment on lines 37 to 38
if (outputAsset.path.endsWith('.png')) {
_copyBinaryFile(buildStep,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be safe to copy all files as bytes and that will simplify things a bit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, that works!

> *At this point, you should manually verify that everything is working by following the steps in [Local Development](#local-development).*
1. Update the version in `web/manifest_prod.json`, `pubspec.yaml`, and in the `CHANGELOG`.
2. Follow the instructions above to build the dart2js-compiled release version of the extension.
> *At this point, you should manually verify that everything is working by following the steps in [Local Development](#local-development), except load the extension from the `build/web_prod` directory. You will need to add a manifest developer key to the `manifest.json` in the `build/web_prod` directory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] reflow to 80 columns. There is an internal formatter if you'd like to use it, but you'd probably want to first format the entire file in a separate commit. go/mdformat

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

shift;;
esac

# Clean existing build directory to avoid merge conflicts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often did you find this was necessary? We don't expect a clean to be necessary for every build in typical workflows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, solved the problem with --delete-conflicting-outputs flag. Was trying to prevent the prompt about conflicts from showing up when running the continuous integration tests

class _CopyBuilder extends Builder {
@override
Map<String, List<String>> get buildExtensions => {
_backgroundJsId.path: [_backgroundJsCopyId.path]
"web/{{}}.dart.js": ["build/web_prod/{{}}.js"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that you are outputting into <package root>/build here, but that also you run the build with -o build?

Do you get a mix of "to source" written output, and then the merged output all in the same directory?

Would it work to change this builder to be to-cache instead of to-source, and make the directory move into a subdirectory of web/?

Suggested change
"web/{{}}.dart.js": ["build/web_prod/{{}}.js"],
"web/{{}}.dart.js": ["web/web_prod/{{}}.js"],

I think that should result in the -o build copying these files into where you expect them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thank you! Updated so now:

  • building with DDC builds to a dev_build directory
  • building with dart2js builds to the build directory, but then copies just the build/web directory over to prod_build

final process = await Process.run('tool/build_extension.sh', ['prod'],
runInShell: true);
print(process.stdout);
Directory.current = currentDir;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wrap the building code in a try/finally and put the Directory.current = currentDir; in a finally block so the directory is restored on exceptions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, done!

return;
}
try {
Directory.current = '$currentDir/debug_extension';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work on windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to test this because I don't have a Windows machine. I tried re-enabling the tests for this change, and at head:

For both, the failure is coming from the fact that the client is null, so it doesn't even get here.

The debug extension tests have been disabled on Windows for 3 years. When we re-enable them, I'm guessing there are quite a few things we will need to change to get them to work.

Copy link
Contributor

@annagrin annagrin Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client is null probably due to some race during retry, I presume the actual failure is different and we don't see it in the test output - the tests are failing originally right after the build has succeeded. As for disabled tests - yeah it looks like an omission - probably disabled in the beginning when the windows tests were set up and we never came back to it. Do we have users of the extension on windows machines? If not, we could make the feature not supported on windows (with an error if someone tries). I think flutter allows to use the extension with the flutter run -d web-server but I might be wrong:)

If we are making changes to the extension build and I suppose subsequent changes to the extension, it would be great to understand what we are missing and have a plan - for example, how do we test extension changes until the tests start working? I presume we would need to run tests manually on a windows machine every time a change to the extension is made.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grouma do you know what was the problem with running the extension tests on windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for context, it looks like we have never tested the extension on Windows (if I understand this correctly): #712

It looks like since adding Windows-test support, the debug extension test has been disabled.

runInShell: true);
print(process.stdout);
} catch (e) {
_logger.warning('Error building Debug Extension: $e');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is swallowing the exception and continuing what we would want to do in that case? Or do we want to rethrow at this point so the test fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, rethrowing the exception

final capabilities = Capabilities.chrome
..addAll({
Capabilities.chromeOptions: {
'args': [
'remote-debugging-port=$debugPort',
if (enableDebugExtension) '--load-extension=debug_extension/web',
if (enableDebugExtension)
'--load-extension=debug_extension/prod_build',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work on windows as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment, we don't get here due to other failures on Windows

'Expected to be in /dwds directory, instead path was $currentDir.');
}
try {
Directory.current = '$currentDir/debug_extension';
Copy link
Contributor

@annagrin annagrin Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted offline about running the build runner directly, so the extension build works on windows as well (potentially, after we fix the tests)

One more thing I realized - we might not need to change the current directory (which is prone to races, especially on retries), but just run the build runner process with the working directory parameter set to the right directory. Would this work?

Copy link
Contributor Author

@elliette elliette Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it does not work, looks like only top-level directories are permitted as args to build_runner build:
Only top level directories such as 'web' or 'test' are allowed as positional args, but got 'debug_extension/web'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants