Visitar URL original
Adds xdg_directories package to access Linux well known director… (#117) · flutter/packages@1c614f6 · GitHub
Skip to content

Commit 1c614f6

Browse files
authored
Adds xdg_directories package to access Linux well known director… (#117)
xdg_directories is a package that allows access to the directory values managed by xdg on Linux systems. It makes it easier to write other packages that need to know where Linux directories like "Documents" and "Desktop" are.
1 parent 2ffb4b7 commit 1c614f6

8 files changed

Lines changed: 494 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
12+
# IntelliJ related
13+
*.iml
14+
*.ipr
15+
*.iws
16+
.idea/
17+
18+
# The .vscode folder contains launch configuration and tasks you configure in
19+
# VS Code which you may wish to be included in version control, so this line
20+
# is commented out by default.
21+
#.vscode/
22+
23+
# Flutter/Dart/Pub related
24+
**/doc/api/
25+
.dart_tool/
26+
.flutter-plugins
27+
.flutter-plugins-dependencies
28+
.packages
29+
.pub-cache/
30+
.pub/
31+
build/
32+
33+
# Android related
34+
**/android/**/gradle-wrapper.jar
35+
**/android/.gradle
36+
**/android/captures/
37+
**/android/gradlew
38+
**/android/gradlew.bat
39+
**/android/local.properties
40+
**/android/**/GeneratedPluginRegistrant.java
41+
42+
# iOS/XCode related
43+
**/ios/**/*.mode1v3
44+
**/ios/**/*.mode2v3
45+
**/ios/**/*.moved-aside
46+
**/ios/**/*.pbxuser
47+
**/ios/**/*.perspectivev3
48+
**/ios/**/*sync/
49+
**/ios/**/.sconsign.dblite
50+
**/ios/**/.tags*
51+
**/ios/**/.vagrant/
52+
**/ios/**/DerivedData/
53+
**/ios/**/Icon?
54+
**/ios/**/Pods/
55+
**/ios/**/.symlinks/
56+
**/ios/**/profile
57+
**/ios/**/xcuserdata
58+
**/ios/.generated/
59+
**/ios/Flutter/App.framework
60+
**/ios/Flutter/Flutter.framework
61+
**/ios/Flutter/Flutter.podspec
62+
**/ios/Flutter/Generated.xcconfig
63+
**/ios/Flutter/app.flx
64+
**/ios/Flutter/app.zip
65+
**/ios/Flutter/flutter_assets/
66+
**/ios/Flutter/flutter_export_environment.sh
67+
**/ios/ServiceDefinitions.json
68+
**/ios/Runner/GeneratedPluginRegistrant.*
69+
70+
# Exceptions to above rules.
71+
!**/ios/**/default.mode1v3
72+
!**/ios/**/default.mode2v3
73+
!**/ios/**/default.pbxuser
74+
!**/ios/**/default.perspectivev3
75+
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

‎packages/xdg_directories/.metadata‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: d8c0deb1b6c116be79ceeca005f893be34ab5df2
8+
channel: master
9+
10+
project_type: package
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## [0.1.0] - Initial Release
2+
3+
* Initial release includes all the features described in the README.md

‎packages/xdg_directories/LICENSE‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright 2020 The Flutter Authors. All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above
10+
copyright notice, this list of conditions and the following
11+
disclaimer in the documentation and/or other materials provided
12+
with the distribution.
13+
* Neither the name of Google Inc. nor the names of its
14+
contributors may be used to endorse or promote products derived
15+
from this software without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

‎packages/xdg_directories/README.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# `xdg_directories`
2+
3+
A Dart package for reading XDG directory configuration information on Linux.
4+
5+
## Getting Started
6+
7+
On Linux, `xdg` is a system developed by [freedesktop.org](freedesktop.org), a
8+
project to work on interoperability and shared base technology for free software
9+
desktop environments for Linux.
10+
11+
This Dart package can be used to determine the directory configuration
12+
information defined by `xdg`, such as where the Documents or Desktop directories
13+
are. These are called "user directories" and are defined in configuration file
14+
in the user's home directory.
15+
16+
See [this wiki](https://wiki.archlinux.org/index.php/XDG_Base_Directory) for
17+
more details of the XDG Base Directory implementation.
18+
19+
To use this package, the basic XDG values for the following are available via a Dart API:
20+
21+
- `dataHome` - The single base directory relative to which user-specific data
22+
files should be written. (Corresponds to `$XDG_DATA_HOME`).
23+
24+
- `configHome` - The a single base directory relative to which user-specific
25+
configuration files should be written. (Corresponds to `$XDG_CONFIG_HOME`).
26+
27+
- `dataDirs` - The list of preference-ordered base directories relative to
28+
which data files should be searched. (Corresponds to `$XDG_DATA_DIRS`).
29+
30+
- `configDirs` - The list of preference-ordered base directories relative to
31+
which configuration files should be searched. (Corresponds to
32+
`$XDG_CONFIG_DIRS`).
33+
34+
- `cacheHome` - The base directory relative to which user-specific
35+
non-essential (cached) data should be written. (Corresponds to
36+
`$XDG_CACHE_HOME`).
37+
38+
- `runtimeDir` - The base directory relative to which user-specific runtime
39+
files and other file objects should be placed. (Corresponds to
40+
`$XDG_RUNTIME_DIR`).
41+
42+
- `getUserDirectoryNames()` - Returns a set of the names of user directories
43+
defined in the `xdg` configuration files.
44+
45+
- `getUserDirectory(String dirName)` - Gets the value of the user dir with the
46+
given name. Requesting a user dir that doesn't exist returns `null`. The
47+
`dirName` argument is case-insensitive. See [this
48+
wiki](https://wiki.archlinux.org/index.php/XDG_user_directories) for more
49+
details and what values of `dirName` might be available.
50+
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2020 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
library xdg_directories;
6+
7+
import 'dart:convert';
8+
import 'dart:io';
9+
10+
import 'package:flutter/cupertino.dart';
11+
import 'package:path/path.dart' as path;
12+
import 'package:process/process.dart';
13+
14+
/// An override function used by the tests to override the environment variable
15+
/// lookups using [xdgEnvironmentOverride].
16+
typedef EnvironmentAccessor = String Function(String envVar);
17+
18+
/// A testing setter that replaces the real environment lookups with an override.
19+
///
20+
/// Set to null to stop overriding.
21+
///
22+
/// Only available to tests.
23+
@visibleForTesting
24+
set xdgEnvironmentOverride(EnvironmentAccessor override) {
25+
_xdgEnvironmentOverride = override;
26+
_getenv = _xdgEnvironmentOverride ?? _productionGetEnv;
27+
}
28+
29+
/// A testing getter that returns the current value of the override that
30+
/// replaces the real environment lookups with an override.
31+
///
32+
/// Only available to tests.
33+
EnvironmentAccessor get xdgEnvironmentOverride => _xdgEnvironmentOverride;
34+
EnvironmentAccessor _xdgEnvironmentOverride;
35+
EnvironmentAccessor _productionGetEnv =
36+
(String value) => Platform.environment[value];
37+
EnvironmentAccessor _getenv = _productionGetEnv;
38+
39+
/// A testing function that replaces the process manager used to run xdg-user-path
40+
/// with the one supplied.
41+
///
42+
/// Only available to tests.
43+
@visibleForTesting
44+
set xdgProcessManager(ProcessManager processManager) {
45+
_processManager = processManager;
46+
}
47+
48+
ProcessManager _processManager = const LocalProcessManager();
49+
50+
List<Directory> _directoryListFromEnvironment(
51+
String envVar, List<Directory> fallback) {
52+
assert(envVar != null);
53+
assert(fallback != null);
54+
final String value = _getenv(envVar);
55+
if (value == null || value.isEmpty) {
56+
return fallback;
57+
}
58+
return value.split(':').where((String value) {
59+
return value.isNotEmpty;
60+
}).map<Directory>((String entry) {
61+
return Directory(entry);
62+
}).toList();
63+
}
64+
65+
Directory _directoryFromEnvironment(String envVar, String fallback) {
66+
assert(envVar != null);
67+
final String value = _getenv(envVar);
68+
if (value == null || value.isEmpty) {
69+
if (fallback == null) {
70+
return null;
71+
}
72+
return _getDirectory(fallback);
73+
}
74+
return Directory(value);
75+
}
76+
77+
// Creates a Directory from a fallback path.
78+
Directory _getDirectory(String subdir) {
79+
assert(subdir != null);
80+
assert(subdir.isNotEmpty);
81+
final String homeDir = _getenv('HOME');
82+
if (homeDir == null || homeDir.isEmpty) {
83+
throw StateError(
84+
'The "HOME" environment variable is not set. This package (and POSIX) '
85+
'requires that HOME be set.');
86+
}
87+
return Directory(path.joinAll(<String>[homeDir, subdir]));
88+
}
89+
90+
/// The base directory relative to which user-specific
91+
/// non-essential (cached) data should be written. (Corresponds to
92+
/// `$XDG_CACHE_HOME`).
93+
///
94+
/// Throws [StateError] if the HOME environment variable is not set.
95+
Directory get cacheHome =>
96+
_directoryFromEnvironment('XDG_CACHE_HOME', '.cache');
97+
98+
/// The list of preference-ordered base directories relative to
99+
/// which configuration files should be searched. (Corresponds to
100+
/// `$XDG_CONFIG_DIRS`).
101+
///
102+
/// Throws [StateError] if the HOME environment variable is not set.
103+
List<Directory> get configDirs {
104+
return _directoryListFromEnvironment(
105+
'XDG_CONFIG_DIRS',
106+
<Directory>[Directory('/etc/xdg')],
107+
);
108+
}
109+
110+
/// The a single base directory relative to which user-specific
111+
/// configuration files should be written. (Corresponds to `$XDG_CONFIG_HOME`).
112+
///
113+
/// Throws [StateError] if the HOME environment variable is not set.
114+
Directory get configHome =>
115+
_directoryFromEnvironment('XDG_CONFIG_HOME', '.config');
116+
117+
/// The list of preference-ordered base directories relative to
118+
/// which data files should be searched. (Corresponds to `$XDG_DATA_DIRS`).
119+
///
120+
/// Throws [StateError] if the HOME environment variable is not set.
121+
List<Directory> get dataDirs {
122+
return _directoryListFromEnvironment(
123+
'XDG_DATA_DIRS',
124+
<Directory>[Directory('/usr/local/share'), Directory('/usr/share')],
125+
);
126+
}
127+
128+
/// The base directory relative to which user-specific data files should be
129+
/// written. (Corresponds to `$XDG_DATA_HOME`).
130+
///
131+
/// Throws [StateError] if the HOME environment variable is not set.
132+
Directory get dataHome =>
133+
_directoryFromEnvironment('XDG_DATA_HOME', '.local/share');
134+
135+
/// The base directory relative to which user-specific runtime
136+
/// files and other file objects should be placed. (Corresponds to
137+
/// `$XDG_RUNTIME_DIR`).
138+
///
139+
/// Throws [StateError] if the HOME environment variable is not set.
140+
Directory get runtimeDir => _directoryFromEnvironment('XDG_RUNTIME_DIR', null);
141+
142+
/// Gets the xdg user directory named by `dirName`.
143+
///
144+
/// Use [getUserDirectoryNames] to find out the list of available names.
145+
Directory getUserDirectory(String dirName) {
146+
final ProcessResult result = _processManager.runSync(
147+
<String>['xdg-user-dir', dirName],
148+
includeParentEnvironment: true,
149+
stdoutEncoding: Encoding.getByName('utf8'),
150+
);
151+
final String path = utf8.decode(result.stdout).split('\n')[0];
152+
return Directory(path);
153+
}
154+
155+
/// Gets the set of user directory names that xdg knows about.
156+
///
157+
/// These are not paths, they are names of xdg values. Call [getUserDirectory]
158+
/// to get the associated directory.
159+
///
160+
/// These are the names of the variables in "[configHome]/user-dirs.dirs", with
161+
/// the `XDG_` prefix removed and the `_DIR` suffix removed.
162+
Set<String> getUserDirectoryNames() {
163+
final File configFile = File(path.join(configHome.path, 'user-dirs.dirs'));
164+
List<String> contents;
165+
try {
166+
contents = configFile.readAsLinesSync();
167+
} on FileSystemException {
168+
return const <String>{};
169+
}
170+
final Set<String> result = <String>{};
171+
final RegExp dirRegExp =
172+
RegExp(r'^\s*XDG_(?<dirname>[^=]*)_DIR\s*=\s*(?<dir>.*)\s*$');
173+
for (String line in contents) {
174+
final RegExpMatch match = dirRegExp.firstMatch(line);
175+
if (match == null) {
176+
continue;
177+
}
178+
result.add(match.namedGroup('dirname'));
179+
}
180+
return result;
181+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: xdg_directories
2+
description: A Dart package for reading XDG directory configuration information on Linux.
3+
version: 0.1.0
4+
homepage: https://github.com/flutter/packages/tree/master/packages/animations
5+
6+
environment:
7+
sdk: ">=2.3.0 <3.0.0"
8+
9+
dependencies:
10+
path: ^1.6.4
11+
process: ^3.0.12
12+
flutter:
13+
sdk: flutter
14+
15+
dev_dependencies:
16+
mockito: ^4.1.1
17+
flutter_test:
18+
sdk: flutter

0 commit comments

Comments
 (0)