Skip to content

Commit d56c2a9

Browse files
authored
Introduce applicationConfigHome (dart-archive/cli_util#66)
* Introduce applicationConfigHome
1 parent 5763bbe commit d56c2a9

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

pkgs/cli_util/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.3.4
2+
3+
- Introduce `applicationConfigHome` for making it easy to consistently find the
4+
user-specific application configuration folder.
5+
16
## 0.3.3
27

38
- Reverted `meta` constraint to `^1.3.0`.

pkgs/cli_util/lib/cli_util.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,66 @@ Directory getSdkDir([List<String>? cliArgs]) {
5959

6060
/// Return the path to the current Dart SDK.
6161
String getSdkPath() => path.dirname(path.dirname(Platform.resolvedExecutable));
62+
63+
/// Get the user-specific application configuration folder for the current
64+
/// platform.
65+
///
66+
/// This is a location appropriate for storing application specific
67+
/// configuration for the current user. The [productName] should be unique to
68+
/// avoid clashes with other applications on the same machine. This method won't
69+
/// actually create the folder, merely return the recommended location for
70+
/// storing user-specific application configuration.
71+
///
72+
/// The folder location depends on the platform:
73+
/// * `%APPDATA%\<productName>` on **Windows**,
74+
/// * `$HOME/Library/Application Support/<productName>` on **Mac OS**,
75+
/// * `$XDG_CONFIG_HOME/<productName>` on **Linux**
76+
/// (if `$XDG_CONFIG_HOME` is defined), and,
77+
/// * `$HOME/.config/<productName>` otherwise.
78+
///
79+
/// This aims follows best practices for each platform, honoring the
80+
/// [XDG Base Directory Specification][1] on Linux and [File System Basics][2]
81+
/// on Mac OS.
82+
///
83+
/// Throws if `%APPDATA%` or `$HOME` is undefined.
84+
///
85+
/// [1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
86+
/// [2]: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW1
87+
String applicationConfigHome(String productName) =>
88+
path.join(_configHome, productName);
89+
90+
String get _configHome {
91+
if (Platform.isWindows) {
92+
final appdata = Platform.environment['APPDATA'];
93+
if (appdata == null) {
94+
throw StateError('Environment variable %APPDATA% is not defined!');
95+
}
96+
return appdata;
97+
}
98+
99+
if (Platform.isMacOS) {
100+
return path.join(_home, 'Library', 'Application Support');
101+
}
102+
103+
if (Platform.isLinux) {
104+
final xdgConfigHome = Platform.environment['XDG_CONFIG_HOME'];
105+
if (xdgConfigHome != null) {
106+
return xdgConfigHome;
107+
}
108+
// XDG Base Directory Specification says to use $HOME/.config/ when
109+
// $XDG_CONFIG_HOME isn't defined.
110+
return path.join(_home, '.config');
111+
}
112+
113+
// We have no guidelines, perhaps we should just do: $HOME/.config/
114+
// same as XDG specification would specify as fallback.
115+
return path.join(_home, '.config');
116+
}
117+
118+
String get _home {
119+
final home = Platform.environment['HOME'];
120+
if (home == null) {
121+
throw StateError('Environment variable \$HOME is not defined!');
122+
}
123+
return home;
124+
}

pkgs/cli_util/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: cli_util
2-
version: 0.3.3
2+
version: 0.3.4
33
description: A library to help in building Dart command-line apps.
44
repository: https://github.com/dart-lang/cli_util
55

pkgs/cli_util/test/cli_util_test.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@ void defineTests() {
3636
expect(isSdkDir(Directory(getSdkPath())), true);
3737
});
3838
});
39+
40+
group('applicationConfigHome', () {
41+
test('returns a string', () {
42+
expect(applicationConfigHome('dart'), isA<String>());
43+
});
44+
});
3945
}

0 commit comments

Comments
 (0)