Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[path_provider] Add Windows support #2818

Merged
merged 40 commits into from Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7e018b9
Initial Windows repo
Jun 4, 2020
712c043
Implementation for getTemporaryPath() and getDownloadsPath()
Jun 4, 2020
55429f6
Tidy up Windows plugin implementation
Jun 4, 2020
52d5b0d
Add folder documentation comments.
Jun 5, 2020
aea6a4c
Add Windows runner
Jun 5, 2020
f20a00e
Fix doc comment nit
Jun 5, 2020
1be04d7
Set pubspec version
Jun 5, 2020
306868e
Add manual registration of Windows plug-in
Jun 5, 2020
cd0ea88
Fix bug in pubspec
Jun 6, 2020
0eba356
Tweaks
Jun 6, 2020
06bd98f
Remove windows folder
Jun 7, 2020
383ef8f
Add missing copyright comment
Jun 7, 2020
ad0c2b9
More minor copyright tweaks
Jun 7, 2020
f264046
Add warning
Jun 17, 2020
03a126e
Bump changelog
Jun 17, 2020
5057d47
Wrap pointer allocation in try/free
Sep 4, 2020
9da128b
Merge remote-tracking branch 'upstream/master' into path_provider_win…
Sep 4, 2020
37eba73
path endsWith
Sep 4, 2020
a3a2d41
Trim back comment on TEMP environment variable
Sep 4, 2020
6048f43
Switch to the improved manual Dart registration used in shared_prefer…
stuartmorgan Sep 15, 2020
30ef537
Fix endorsement
stuartmorgan Sep 15, 2020
ca07f04
Version bump for endorsement
stuartmorgan Sep 15, 2020
41c704e
Use newer format license
stuartmorgan Sep 15, 2020
d017a20
Update README for path_provider_windows to have correct path_provider…
stuartmorgan Sep 15, 2020
22afc78
Dependency fixes in example
stuartmorgan Sep 15, 2020
bd11efc
Comment cleanup, remove getLibraryPath, make applitionSupportPath con…
stuartmorgan Sep 15, 2020
3cd2f98
Improve unit test coverage; skip on non-Windows
stuartmorgan Sep 15, 2020
3d49b16
Make example self-contained
stuartmorgan Sep 15, 2020
845074f
Ensure that temp directory exists before returning it
stuartmorgan Sep 15, 2020
a3c2bf2
Dart format
stuartmorgan Sep 15, 2020
676fd02
Use actual executable name
stuartmorgan Sep 15, 2020
cd2f366
Use 0.0.2, since there were code changes
stuartmorgan Sep 16, 2020
7d46f63
Use VERSIONINFO to figure out the appdata subdir
stuartmorgan Sep 17, 2020
80a0b6a
Use TestOn
stuartmorgan Sep 17, 2020
3a3fdb7
Cap directory component length
stuartmorgan Sep 17, 2020
954a8df
Revert "Use TestOn"
stuartmorgan Sep 18, 2020
be299b9
Update the test added after the revert change
stuartmorgan Sep 18, 2020
e826b17
Use a named constant for the language code
stuartmorgan Sep 18, 2020
370f3ce
Make the name more accurate
stuartmorgan Sep 18, 2020
fe6d472
Fix long path handling
stuartmorgan Sep 18, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/path_provider/path_provider/lib/path_provider.dart
Expand Up @@ -7,6 +7,7 @@ import 'dart:io' show Directory, Platform;

import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting;
import 'package:path_provider_linux/path_provider_linux.dart';
import 'package:path_provider_windows/path_provider_windows.dart';
timsneath marked this conversation as resolved.
Show resolved Hide resolved
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';

export 'package:path_provider_platform_interface/path_provider_platform_interface.dart'
Expand Down Expand Up @@ -39,6 +40,8 @@ PathProviderPlatform get _platform {
}
if (!kIsWeb && Platform.isLinux && !_disablePlatformOverride) {
__platform = PathProviderLinux();
} else if (!kIsWeb && Platform.isWindows && !_disablePlatformOverride) {
__platform = PathProviderWindows();
} else {
__platform = PathProviderPlatform.instance;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/path_provider/path_provider/pubspec.yaml
@@ -1,6 +1,5 @@
name: path_provider
description: Flutter plugin for getting commonly used locations on the Android &
iOS file systems, such as the temp and app data directories.
description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories.
homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider
version: 1.6.10

Expand All @@ -23,6 +22,8 @@ dependencies:
path_provider_platform_interface: ^1.0.1
path_provider_macos: ^0.0.4
path_provider_linux: ^0.0.1
path_provider_windows:
path: ../path_provider_windows
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved

dev_dependencies:
e2e: ^0.2.1
Expand Down
3 changes: 3 additions & 0 deletions packages/path_provider/path_provider_windows/.gitignore
@@ -0,0 +1,3 @@
.packages
.flutter-plugins
pubspec.lock
5 changes: 5 additions & 0 deletions packages/path_provider/path_provider_windows/CHANGELOG.md
@@ -0,0 +1,5 @@
## 0.0.1+1

* The initial implementation of path_provider for Windows
* Implements getTemporaryPath, getApplicationSupportPath, getLibraryPath,
getApplicationDocumentsPath and getDownloadsPath.
27 changes: 27 additions & 0 deletions packages/path_provider/path_provider_windows/LICENSE
@@ -0,0 +1,27 @@
Copyright 2017 The Chromium Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 changes: 30 additions & 0 deletions packages/path_provider/path_provider_windows/README.md
@@ -0,0 +1,30 @@
# path_provider_windows

The Windows implementation of [`path_provider`][1].

**Please set your constraint to `path_provider_windows: '>=0.0.y+x <2.0.0'`**

## Backward compatible 1.0.0 version is coming
The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`.
Please use `path_provider_windows: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration.
For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0

## Usage

### Import the package

This package has been endorsed, meaning that you only need to add `path_provider`
as a dependency in your `pubspec.yaml`. It will be automatically included in your app
when you depend on `package:path_provider`.

This is what the above means to your `pubspec.yaml`:

```yaml
...
dependencies:
...
path_provider: ^1.5.1
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
...
```

[1]:../
44 changes: 44 additions & 0 deletions packages/path_provider/path_provider_windows/example/.gitignore
@@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
10 changes: 10 additions & 0 deletions packages/path_provider/path_provider_windows/example/.metadata
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: f2320c3b7a42bc27e7f038212eed1b01f4269641
channel: master

project_type: app
@@ -0,0 +1,8 @@
# path_provider_windows_example
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need a separate sample for Windows? won't the normal path_provider sample do?

Copy link
Contributor

Choose a reason for hiding this comment

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

There's an open question in the longer term about how to best structure the tests and examples for federated plugins. The plugin repo tooling expects them though, and it does have value in the general case:

  • It's a self-contained way to build and test the plugin, which is convenient for plugin development.
  • It can test platform-specific APIs (which we don't currently have, but could in the future).

So long term, TBD, short term, this is the standard practice we've been following.


Demonstrates how to use the path_provider_windows plugin.

## Getting Started

For help getting started with Flutter, view our online
[documentation](http://flutter.io/).
92 changes: 92 additions & 0 deletions packages/path_provider/path_provider_windows/example/lib/main.dart
@@ -0,0 +1,92 @@
// Copyright 2020 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.

// ignore_for_file: public_member_api_docs

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
runApp(MyApp());
}

/// Sample app
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
String _tempDirectory = 'Unknown';
String _downloadsDirectory = 'Unknown';
String _appSupportDirectory = 'Unknown';
String _documentsDirectory = 'Unknown';

@override
void initState() {
super.initState();
initDirectories();
}

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initDirectories() async {
String tempDirectory;
String downloadsDirectory;
String appSupportDirectory;
String documentsDirectory;

try {
tempDirectory = (await getTemporaryDirectory()).path;
} catch (exception) {
tempDirectory = 'Failed to get temp directory: $exception';
}
try {
downloadsDirectory = (await getDownloadsDirectory()).path;
} catch (exception) {
downloadsDirectory = 'Failed to get downloads directory: $exception';
}

try {
documentsDirectory = (await getApplicationDocumentsDirectory()).path;
} catch (exception) {
documentsDirectory = 'Failed to get documents directory: $exception';
}

try {
appSupportDirectory = (await getApplicationSupportDirectory()).path;
} catch (exception) {
appSupportDirectory = 'Failed to get app support directory: $exception';
}

setState(() {
_tempDirectory = tempDirectory;
_downloadsDirectory = downloadsDirectory;
_appSupportDirectory = appSupportDirectory;
_documentsDirectory = documentsDirectory;
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Path Provider example app'),
),
body: Center(
child: Column(
children: [
Text('Temp Directory: $_tempDirectory\n'),
Text('Documents Directory: $_documentsDirectory\n'),
Text('Downloads Directory: $_downloadsDirectory\n'),
Text('Application Support Directory: $_appSupportDirectory\n'),
],
),
),
),
);
}
}
19 changes: 19 additions & 0 deletions packages/path_provider/path_provider_windows/example/pubspec.yaml
@@ -0,0 +1,19 @@
name: path_provider_example
description: Demonstrates how to use the path_provider plugin.

dependencies:
flutter:
sdk: flutter
path_provider: any
path_provider_windows:
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
path: ../

dev_dependencies:
e2e: ^0.2.1
flutter_driver:
sdk: flutter
test: any
pedantic: ^1.8.0

flutter:
uses-material-design: true
@@ -0,0 +1,51 @@
// Copyright 2019, the Chromium project authors. Please see the AUTHORS file
// for details. 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:flutter_test/flutter_test.dart';
import 'package:path_provider/path_provider.dart';
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
import 'package:e2e/e2e.dart';

void main() {
E2EWidgetsFlutterBinding.ensureInitialized();

testWidgets('getTemporaryDirectory', (WidgetTester tester) async {
final Directory result = await getTemporaryDirectory();
_verifySampleFile(result, 'temporaryDirectory');
});

testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async {
final Directory result = await getApplicationDocumentsDirectory();
_verifySampleFile(result, 'applicationDocuments');
});

testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async {
final Directory result = await getApplicationSupportDirectory();
_verifySampleFile(result, 'applicationSupport');
});

testWidgets('getLibraryDirectory', (WidgetTester tester) async {
if (!Platform.isWindows) {
return;
}
final Directory result = await getLibraryDirectory();
_verifySampleFile(result, 'library');
});
}

/// Verify a file called [name] in [directory] by recreating it with test
/// contents when necessary.
void _verifySampleFile(Directory directory, String name) {
final File file = File('${directory.path}${Platform.pathSeparator}$name');

if (file.existsSync()) {
file.deleteSync();
expect(file.existsSync(), isFalse);
}

file.writeAsStringSync('Hello world!');
expect(file.readAsStringSync(), 'Hello world!');
expect(directory.listSync(), isNotEmpty);
file.deleteSync();
}
@@ -0,0 +1,15 @@
// Copyright 2019, the Chromium project authors. Please see the AUTHORS file
// for details. 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:async';
import 'dart:io';
import 'package:flutter_driver/flutter_driver.dart';

Future<void> main() async {
final FlutterDriver driver = await FlutterDriver.connect();
final String result =
await driver.requestData(null, timeout: const Duration(minutes: 1));
await driver.close();
exit(result == 'pass' ? 0 : 1);
}