Add plugin version to SwiftPM package symlink directory#183668
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses a SwiftPM caching issue by including the plugin version in the symlink directory name, forcing Xcode to re-cache the manifest when the version changes. It also refactors how plugins are accessed by caching the list of plugins within the XcodeBasedProject to avoid repeated lookups.
| class FakePlugin extends Fake implements Plugin { | ||
| FakePlugin({required this.name, this.platforms = const <String, PluginPlatform>{}}); | ||
|
|
||
| @override | ||
| final String name; | ||
|
|
||
| @override | ||
| final Map<String, PluginPlatform> platforms; | ||
|
|
||
| @override | ||
| String? pluginSwiftPackageManifestPath(FileSystem fileSystem, String platform) { | ||
| return 'path/to/$name/$platform/$name/Package.swift'; | ||
| } | ||
|
|
||
| @override | ||
| String? pluginPodspecPath(FileSystem fileSystem, String platform) { | ||
| return 'path/to/$name/$platform/$name.podspec'; | ||
| } | ||
| } |
There was a problem hiding this comment.
There's some duplication of test fakes. The FakePlugin class is also defined in packages/flutter_tools/test/general.shard/macos/swift_package_manager_test.dart and packages/flutter_tools/test/general.shard/migrations/swift_package_manager_integration_migration_test.dart.
To improve maintainability and reduce code duplication, consider creating a single, more configurable FakePlugin in a shared test utility file, like packages/flutter_tools/test/src/fakes.dart. This shared fake could be made flexible enough to accommodate the different needs of these tests, for example by allowing customization of its path, supported platforms, and whether it has a Swift package.
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Hm, this will break the way I had planned to do cross-plugin referencing in https://github.com/googleads/googleads-mobile-flutter/pull/1395/changes#diff-1298932cb35428e06f9cc2a3af652bb7124a352b9d74a42adfefb6d7633ae080R17, and it'll break anyone who has already done that. Not necessarily a deal-breaker since the directory layout isn't a formal API, but it is a risk. And more importantly, we'll need a way to handle that use case that we can recommend instead.
🤦♀️ I forgot about that and integration tests wouldn't have caught it because they use local path. Thank goodness for @stuartmorgan-g |
Is this comment resolved, or was there a discussion that I didn't see? What is the solution? It'd be helpful to provide some context here. |
stuartmorgan-g
left a comment
There was a problem hiding this comment.
LGTM with minor comments.
There was offline discussion; the resolution is that if a plugin has this pattern, There is some risk of unexpected edge-case breakage due to this, since it will be a black-magic step from the plugin developer's perspective, but:
|
stuartmorgan-g
left a comment
There was a problem hiding this comment.
I appear to have pressed the wrong button with that review.
|
auto label is removed for flutter/flutter/183668, Failed to enqueue flutter/flutter/183668 with HTTP 400: GraphQL mutate failed. |
flutter/flutter@0f401ee...7245c3f 2026-04-03 [email protected] Roll Skia from c07c67045b6d to 5d847ba5c4aa (1 revision) (flutter/flutter#184570) 2026-04-03 [email protected] Roll Dart SDK from 3c7a79045b8b to 46f49142acd9 (1 revision) (flutter/flutter#184567) 2026-04-03 [email protected] Roll ICU from ee5f27adc28b to ff7995a708a1 (5 revisions) (flutter/flutter#184566) 2026-04-03 [email protected] Roll Skia from 9ae8231be181 to c07c67045b6d (4 revisions) (flutter/flutter#184562) 2026-04-03 [email protected] Roll Fuchsia Linux SDK from BFLjk6Uwd0gs_Hkdk... to PpL3Bn2YMb2h9LbdK... (flutter/flutter#184556) 2026-04-03 [email protected] Roll Skia from 0566b2f5f0d1 to 9ae8231be181 (1 revision) (flutter/flutter#184547) 2026-04-03 [email protected] Roll Dart SDK from 6008eaddd589 to 3c7a79045b8b (3 revisions) (flutter/flutter#184551) 2026-04-03 [email protected] Fix wide gamut macos integration test (flutter/flutter#184427) 2026-04-02 [email protected] forward an application name to DDS (flutter/flutter#184459) 2026-04-02 [email protected] Roll Skia from 973117cfa875 to 0566b2f5f0d1 (8 revisions) (flutter/flutter#184534) 2026-04-02 [email protected] Support different joins for stroked rects in uber_sdf, fix incorrect aa (flutter/flutter#184395) 2026-04-02 [email protected] [ Widget Preview ] Handle collections and records in custom preview annotations (flutter/flutter#184518) 2026-04-02 [email protected] Moves android_semantics_integration_test out of staging (flutter/flutter#184079) 2026-04-02 [email protected] Roll Packages from b3fcf14 to 66bf7ec (4 revisions) (flutter/flutter#184514) 2026-04-02 [email protected] Fix line breaks being lost when copying after selection gesture in SelectableRegion (flutter/flutter#184421) 2026-04-02 [email protected] Add plugin version to SwiftPM package symlink directory (flutter/flutter#183668) 2026-04-02 [email protected] Add our own wrapper for `CommonExtension` due to change in signature from 8.x->9.0 (flutter/flutter#184433) 2026-04-02 [email protected] [Android] Use EdgeToEdge.enable/WindowCompat for edge-to-edge mode instead of deprecated View flags (flutter/flutter#183072) 2026-04-02 [email protected] [data_assets] Cleanup tests (flutter/flutter#184209) 2026-04-02 [email protected] Enable SPM by default on Stable (flutter/flutter#184495) 2026-04-02 [email protected] Roll Dart SDK from d84bdfeb45eb to 6008eaddd589 (2 revisions) (flutter/flutter#184513) 2026-04-02 [email protected] Reland "Even more awaits" (flutter/flutter#184467) 2026-04-02 [email protected] Roll Skia from bb9fd8653739 to 973117cfa875 (2 revisions) (flutter/flutter#184498) 2026-04-02 [email protected] [ Widget Preview ] Use analysis server for widget preview detection (flutter/flutter#184473) 2026-04-02 [email protected] [web_ui] Fix avoid_type_to_string lint violation (flutter/flutter#184342) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: 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
SwiftPM caches package's Package.swift manifest in `$HOME/Library/Caches/org.swift.swiftpm/manifests`. Due to this caching, when pub changes versions, SwiftPM doesn't always detect the Package.manifest has changed. This PR changes the symlink directory to use the plugin's directory basename, which has the version in it: ```diff - .packages/plugin_a -> /$HOME/.pub-cache/hosted/pub.dev/plugin_a-1.0.0/ios/plugin_a + .packages/plugin_a-1.0.0 -> /$HOME/.pub-cache/hosted/pub.dev/plugin_a-1.0.0/ios/plugin_a ``` This forces Xcode to re-cache the manifest. This also refactors a few places we fetch plugins by saving them to the project rather than re-finding them each time. This is currently limited to the `XcodeBasedProject`. Fixes flutter#182099 Fixes flutter#183226 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
SwiftPM caches package's Package.swift manifest in
$HOME/Library/Caches/org.swift.swiftpm/manifests. Due to this caching, when pub changes versions, SwiftPM doesn't always detect the Package.manifest has changed.This PR changes the symlink directory to use the plugin's directory basename, which has the version in it:
This forces Xcode to re-cache the manifest.
This also refactors a few places we fetch plugins by saving them to the project rather than re-finding them each time. This is currently limited to the
XcodeBasedProject.Fixes #182099
Fixes #183226
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.