-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ZIGUP_INSTALL_PATH environment variable #146
base: master
Are you sure you want to change the base?
Conversation
Added for convenience so that a user can just set this in their RC file instead of setting an alias. It is overrided by the --install-dir flag.
Id love to see this merged. It's generally bad practice to put these files in the $HOME directory despite it happening quite often. Theres even a tool that "fixes" this called https://github.com/b3nj5m1n/xdg-ninja with 2k stars and being updated constantly with 100s of CLI tools added that make this mistake, as well as another called "boxxy" that forces config and cache files to respect XDG spec by using containers. Its safe to say that this is an important thing to many users. This library abstracts this https://github.com/ziglibs/known-folders a bit, but generally the order of precedence goes as follows:
I wrote an example function here of how to correctly handle this for all operating systems, let me know if anyone's serious about accepting the PR and I will flesh this out further and make a new PR if needed. const std = @import("std");
const os = std.os;
const path = std.fs.path;
const Allocator = std.mem.Allocator;
const builtin = @import("builtin");
const testing = std.testing;
const getenv = std.c.getenv;
pub fn UserCacheDir(allocator: Allocator) ![]const u8 {
switch (builtin.os.tag) {
.windows => {
var xdg_dir: ?[]const u8 = null;
xdg_dir = std.process.getEnvVarOwned(allocator, "LocalAppData") catch null;
if (xdg_dir) |dir| {
return dir;
}
return error.CacheDirNotFound;
},
.macos, .ios => {
var xdg_dir: ?[]const u8 = null;
xdg_dir = try std.process.getEnvVarOwned(allocator, "HOME");
if (xdg_dir) |dir| {
return try path.join(allocator, &[_][]const u8{ dir, "Library", "Caches" });
}
return error.CacheDirNotFound;
},
.plan9 => {
var xdg_dir: ?[]const u8 = null;
xdg_dir = try std.process.getEnvVarOwned(allocator, "home");
if (xdg_dir) |dir| {
return try path.join(allocator, &[_][]const u8{ dir, "lib", "cache" });
}
return error.CacheDirNotFound;
},
// Unix like operating systems
else => {
var xdg_dir: ?[]const u8 = null;
xdg_dir = std.process.getEnvVarOwned(allocator, "XDG_CACHE_HOME") catch null;
if (xdg_dir) |dir| {
return dir;
}
xdg_dir = try std.process.getEnvVarOwned(allocator, "HOME");
if (xdg_dir) |dir| {
return try path.join(allocator, &[_][]const u8{ dir, ".cache" });
}
return error.CacheDirNotFound;
},
}
}
obviously could use a little better error handling, but I want to gauge whether it is aligned with the project or what the general consensus is here before I do anything else. |
I've shared my reservations in adding configuration via environment variables here: ziglang/zig#10754 (comment) I've seen people repeat that it's "generally bad practice" to put things in the I'm open to being persuaded/convinced otherwise on these points though, just haven't seen any good counterarguments yet. |
An apt comparison for Windows would be like if Node, Go, Zig, Rust, Java, Android Studio, etc... all insisted on putting their cache, config and state folders and files on your Desktop, and moving those files anywhere else would irreparably break those tools, and if you deleted them, they would just be re-created. Sure, maybe one isn't that annoying, but a ton of tools have done this prior to the xdg-basedir-spec (and many still do) and they add up to a ridiculous amount, which this spec was created to address exactly this problem (same story as hidden files/dirs that are prefixed with a "." which was a previous attempt to address this issue, which also became untenable) Often times you don't even know where these files came from or what they do, or what repercussions deleting it would have... on top of the clutter this causes. or another analogy, would be someone else using your room as a storage unit instead of the closet because the closet is a little further back. As one somewhat dramatically put it in one of the links below:
some writings on the matter:
and then on the other side of this, I don't really seeing it being a hinder to anyone, especially since this also lets everyone place this folder wherever they want it to reside. You could even leave the default as I'd say that this PR is a minimal way to address this. Its a pretty straightforward and simple change without making any structural or significant changes to the tool, and most people could just ignore it if they wanted to, but as I pointed out with tools like xdg-ninja and boxxy, and the creation of a literal xdg spec its a pretty significant issue that a lot of people put a ton of time into fixing. edit: and to tack on to this, I think what you highlighted in the issue that you linked is a compromise already being made by having a CLI flag that overrides this. I also don't think the place where a folder lives is the same compromise as running some obscure libc or ld_preload hack where the stakes are a lot higher and things like env vars actually do make things more complex. At the very least, it would be nice for the default (or a build option) to allow for conformance with the XDG spec. I don't know of a single Linux system that doesn't follow it, and that could be a feasible alternative solution if you were really firm on the no environment variables thing. |
To preface this, I'm a big proponent of questioning why we do things the way we do so that we can learn/grow and improve. I try to understand they "why" behind what we call "good practices" so I can evaluate whether they actually improve things on a case-by-case basis. I've skimmed/read through some of the material you've referenced (thanks for compiling those). The overall impression I get is this XDG standard allows you to understand a bit more about the files that programs are accessing (i.e. is it configuration, data, state, cache, etc) which gives the user/system some control over them (i.e. which filesystems to use for each and/or which permissions to grant and/or whether to share those files across a network, etc). This seems particularly useful for files that are "internal" to programs that the user isn't necessarily suppose to interact with. Now if we consider zigup, it's purpose is to fetch and store multiple versions of the zig compiler somewhere on the filesystem and provide access to those files to the user. These files aren't strictly "internal" to zigup, they are meant to be exposed to the user. This install directory doesn't seem to fit into any of the XDG categories I saw listed, I think the closest match might be "cache" but still doesn't seem to fit. Please let me know if this isn't the case...maybe there is a perfect location for zigup's install directory that has eluded me (i.e. is there a standard location to put user programs/applications)? However, if my summary is accurate, I think a case can be made for setting zigup's install directory in To expand on this a bit, one way to think of zigup is as a package manager...a very minimal one that only manages one package with multiple versions :) Package managers will typically install packages to various global hardcoded paths on the system depending on the package and/or distribution. Selecting a default hardcoded global path like |
For my two cents I care about keeping a clean and organized home directory, and find software that automatically creates unhidden files/directories in my Consider also that package managers may invoke zigup as a dependency, and so this For this I propose that zigup file itself away somewhere by default. On Linux at least I can suggest I do not mind this being configured via an environment variable, configuration file, or any other means. The only option I am not a fan of is having to create an alias, as that feels hacky to me because it depends on my shell configuration which may change from shell-to-shell and is less universal than an envvar. I've read and sympathized with your thoughts on environment variables @marler8997, and IMO an envvar is fine for controlling this specific use case as the configuration is so minimal. We should print out the install path for logging purposes though, and ensure that CLI arguments always override envvars. Alternatively a config file would work just as well and would scale better if more config is added in the future, but may be a bit funny if there's only one configuration to set. For this option I can suggest a ZON file in |
This, and, stops a ton of clutter in the HOME directory. Which is arguably the primary reason XDG and dotfiles exist. If I run
I don't see how allowing the user to move these files out of the $HOME directory makes them not exposed to the user. I also have to imagine most people are just adding this directory (wherever it may be) to the PATH (another env var here we heavily rely on) I am also confused here, from the issue you linked, you want to move the Zig libs and executable into the zig global cache (which ironically lives in
The directory for storing files of this kind would be
IMO this is also bad practice for the exact same reasons. In fact, Zig itself doesn't store packages in $HOME either, it stores them in the cache directory. This is where cache files go, and it should be known that people should be able to delete these files at any time. Which Zig does abide by. It doesn't put packages haphazardly in the $HOME directory. Please help me understand what the resistance to this is? I'm not sure how the issue you linked originally, directly applies to this project. Especially when we are already relying on CLI flags that feasibly do the same thing and other env vars (PATH and HOME) as well as upstream Zig itself respecting the XDG base dir spec... It is your project obviously, and you can do whatever you'd like, but this a pretty hard line for me. |
Having alot of files in the home directory doesn't seem like a problem to me, but I'm willing to hear you out on what problems this causes. Moving files from one place to another doesn't really seem like it's solving anything...all the files are still there, and adding an extra heirarchy makes some things easier and some things harder, so I'm not sure it's a net benefit. Enabling more use cases/control/uniformity seem like the main benefits of XDG which I can get behind.
Yes XDG_CACHE_HOME is a perfect example of a good time to use the XDG standard. I'm not resistant to using the XDG standard, I'm just not sure XDG has any place that's a good fit for zigup's install directory.
I'm not so sure. If you were installing zig via a package manager, I would expect zig to go into a directory in the PATH such as I appreciate some of the points you've brought up and think it's good to exchange perspectives/ideas, which is why I asked for it, however, there's not much point in trying to convince me to move the install directory or add an environment variable to configure it as it's likely going to go away soon. If/when I update zigup to use zig's global cache, compiler's will be stored in XDG_CACHE_HOME like you say. There's also the "exe path link" which is separate from the install directory, and the current mechanism for placing that is to put it in the same directory as zigup. I mention this because you said people might add the install directory to |
I feel like I've already written a lengthy explanation on why this is not the best approach, how it could lead to potential issues, and why it is not considerate use of the user's space. I’d like to think users are capable enough to decide where their files go. Personally, I find the idea of dumping compiler files in the home directory a bit... unconventional, but hey, it’s your choice. A 'no' for any reason is totally fine. I'm not here to rehash the XDG spec, so I’ll leave it at that. |
Added for convenience so that a user can just set this in their RC file instead of setting an alias. It is overrided by the --install-dir flag.