Repository navigation
[vector_graphics_compiler] Resolve Flutter artifact cache via package:cli_util - #13252
Conversation
…:cli_util Use package:cli_util to locate the Flutter artifact cache when running as a standalone AOT executable (e.g. via dart install or dart run vector_graphics_compiler@).
There was a problem hiding this comment.
Code Review
This pull request refactors the Flutter artifact cache resolution in vector_graphics_compiler by introducing a centralized resolveFlutterCacheRoot function that utilizes package:cli_util to support standalone AOT-compiled executables. Feedback on the changes suggests improving the robustness of the executable name check using p.basenameWithoutExtension to avoid false positives, adding a corresponding test case, and updating the error messages in the initialization files to accurately reflect when the cache root cannot be located.
| if (executable.contains('flutter_tester')) { | ||
| return File(executable).parent.parent.parent.parent; | ||
| } |
There was a problem hiding this comment.
Using executable.contains('flutter_tester') can lead to false positives if the path to a standalone AOT binary happens to contain the string 'flutter_tester' as a directory name (e.g., /path/to/flutter_tester_project/bin/vector_graphics_compiler).\n\nTo make this check more robust, we should verify that the executable's name (excluding extension) is exactly 'flutter_tester' using p.basenameWithoutExtension.
| if (executable.contains('flutter_tester')) { | |
| return File(executable).parent.parent.parent.parent; | |
| } | |
| if (p.basenameWithoutExtension(executable) == 'flutter_tester') { | |
| return File(executable).parent.parent.parent.parent; | |
| } |
There was a problem hiding this comment.
That suggestion seems reasonable.
There was a problem hiding this comment.
Done — switched to p.basenameWithoutExtension(executable) == 'flutter_tester' and added unit tests in test/engine_artifact_test.dart.
| test('resolves from flutter_tester executable', () { | ||
| final String testerExe = p.join( | ||
| cacheDir.path, | ||
| 'artifacts', | ||
| 'engine', | ||
| 'linux-x64', | ||
| 'flutter_tester', | ||
| ); | ||
| final Directory? resolved = resolveFlutterCacheRoot(resolvedExecutable: testerExe); | ||
| expect(resolved?.path, cacheDir.path); | ||
| }); |
There was a problem hiding this comment.
Add a test case to verify that an executable path containing 'flutter_tester' as a directory name (but not as the executable name itself) is not incorrectly resolved as the flutter_tester executable.
test('resolves from flutter_tester executable', () {
final String testerExe = p.join(
cacheDir.path,
'artifacts',
'engine',
'linux-x64',
'flutter_tester',
);
final Directory? resolved = resolveFlutterCacheRoot(resolvedExecutable: testerExe);
expect(resolved?.path, cacheDir.path);
});
test('does not resolve from executable containing flutter_tester in path but not as name', () {
final String nonTesterExe = p.join(
tempDir.path,
'flutter_tester_project',
'bin',
'vector_graphics_compiler',
);
final Directory? resolved = resolveFlutterCacheRoot(resolvedExecutable: nonTesterExe);
expect(resolved, isNull);
});| if (cacheRoot == null) { | ||
| print('Unknown executable: ${Platform.resolvedExecutable}'); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
The error message 'Unknown executable: ...' is misleading when resolveFlutterCacheRoot() returns null. This can happen when running as a standalone AOT binary and the Flutter SDK/cache cannot be located, even though the executable itself is known.\n\nConsider updating the message to accurately reflect that the Flutter artifact cache could not be located.
| if (cacheRoot == null) { | |
| print('Unknown executable: ${Platform.resolvedExecutable}'); | |
| return false; | |
| } | |
| if (cacheRoot == null) { | |
| print('Could not locate Flutter artifact cache. Executable: ${Platform.resolvedExecutable}'); | |
| return false; | |
| } |
| if (cacheRoot == null) { | ||
| print('Unknown executable: ${Platform.resolvedExecutable}'); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
The error message 'Unknown executable: ...' is misleading when resolveFlutterCacheRoot() returns null. This can happen when running as a standalone AOT binary and the Flutter SDK/cache cannot be located, even though the executable itself is known.\n\nConsider updating the message to accurately reflect that the Flutter artifact cache could not be located.
| if (cacheRoot == null) { | |
| print('Unknown executable: ${Platform.resolvedExecutable}'); | |
| return false; | |
| } | |
| if (cacheRoot == null) { | |
| print('Could not locate Flutter artifact cache. Executable: ${Platform.resolvedExecutable}'); | |
| return false; | |
| } |
|
@flar can you please give this a look? |
…r-graphics-compiler-aot # Conflicts: # packages/vector_graphics_compiler/CHANGELOG.md # packages/vector_graphics_compiler/pubspec.yaml
flar
left a comment
There was a problem hiding this comment.
LGTM, but a safety nit to consider.
| Directory? resolveFlutterCacheRoot({String? resolvedExecutable, String? dartSdkPath}) { | ||
| final String executable = resolvedExecutable ?? Platform.resolvedExecutable; | ||
| if (p.basenameWithoutExtension(executable) == 'flutter_tester') { | ||
| return File(executable).parent.parent.parent.parent; |
There was a problem hiding this comment.
These should be ?. instead of . in case there is a missing parent earlier than the 4th parent. Although, would it be better to pass through to the next option if these 4 consecutive parent calls fail?
…r#196296) flutter/packages@565c657...08faf64 2026-11-10 [email protected] [pigeon] Pass data classes and collections in a single buffer per native interop call (flutter/packages#13265) 2026-11-10 [email protected] [ci] Fix release workflows (flutter/packages#13611) 2026-11-09 [email protected] [pigeon] Fix standalone Native Interop @FlutterApi issues (flutter/packages#13609) 2026-11-09 [email protected] [cross_file_web] Adds support to instantiate the web PlatformXFile without needing to import web apis (flutter/packages#13395) 2026-11-09 [email protected] Sync release-go_router-18.1.4 to main (flutter/packages#13606) 2026-11-09 [email protected] Sync release-material_ui-1.11.0 to main (flutter/packages#13605) 2026-11-09 [email protected] [vector_graphics_compiler] Resolve Flutter artifact cache via package:cli_util (flutter/packages#13252) 2026-11-09 [email protected] [ci] Remove `pull_request_target` workflows (flutter/packages#13581) 2026-11-09 [email protected] Roll Flutter from acade0f to d463821 (1 revision) (flutter/packages#13601) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Resolves the Flutter artifact cache directory (
<flutter>/bin/cache) viapackage:cli_util'ssdkPathwhenPlatform.resolvedExecutableis notflutter_tester.When
vector_graphics_compileris compiled to a standalone AOT executable (for example viadart install vector_graphics_compilerordart run vector_graphics_compiler@),Platform.resolvedExecutableis thevector_graphics_compilerbinary itself rather than<flutter>/bin/cache/dart-sdk/bin/dart, which previously preventedinitializePathOpsFromFlutterCacheandinitializeTessellatorFromFlutterCachefrom finding the engine dynamic libraries.Part of dart-lang/sdk#63210
Pre-Review Checklist
[shared_preferences]///).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2