8000 [path_provider] path provider linux implementation in dart by TimWhiting · Pull Request #2589 · flutter/plugins · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[path_provider] path provider linux implementation in dart #2589

Merged
merged 38 commits into from
May 21, 2020

Conversation

TimWhiting
Copy link
Contributor

Description

This PR contributes a Linux implementation of the path provider plugin. It is a work in progress, since it seems that pure dart implementations aren't automatically detected / registered. (Flutter generates a makefile that expects a C++ class / header file).

Related Issues

flutter/flutter#41716 would be resolved by this PR
google/flutter-desktop-embedding PR #674 contains discussion related / leading to this implementation
flutter/packages PR #117 contains work leading up to this

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • [] I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@TimWhiting
Copy link
Contributor Author
TimWhiting commented Mar 8, 2020

@stuartmorgan

Here is the dart implementation of path_provider for Linux we discussed. I'm having trouble figuring out how to get the example app to run. It seems that currently there is a lack of support for automatically registering pure dart plugins for platforms other than web. Can you confirm or point me in the right direction? Currently the Makefile expects there to be a C++ header file by the name of path_provider_linux.h.

@TimWhiting
Copy link
Contributor Author
TimWhiting commented Mar 8, 2020

I took a look at the place where the plugin registry is built:
here
as well as the web plugin registrar: here

My proposal would be to:

  1. Rename the flutter_web_plugins package to flutter_dart_plugins,
  2. Have a language key/value in the yaml map in the pubspec that specifies if you are using dart to implement the plugin. (Defaults to dart for web). Then use that to generate the dart plugin registrar.
  3. Provide some documentation that you can use dart to implement a plugin on desktop, just like you can on web, but you have to specify dart for the language parameter in the pubspec

By adding this language parameter this we could eventually allow using ffi (through dart parameter in pubspec), C# for windows, etc...

@stuartmorgan-g
Copy link
Contributor

It seems that currently there is a lack of support for automatically registering pure dart plugins for platforms other than web. Can you confirm or point me in the right direction?

Yes, unfortunately that's the case; a couple of us were looking at that a bit at the end of last week and discovered that the planned solution hasn't actually been implemented yet.

  1. Rename the flutter_web_plugins package to flutter_dart_plugins,

We shouldn't need that; the goal is to implement the platform interface, bypassing platform messages entirely. That's one of the things the new platform interface abstraction was designed to address.

  1. Have a language key/value in the yaml map in the pubspec that specifies if you are using dart to implement the plugin. (Defaults to dart for web). Then use that to generate the dart plugin registrar.

The existing plan for allowing Dart registration on any platform is described here. There's no plan to add something as generic as "language" for all plugin platforms as the potential for confusion is high.

The complexity is not in generating the Dart plugin registrar, but in finding a way to invoke it in a way that doesn't have problematic edge cases. It's something that will need more investigation and discussion in the coming weeks.

By adding this language parameter this we could eventually allow using ffi (through dart parameter in pubspec), C# for windows, etc...

In general, we want to be extremely thoughtful about when/how we add native language options for plugins; allowing lots of choice at that layer is not necessarily a feature.

@TimWhiting
Copy link
Contributor Author

@stuartmorgan Thanks for pointing me to that document. I haven't forgotten this plugin.

Is there an issue I can follow to know when the flutter_tools support of dart plugins for non-web clients is available?

@stuartmorgan-g
Copy link
Contributor

flutter/flutter#52267 is tracking dartPluginClass plumbing. However, based on recent discussions I think while we're waiting for that we can do manual registration in the front-end plugin. So we would have path_provider endorse path_provider_linux, and then for Platform.isLinux path_provider would set PathProviderPlatform.instance to the Linux Dart implementation.

@stuartmorgan-g
Copy link
Contributor

@TimWhiting I'm going to be working on setting up the testing infrastructure for Linux (which is a blocker for landing Linux plugins) next week; if you're interested in updating this PR we can use it to continue blazing the trail of landing an FFI-based Linux plugin.

I think it's pretty close, the main things are to add the registration to the front-end package (to work around the lack of support for automatic registration), and removing the linux/ directories from the example apps. See #2631, which is the first attempt to do this same thing for Windows, for an example and relevant discussion.

@TimWhiting
Copy link
Contributor Author

Okay, I'll look into it tomorrow, thanks!

@TimWhiting TimWhiting force-pushed the path_provider_linux branch from 1b872e5 to 63e41ef Compare April 25, 2020 18:59
@stuartmorgan-g
Copy link
Contributor

get rid of android and ios plugin stubs

The podspec stub is still required for iOS. I believe some kind of Android stub is still required on stable as well for the moment.

@TimWhiting
Copy link
Contributor Author

get rid of android and ios plugin stubs

The podspec stub is still required for iOS. I believe some kind of Android stub is still required on stable as well for the moment.

Okay, I'll revert that last commit

@stuartmorgan-g
Copy link
Contributor

On the testing infrastructure front, the plugin_tools support is in, and once #2717 lands we should be able to merge master into this PR and see it run e2e tests on this plugin 🤞

Copy link
Contributor
@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

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

The CI support has landed, so you can merge master into this now.

The Android test failures look real; it seems like there's an issue with your Android stub.

@stuartmorgan-g
Copy link
Contributor

The lint errors look like there is a tighter set of requirements being enforced on new/changed packages. https://github.com/flutter/plugins/blob/master/packages/google_maps_flutter/google_maps_flutter/ios/google_maps_flutter.podspec looks like one that's recent enough to address the things flagged by the linter.

@TimWhiting TimWhiting changed the title [path_provider] WIP path provider linux implementation in dart [path_provider] path provider linux implementation in dart May 20, 2020
@stuartmorgan-g
Copy link
Contributor
CMake Error at /usr/share/cmake-3.10/Modules/BundleUtilities.cmake:966 (message):
  error: fixup_bundle: not a valid bundle

I'm not sure what's going on there; my local 3.10 test didn't have that issue. I'll need to try to figure out how to get verbose build output enabled for a bot run (which will be tricky since the tools that drive the build are from a published package).

@stuartmorgan-g
Copy link
Contributor

I'm not sure what's going on there

#2774

@stuartmorgan-g
Copy link
Contributor

Fix landed; if you merge in master, I think there's a good chance this will finally be green across the board! 🤞

@TimWhiting
Copy link
Contributor Author

@stuartmorgan

It looks like a lot of plugins are now removing the no-op android folders. Should I do the same here?
flutter/flutter#46304

@stuartmorgan-g
Copy link
Contributor

It looks like a lot of plugins are now removing the no-op android folders. Should I do the same here?]

Yes, I hadn't followed which release that bug was waiting on, but apparently it was 1.17. No need to land 9E88 the Android no-op if it's no longer needed.

@TimWhiting
Copy link
Contributor Author

@stuartmorgan
Is this ready to merge now?

@stuartmorgan-g
Copy link
Contributor

I was planning on landing and publishing it this morning. I was just doing a final once-over and noticed that path_provider_linux/README.md is still just the placeholder. Can you update it with an actual README? See path_provider_macos/README.md for an example of a federated plugin readme.

… as well as the notification that path_provider 1.0.0 is coming, with instructions on how to set dependencies to allow for an upgrade to 1.0.0
@TimWhiting
Copy link
Contributor Author

@stuartmorgan
Sorry about that, I thought I had done that earlier. Just made the update to the README.md and merged in the latest master.

@stuartmorgan-g
Copy link
Contributor

The readme is somewhat misleading since there is a step other than adding it to your pubspec, but since we should be doing the follow-up to endorse it shortly I'll land it as-is.

@stuartmorgan-g stuartmorgan-g merged commit def1025 into flutter:master May 21, 2020
@stuartmorgan-g
Copy link
Contributor

https://pub.dev/packages/path_provider_linux 🎉

Congratulations on getting the first Linux flutter/plugins plugin, and the first pure-Dart desktop plugin, landed and published 🙂 Thanks again for bearing with all the difficulties of blazing this trail.

You should be able to do the endorsement PR now, which I expect to go much more smoothly.

@TimWhiting TimWhiting deleted the path_provider_linux branch June 3, 2020 17:59
@apgapg
Copy link
apgapg commented Jun 4, 2020

@TimWhiting In unit test(s) getApplicationDocumentsDirectory generally fails due to MissingPuginException but when running flutter test in Linux environment, the test doesn't fail, because in linux path_provider doesnt call method channel instead use xdg lib directly.

Am i clear in my understanding?

I then have to mock method channel sometimes. See https://stackoverflow.com/questions/56158676/why-applicationsdocumentsdirectory-return-null-for-unit-test

@TimWhiting
Copy link
Contributor Author
TimWhiting commented Jun 4, 2020

@apgapg
I guess I'm not understanding the question.
At one point you say that it fails in unit tests, and then you say that it doesn't fail in flutter test. Shouldn't you be using flutter test for all of your unit tests? What exactly is failing & what environment / setup, do you have a simple reproducible example?

You are correct that path_provider_linux does not use a method channel.
However, now you should be able to use path_provider regularly, and not import the linux package separately. The plugin has been endorsed. If you want to see how to set your own PathProviderPlatform for overriding during tests, see path_provider ^1.6.10's documentation about this new setter: disablePathProviderPlatformOverride. (It will disable the registering of path_provider_linux, and use the method channel instead. (Which you can then mock like your example). However, the preferred way of mocking federated plugins like this one is to register a MockPathProviderPlatform that conforms to the PathProviderPlatform interface. See the documentation in this package

Or see the discussion on this pull request about disablePathProviderPlatformOverride:
#2789

@apgapg
Copy link
apgapg commented Jun 4, 2020

@TimWhiting for first question:
I was trying flutter test on my mac air. Here all test related to path_provider failed as it was throwing MissingPlatformException.

But when i run the same command in my CI/CD on github action where the
build: runs-on: ubuntu-latest

test run on ubuntu, they all passed.

So the flutter test in my case is behaving differently on different platforms.

For second para:
Yes i am now using path_provider only. Thanks for clarification

@hpoul
Copy link
Contributor
hpoul commented Jun 4, 2020

@apgapg i'm not sure you are testing what you think you are testing.. but you probably want to just mock plugins in unit tests anyway, mocking path_provider method channel is actually an example on the flutter test page: https://flutter.dev/docs/cookbook/persistence/reading-writing-files#testing

@TimWhiting
Copy link
Contributor Author
TimWhiting commented Jun 4, 2020

@apgapg
Was flutter test on your mac working before? I'm guessing it was.

The macos plugin uses method channels so it needs to be mocked in the same way as your link you wrote about earlier. (Unless you mock the PathProviderPlatform, like I mentioned).

What is it that you are trying to test? Tests for path_provider pass, so you shouldn't be testing path_provider.
You should probably be mocking PathProviderPlatform to get a consistent result across platforms.

Also make sure you remove any manual registration of the Linux implementation of PathProviderPlatform, if you were doing that.

@apgapg
Copy link
apgapg commented Jun 4, 2020

@TimWhiting @hpoul Yes its my ignorance about testing code. I didn't mock path_provider and just messing around with nothing.

Thanks both of you for clarifying and helping me to learn it in more better way.
Thanks again

UPDATE 1:
I now understand the whole scenario. disablePathProviderPlatformOverride is to disable the override in linux and use method channel which then can be mocked with anything.

  1. Using MockPathProviderPlatform is recommended in case of Unit testing.
  2. Mocking method channel is what required in integration testing

@TimWhiting TimWhiting mentioned this pull request Jun 4, 2020
13 tasks
EdwinRomelta pushed a commit to EdwinRomelta/plugins that referenced this pull request Jun 11, 2020
)

Adds a pure-Dart path_provider_linux, to use as a federated Linux implementation of path_provider.
jorgefspereira pushed a commit to jorgefspereira/plugins_flutter that referenced this pull request Oct 10, 2020
)

Adds a pure-Dart path_provider_linux, to use as a federated Linux implementation of path_provider.
FlutterSu pushed a commit to FlutterSu/flutter-plugins that referenced this pull request Nov 20, 2020
)

Adds a pure-Dart path_provider_linux, to use as a federated Linux implementation of path_provider.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0