-
Notifications
You must be signed in to change notification settings - Fork 71
Add ZIGUP_INSTALL_PATH environment variable #146
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
Conversation
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. |
I'm sorry, this is making me mad. It seems ironic to me that a tool for managing downloaded files (which happen to be zig releases in this case) would balk at organizing things in a standardized way and instead prefer to make up it's own convention. I would much prefer it if zigup put its folders at On my desktop computer's home folder, which is relatively new, there are still a bunch of random folders. That means I have to look at all this random crap every time I open a file browser, or type Anyway, I don't really expect this to convince anyone. But leaving random shit in my home directory on purpose made me angry enough that I had to write this post. |
If you want to build zigup yourself, I'll accept a PR that adds a build option to override the default install directory. So far no one's taken me up on that offer. You can also override it without building zigup via the if [ ! -e $(which zigup).bin ]; then cp $(which zigup) $(which zigup).bin; fi && echo -e '#!/usr/bin/env sh\nexec '$(which zigup).bin' --install-dir $HOME/.local/share/zigup "$@"' | tee $(which zigup) I'm also open to being persuaded to changing zigup's default, but so far I haven't seen any problems this solves. I'm not seeing how having too many entries in your home directory is solved by moving everything to a subdirectory...then you'll just have alot of entries in that subdirectory instead. I'm not getting why moving entries from one location to another improves things, can you help me understand? |
Hello, @marler8997 it is not necessarily about solving a technical problem but respecting users preferences. For every other language I store everything in (Edit) I guess the disconnect is occurring due to differences in worlflow. There is a significant number of linux users who primarily interact with their system using the terminal. Having a cluttered home when using ls, cd or terminal file managers is untenable such users. |
Hi @marler8997 , thank you for your calm reply. I definitely don't feel like I earned it, I'm kind of regretting blowing up earlier. Kind of going along with what @kodesoul is saying, I'm not sure it's solving a purely technical problem. I know it's bugged me for a long time, years ago I was very disappointed to learn that For something closer to a technical reason, my argument goes more like this:
The argument that this "just pushes it into a subdirectory" is not compelling. That subdirectory is there for programs to keep track of things they care about. When I interact with that directory I'm prepared for the wading I'll have to do. I also don't go there as often as I go to my home directory. I also think an important part of this story is that I was using the I do agree that environment variables bring their own headaches and understand the caution in accepting code that uses them. And actually, I don't set I got angry when I saw you pushing back against "hiding it" in subfolder. In my mind that turned it from a missing feature into a program deliberately making itself obtuse. While I could wrap it in a script, that would mean setting up that script every time I set up a new system. Same with adding a build option -- my problem isn't so much that I can't make it do what I want, it's that I have to go out of my way to tell it what I want it to do. Maybe I'll do a pull request, but realistically:
Sorry for the long rambling post 😓 . Being concise is not one of my virtues, and I'm weirdly emotional on this topic. Thank you for reading, anyway. And if I got anything wrong, please correct me; I don't want to be putting words in other people's mouths. |
Haha, no worries, you seem like a nice person and I can relate/understand being frustrated when discussing technical differences. By the way, someone actually recently added a
I appreciate you taking the time to write down your experience/reasons for why it's annoying that zigup adds an entry to your That being said, outside of changing the default I'm also open to other ideas/suggestions. Having to create a wrapper script around zigup could be annoying and/or hard to manage. For that reason, I'd be open to supporting a config file, and that's a case I'd be more than happy to use the XDG spec for. If you use some sort of home manager or dotfiles directory, then you could put your zigup config in there and zigup would automatically find it/use it. Also to reiterate...this is likely to become moot soon since the install directory will eventually go away. Plan is to store the zig compilers in the global zig cache directory. Once that's done, zigup will still need to store some state somewhere on the filesystem, and I'll be using the standard XDG locations for state/configuration for that. |
I don't think this would be a good idea because Zig's global Cache directory is I think the ideal option is just to offer the opportunity for users to choose the directories location. Maybe only have the |
Interesting, yeah I think giving users the choice makes sense. You can do that today with a wrapper script but moving to a config file probably makes sense. Also you bring up a good point about the cache directory. One thing I like about using the global cache is that means all tools can use the same compiler instance, I wonder if there's a solution that can still maintain this property? |
Woops, I sorted out my branches in my fork and accidentally closed this issue. As the conversation is still ongoing I'm trying to reopen it but can't quite figure out how... I think a ZON configuration file which can set the |
Sounds reasonable to me. |
Fixes marler8997#177. Also related to discussion in marler8997#146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
Fixes marler8997#177. Also related to discussion in marler8997#146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
…stems Fixes marler8997#177. Also related to discussion in marler8997#146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
…stems Fixes marler8997#177. Also related to discussion in marler8997#146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
…stems Fixes marler8997#177. Also related to discussion in marler8997#146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
…stems Fixes #177. Also related to discussion in #146. Windows path is not changed because currently on Windows the path is derived from the location of the binary, so assuming Windows does not allow two identcal paths, the most logical path name, `zigup`, is not available. I don't know about Windows conventions and don't have a Windows machine available to be able to test my assumptions.
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.