Code Monkey home page Code Monkey logo

directories-rs's People

Contributors

b-r-u avatar calinou avatar dwijnand avatar emlun avatar fkohlgrueber avatar kraai avatar mathstuf avatar matklad avatar soc avatar spacekookie avatar tbu- avatar wezm avatar ydx-2147483647 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

directories-rs's Issues

Add trash_dir to UserDirs

Self-explanatory.

In Linux, it is located under $HOME/.local/share/Trash. It has these entries:

  • directorysizes file only containing deleted folders.
  • info directory with *.trashinfo files inside.
  • files directory containing deleted files and directories.

Documentation for `BaseDirs` mentions panicing, but the function returns None

Documentation for BaseDirs::new contains the following:

Panics

Panics if the home directory cannot be determined. See [home_dir].

but from my understanding, the function returns None in the circumstance. Also, home_dir links to std::env::home_dir, but the implementation in this crate is different wrt. handling of empty paths. Should it link to dirs::home_dir instead?

Relicense under MIT/Apache-2

It has been brought up repeatedly that MIT/Apache-2 is the preferred license, especially for crates the core ecosystem might depend on (like cargo).

Steps that would be necessary:

  • Ask contributors whether this is fine for them
  • If all agree, change license.
  • Publish new version, probably combined with the necessary fixes/changes around home_dir.

Make `ProjectDirs` return temporary directories for testing

I'm creating a command-line application that stores its data in the locations returned by ProjectDirs. In order to test the application without affecting the user's data, I'd like to be able to make ProjectDirs return temporary directories when the application is run during testing. I think that setting the XDG_... environment variables would work on Linux and setting the HOME environment variable would work on macOS, but I don't see a way to do this on Windows. Would adding a standard way to do this to directories-rs be welcome? Do you have any suggestions for how to do so?

System folders?

Need to know if to use Program\ Files or /usr/share or /usr/games/share.

Access directories with getters

Currently, the fields of BaseDirectories and ProjectDirectories are private, and can't be accessed by external crates. I propose we add getters that return Path/Option<Path>.

Deal with home_dir changes

std::env::home_dir is not working correctly on (at least) Linux, macOS and Windows.

Therefore, we provide our own implementation here, like in dirs-dev/dirs-rs@b7ea3b7.

Along with that, we need to deal with the fact that home_dir can now fail in non-exotic cases, so the signatures have to reflect that, see dirs-dev/dirs-rs@6536c1f, either by

  • making {BaseDirs, UserDirs}::new and ProjectDirs::from return Option, or
  • changing home_dir, cache_dir, config_dir etc. to return Option

feature request: recognise systemd environment variable for systemd services

I would like to write an app which can be run both

  • in the terminal as a normal user, writing its cache to XDG_CACHE_HOME
  • as a systemd service as a system user, and then write its cache to /var/cache/ in a directory prepared by systemd with CacheDirectory=<progname>.

In the second case, systemd sets the CACHE_DIRECTORY env var, and directories-rs could recognize that.

This also applies for other directories than cache: from man systemd.exec:

           Table 2. Automatic directory creation and environment variables
           ┌────────────────────────┬────────────────┬───────────────────────┬──────────────────────────┐
           │Directory               │ Below path for │ Below path for user   │ Environment              │
           │                        │ system units   │ units                 │ variable set             │
           ├────────────────────────┼────────────────┼───────────────────────┼──────────────────────────┤
           │RuntimeDirectory=       │ /run/          │ $XDG_RUNTIME_DIR      │ $RUNTIME_DIRECTORY       │
           ├────────────────────────┼────────────────┼───────────────────────┼──────────────────────────┤
           │StateDirectory=         │ /var/lib/      │ $XDG_CONFIG_HOME      │ $STATE_DIRECTORY         │
           ├────────────────────────┼────────────────┼───────────────────────┼──────────────────────────┤
           │CacheDirectory=         │ /var/cache/    │ $XDG_CACHE_HOME       │ $CACHE_DIRECTORY         │
           ├────────────────────────┼────────────────┼───────────────────────┼──────────────────────────┤
           │LogsDirectory=          │ /var/log/      │ $XDG_CONFIG_HOME/log/ │ $LOGS_DIRECTORY          │
           ├────────────────────────┼────────────────┼───────────────────────┼──────────────────────────┤
           │ConfigurationDirectory= │ /etc/          │ $XDG_CONFIG_HOME      │ $CONFIGURATION_DIRECTORY │
           └────────────────────────┴────────────────┴───────────────────────┴──────────────────────────┘

Feature request: Add user program directory

This is the read-only directory where static package files (executables, shared libraries, vendor resources, etc.) is installed. It's different from application data which could be generated during running and should be writable.
And it's only readable by the user who installed the package. It's like C:\Program Files\, but for each user.

Linux

FHS (https://www.freedesktop.org/software/systemd/man/file-hierarchy.html#User%20Packages)
Base: ~/.local/lib/

Private, static vendor resources of the package, compatible with any architecture, or any other kind of read-only vendor data.

Win32

Known Folders (https://docs.microsoft.com/en-us/windows/win32/msi/single-package-authoring)
Base: %LocalAppData%\Programs (FOLDERID_UserProgramFiles)

When a user installs the dual-purpose package on Windows 7 or Windows Server 2008 R2 using the per-user context, these components are saved in the Programs folder of the current user (for example at %LocalAppData%\Programs) and can be accessed only by that user.

Consider a `Dirs` API that exposes individual functions

The difference to existing APIs is that the values are recomputed every time, not computed once, like with BaseDirs::new, UserDirs::new and ProjectDirs::from, and people could directly use whatever function they need without computing related ones.

Windows user font directory

Heya,
User specific font directory was introduced in Windows (sometime during ~2018) and it's available at %AppData%\Local\Microsoft\Windows\Fonts, but there's a platform API contract curveball ahead.
According to this stack overflow comment, you should not access and/or manipulate the user fonts this way (referencing Why is there no programmatic access to the Start menu pin list?), because the directory has not been added to the Windows known folders API.
Quoting the stackoverflow answer, who loosely quoted Raymond Chen:

Because the user font directory is none of your business.

All this information is actually quite easy to find with your favourite internet search engine, but should we still provide the directory to access fonts for Windows regardless the platform API contract?
We could provide the directory, but document to strongly advise against using it and referring devs to do it correctly for the appropriate platform. AddFontResourceExW

The implementation could be just as simple as being relatively defined to %LOCALAPPDATA%

Aside: The windows platform contract basically forces you to make a daemon/service to broadcast any font changes via window broadcasts, register the fonts again every time the system/service has started and deregister and register the fonts again on font updates.
Aside, extra: But this was actually already on my roadmap, so it's not too-big an issue and yes, I'm making a cross-platform font manager, what clued you in? :D

Comments and thoughts appreciated, thanks.

CI: Pin a minimum supported stable Rust version

To avoid accidentally increasing the minimum supported Rust version, the CI scripts could include a build for a fixed stable Rust version.
I'm not sure what the minimum working version is right now (I tried to lower it with #31), because I couldn't test all platforms.

Add support for Saved Games directory?

Windows (since Vista) has the FOLDERID_SavedGames Known Folder (defaults to %USERPROFILE%\Saved Games). It would be nice if ProjectDirs could surface this in e.g. a saved_games_dir() method.

I don't believe Linux or MacOS has an equivalent; while you could fall back to data_dir() on those systems, that risks setting forth an opinion on a surprisingly controversial topic. It may be best instead to return an Option<&Path>, similar to runtime_dir(), which is None for MacOS and Linux so that developers can make their own decisions there. This could also return None on pre-Vista Windows systems as well.

Functions should return Result not Option

We had a user report a bad error message from some Arti libraries on Android. The root cause of the problem was #83, but additionally, I felt that the error message from our library was too poor. (https://gitlab.torproject.org/tpo/core/arti/-/issues/ 989 999)

I investigated and found that the main reason the message was poor was because ProjectDirs::from simply returned None. So we had to make up our own, rather useless, error message.

IMO all the fallible functions should return Result. (This would be a semver-breaking change, obviously.)

WASM build for the library?

Hi,

Have you considered a WebAssembly build for the library ?
It should allow the usage of this library from any system using webassembly.

WebAssembly + WASI is getting traction and I think it's a good target to keep in mind.

Calling `xdg-user-dirs` on linux takes non-negligible amount of time

If I have xdg-user-dirs utility installed, then creating BaseDirs on my machine takes about 18 milliseconds, which seems pretty substantiation. If I don't have xdg-user-dirs, the time is 2 ms. Finally, if I patch directories-rs to just return None from run_xdg_user_dir_command, the time drops to 8 μs.

Given that xdg-user-dirs is used for stuff like audio_dir, which is probably isn't required for some of potential clients of directories-rs, like Cargo and rustup, I wonder if we should try to optimize away this overhead? Some possible solutions:

  1. Remove audio_dir and such from API altogether for now.
  2. On Linux, use lazy_cell to call xdg-user-dirs only when necessary.
  3. Move audio_dir and friends to another struct.
  4. Reimplement xdg-user-dirs as a Rust library: looks like xdg-user-dirs basically just reads ~/.config/user-dirs.dirs file, so re implementing it should not be super complicated, and should bring substantial performance improvements by removing process spawning overhead.

Should something like temp_dir be added?

As far as I remember from the last time I looked into this, the problem was that operating systems had wildly different definitions of temp dirs and their usage.

Consider using config and data subdirectories for {FOLDERID_RoamingAppData} on Windows

Status Quo

BaseDirs::config_dir:   {FOLDERID_RoamingAppData}
BaseDirs::data_dir:     {FOLDERID_RoamingAppData}
ProjectDirs.config_dir: {FOLDERID_RoamingAppData}/_yourprojectname_/
ProjectDirs.data_dir:   {FOLDERID_RoamingAppData}/_yourprojectname_/

One of the issues with this is that applications that provide global overrides (like cargo's $CARGO_HOME) will end up putting things into the same directory, if no sub-directories are used.

So at the point in time when people want to migrate from $CARGO_HOME back to the standard setup, they will go through the $CARGO_HOME dir and need to sort out which of the files are config, cache, data etc.

Alternative A: Add config/data sub-directories to the paths of both BaseDirs::{config,data}_dir and ProjectDirs.{config,data}_dir

BaseDirs::config_dir:   {FOLDERID_RoamingAppData}/config/
BaseDirs::data_dir:     {FOLDERID_RoamingAppData}/data/
ProjectDirs.config_dir: {FOLDERID_RoamingAppData}/_yourprojectname_/config/
ProjectDirs.data_dir:   {FOLDERID_RoamingAppData}/_yourprojectname_/data/

Benefits:

  • More overall consistency across Linux, macOS and Windows
  • config and data is cleanly separated, not put into the same folder

Drawbacks:

  • Not an established standard on Windows. The structure might be fine for the project directories, but less so for the general base directories.

Alternative B: Add config/data sub-directories only to the paths of ProjectDirs.{config,data}_dir

BaseDirs::config_dir:   {FOLDERID_RoamingAppData}/
BaseDirs::data_dir:     {FOLDERID_RoamingAppData}/
ProjectDirs.config_dir: {FOLDERID_RoamingAppData}/_yourprojectname_/config/
ProjectDirs.data_dir:   {FOLDERID_RoamingAppData}/_yourprojectname_/data/

Benefits:

  • Slightly more overall consistency across Linux, macOS and Windows
  • config and data of applications is cleanly separated, not put into the same folder

Drawbacks:

  • Slightly less internal consistency of BaseDirs and ProjectDirs on Windows.

Additional Consideration

BaseDirs::cache_dir:   {FOLDERID_AppData}/cache

Note the cache directory that is appended to the path. It might make sense to consider whether it makes sense to change this, depending on the alternative that is picked.

ProjectDirs path problem under Windows

Under Windows, there is a split between the local appdata folder and the roaming appdata folder. With regards to what goes where, they're almost interchangeable except that the roaming folder is for user app data that should be synchronized across machines while the local folder is for user app data that is machine-specific and need not/should not be synchronized to other machines.

(The only time any of this comes into play is when people are connected to a domain and using roaming profiles which brings their environment with them each time they log onto a machine, even if it's not "their" machine.)

I'm not sure the decision to use the roaming folder for ProjectDirs is correct given that the description says it's for caching, etc. and caches should generally not be synchronized.

e.g. Chrome stores its caches and more under %localappdata% and not %appdata%, Microsoft stores a user's own crash dumps under %localappdata% while they store things like the dictionaries that a user has installed to %appdata%.

But configuration (aka $HOME/.config) definitely belongs in %roamingappdata%.

Add CI

  • Add Travis CI for Linux and macOS
  • Add AppVeyor for Windows

Add a way to force usage of ogranisation name on Linux

Currently, on Linux, the organisation name is ignored, and e.g. ProjectDirs::config_dir() will return simply ~/.config/appname. This may be enough for applications with some very unique names, but when using some more generic words, can lead to conflicts.

I'd like a way to force the lib to use the organisation name on Linux, so I'd get e.g ~/.config/suve/appname instead of just ~/.config/appname.

Support usage of custom directory

This crate is very useful to get the standard directories for storing files in the app's cache or to read/write configuration files. However, when using this to allow custom directories specified by the user there are some problems.

Let me expand a bit on this. We are building an API that can be used to build applications for different platforms. By default the API expects some configuration files to reside in the application directories that I get using ProjectDirs::from(a, b, c). So far, so good. But I also want to give the user the flexibility of setting a custom path where the configuration files can be stored. So assuming I'm holding this path in memory, I thought I could use ProjectDirs::from. I'm not having a problem with *nix based platforms (Android and iOS included) however on windows /config is being appended to the custom path that has been set. Is there a way to work around this?

TL;DR:

let project_dirs = ProjectDirs::from("/Some/custom/path")?;
println!("{:?}", project_dirs.config_dir());

This prints

  • /Some/custom/path on *NIX based platforms (Android and iOS included)
  • /Some/custom/path/config on Windows.

Provide API to get only specific directory

With dirs crate I can get any directory directly. But directories provides structs and parses all directories at once. Users usually want to get a single directory. I would suggest to create separate functions as in dirs crate.

BSD Support

BSD systems (FreeBSD, NetBSD, OpenBSD, etc.) all follow the freedesktop specifications too so should be handled in the same way the crate currently supports Linux.

Since there are many OSes that follow this spec (Linux, BSD, Redox, Solaris, Illumos, etc) it might make sense to have the crate default to the "lin" module and only white list exceptions like Windows and macOS. That way the crate won't need to be updated each time someone uses it on a new target.

Support global config directory in ProjectDirs

Hi! It would be great if this library supported global config directories... My idea is:

Platform Value Example
Linux /etc/_project_path_ /etc/barapp
macOS /etc/_project_path_ or /usr/local/etc/_project_path_ (if installed via homebrew) /etc/barapp
Windows %ProgramData%\_project_path_\config C:\ProgramData\Bar App\config

MacOS implementation challenges:

  • Only the "bundle_id" is passed to project_dirs_from_path, which makes it hard to get the _project_path_.
  • How to detect if running through homebrew? Does homebrew patch repositories to change /etc/ to /usr/local/etc?

Another idea would be to use /Library/Application Support instead...

Kind of related to #78

Config dir on macOS should not be ~/Library/Preferences

This library is vending ~/Library/Preferences as the config dir on macOS. This is a bad idea. Apple's own documentation explicitly states

You should not create files in this directory yourself. Instead, use the NSUserDefaults class or CFPreferences API to get and set preference values for your app.

Any configuration files written by the app without using one of those two APIs belongs in ~/Library/Application Support instead.

$XDG_DATA_DIRS

Hello,

I don’t find a way to retreive $XDG_DATA_DIRS. Is it a missing feature?

From XDG specifications:

$XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.

If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.

After reading the source code, I think I need a SystemDirs likes ProjectDir.

What's the difference between state_dir and data_local_dir?

On Windows, data_local_dir is LocalAppData which AIUI is like RoamingAppData but not synchronised across machines. The docs for state_dir say that it's not synchronised across machines. Are they not the same thing? If they are, could data_local_dir's behaviour on Linux be changed to match state_dir? Currently state_dir is only useful on Linux, and to me it would make sense to merge it into the existing data_local_dir function.

Should home_dir on Windows consider %USERPROFILE%?

Making home_dir consider %USERPROFILE% on Windows would be more in line with its behavior on Linux, but I'm not really sure what the best practices around changing %USERPROFILE% on Windows are.

I assume that this happens far less frequently on Windows than it does on Linux, and I'd appreciate comments and experience reports from people who have done this to better understand their use cases.

Feature Request: Force MacOS to behave like Linux

I have a CLI app that uses the xdg crate. The current behavior of the crate is that even on OSX it returns Linux-like paths for the ones I care about, namely ~/.config/myapp. Now the crate itself doesn't support Windows (and will straight up refuse to compile on unixlikes), so I was looking for alternatives and found this crate.

My current issue is that I'm looking for something that can kind of bridge the gap with minimal intervention in the CLI code itself by allowing the behavior of Linux on OSX while retaining the behavior for Windows.

I know this doesn't quite meet the philosophy of the crate, but it would make eventual migration much easier. Additionally I'm quite sincere about my dotfiles, and I do like the simplicity of .config files even on OSX (easier to check into my dotfiles), and this would allow me to continue the behavior and have some parity between my terminal configs on my various machines.

Is forcing Linux behavior on OSX something that could be considered at all? I would be happy to implement it myself as well.

`config_dir` but local instead of roaming?

I think there is a missing use case of config_local_dir.

My program needs a config file with the computer's nickname, like "my laptop".

If I use config_dir, it will go into AppData/Roaming on Windows, but I feel like it should be AppData/Local/... on Windows and ~/.config/... on Linux.

Trash dir

Hi,

I was recently looking for a way to locate the user’s trash directory and noticed that some issues here mentioned trash, but that this didn’t seem to be present in this library. However, it seems that trash_dir is still in lib.rs, just that it is commented out. Assuming that this was once provided by this library, would it be possible to restore this feature?

Thanks.

Support non-Windows/Linux/macOS operating systems

Currently the crate fails to compile for these.

I'd suggest to use the Linux conventions in this case, as these are common for other unix-like operating systems such as the BSDs (FreeBSD, NetBSD, DragonFlyBSD, OpenBSD).

External review of the chosen paths to standardized directories on each platform

Many of the paths to standardized directories are thoroughly documented by each operating system vendor, but it would still be helpful for someone not me to go through them and give things a second review.

There are also cases where some directories just don't exist or have a very different behavior:

For instance executables_dir: On Linux, one can expect that binaries placed in this folder also end up on the $PATH, but no such folder exists on macOS and Windows.

It would be helpful to go through the ones that return Option<PathBuf> and make sure these provide the best possible experience given the circumstances.

  • executable_dir: Resolved, only provided on Linux.
  • Cache and data directories on Windows, see #9.
  • Review of XDG user directory values on Linux – what should happen if no values are present? Fallback or None?

Better support directory structure on Windows

According to Windows conventions, the application dir should be inside of an organization dir.

e. g. instead of

{FOLDERID_LocalAppData}/_yourprojectname_/cache/

the cache dir should be

{FOLDERID_LocalAppData}/_yourorganizationname_/_yourprojectname_/cache/

This probably requires extending the factory functions or adding new functions.

Shorten types and function names

This is just a suggestion and I'm wondering what you think about it. But all of the types and function names are very verbose.

For example ProjectDirectories could also just be shortened to AppDirs or Base Directories to BaseDirs. Also then having to say dirs.project_config_dir instead of just dirs.config feels…redundant.

So, this is just a suggestion on my part, I'm not married to any of these names. But I think shortening some of the names could make the crate a lot nicer to use.

BaseDirectories => BaseDirs
ProjectDirectories => AppDirs | ProjDirs | Project

let proj = Project::from_name("my_cool_tool");
proj.config()
proj.cache()
proj. ...

let downloads = BaseDirs::downloads()
// ... etc ...

Generally I would suggest using the non-member :: operator instead of normal dot-notation

Cross-platform tmpfs / %TEMP% BaseDir

It would be useful to have a cross-platform way to get the tmp directory. On Mac and Linux, this should return the /tmp directory, on Windows it's held within the TEMP environment variable.

No project directory on Android

I am calling the following on Android

directories::ProjectDirs::from("me", "nikl", "game");

and get back None. The package identifier is me.nikl.game and the app is running on a real device with Android 12.

Is there anything I need to setup or configure to get a proper project directory on Android?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.