Skip to content
This repository was archived by the owner on Nov 1, 2024. It is now read-only.

Introduce applicationConfigHome #66

Merged
merged 2 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.4

- Introduce `applicationConfigHome` for making it easy to consistently find the
user-specific application configuration folder.

## 0.3.3

- Reverted `meta` constraint to `^1.3.0`.
Expand Down
63 changes: 63 additions & 0 deletions lib/cli_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,66 @@ Directory getSdkDir([List<String>? cliArgs]) {

/// Return the path to the current Dart SDK.
String getSdkPath() => path.dirname(path.dirname(Platform.resolvedExecutable));

/// Get the user-specific application configuration folder for the current
/// platform.
///
/// This is a location appropriate for storing application specific
/// configuration for the current user. The [productName] should be unique to
/// avoid clashes with other applications on the same machine. This method won't
/// actually create the folder, merely return the recommended location for
/// storing user-specific application configuration.
///
/// The folder location depends on the platform:
/// * `%APPDATA%\<productName>` on **Windows**,
/// * `$HOME/Library/Application Support/<productName>` on **Mac OS**,
/// * `$XDG_CONFIG_HOME/<productName>` on **Linux**
/// (if `$XDG_CONFIG_HOME` is defined), and,
/// * `$HOME/.config/<productName>` otherwise.
///
/// This aims follows best practices for each platform, honoring the
/// [XDG Base Directory Specification][1] on Linux and [File System Basics][2]
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 have documentation for the windows convention?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried, I can't find any canonical source on MSDN... The closes I got was:
https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables

But I have no idea what that page actually pertains to.. It looks like it says:

When using the XML files MigDocs.xml, MigApp.xml, and MigUser.xml, you can use environment variables to identify folders that may be different on different computers

So it pertains to people writing such XML files.. and not as general documentation of the Windows environment variables. Or at-least this is not clear to me 🙈

There is also references to Windows File System Namespace Usage Guidelines floating around, but again I can't find updated documentation from original source.

Who knows... maybe it's hidden behind an MSDN subscription? Or maybe it's just so widely known and there is so many search hits that finding the canonical documentation is very hard.

We could use wikipedia:

I just gave up 🤣

/// on Mac OS.
///
/// Throws if `%APPDATA%` or `$HOME` is undefined.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Throws if `%APPDATA%` or `$HOME` is undefined.
/// Throws if `%APPDATA%` or `$HOME` is needed but undefined.

///
/// [1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
/// [2]: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW1
String applicationConfigHome(String productName) =>
path.join(_configHome, productName);

String get _configHome {
if (Platform.isWindows) {
final appdata = Platform.environment['APPDATA'];
if (appdata == null) {
throw StateError('Environment variable %APPDATA% is not defined!');
}
return appdata;
}

if (Platform.isMacOS) {
return path.join(_home, 'Library', 'Application Support');
}

if (Platform.isLinux) {
final xdgConfigHome = Platform.environment['XDG_CONFIG_HOME'];
if (xdgConfigHome != null) {
return xdgConfigHome;
}
// XDG Base Directory Specification says to use $HOME/.config/ when
// $XDG_CONFIG_HOME isn't defined.
return path.join(_home, '.config');
}

// We have no guidelines, perhaps we should just do: $HOME/.config/
// same as XDG specification would specify as fallback.
return path.join(_home, '.config');
}

String get _home {
final home = Platform.environment['HOME'];
if (home == null) {
throw StateError('Environment variable \$HOME is not defined!');
}
return home;
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cli_util
version: 0.3.3
version: 0.3.4
description: A library to help in building Dart command-line apps.
repository: https://github.com/dart-lang/cli_util

Expand Down
6 changes: 6 additions & 0 deletions test/cli_util_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ void defineTests() {
expect(isSdkDir(Directory(getSdkPath())), true);
});
});

group('applicationConfigHome', () {
test('returns a string', () {
expect(applicationConfigHome('dart'), isA<String>());
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm - this is hard to test - but it seems we should be able to do better.

Could we at least confirm that the string ends with '${separator}dart'

});
});
}