-
-
Notifications
You must be signed in to change notification settings - Fork 228
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 $DPATH environment variable for file locations #2281
Conversation
But an environment variable is prone to other kind of issues. For one it's not persistent unless you edit your shell config, which looses locality. Also names are prone to collision. IMO if one wants to get this value in script, we should have a |
imo if you set your environment variable only locally then you probably only want DUB to store its data where you specified in that session. (maybe set to This is similar to the JAVAHOME or GOPATH variables. (go works in a similar way with I think |
if we don't plan to add other tools, it might also make sense to define a |
source/dub/dub.d
Outdated
|
||
@property string dubHome() | ||
const { | ||
if(auto pv = "dubHome" in m_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the setting for this be called dubHome
or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make things a bit more hierarchical, now that we have the ability to (easily) do so ?
Like core.author
in git
, you know.
after discussing with @Geod24 I changed this to also include a setting instead of only an environment variable. This is so that system-wide changes can be made, e.g. by linux package maintainers, but also kept an environment variable so that it's possible to create a quick temporary clean local dub package storage or in general if it might be needed for some specific user's projects on the system. To support changing the path of the packages (and also the config), the config in /etc/dub/settings.json (or /usr/...) will be read first and if the |
This introduces the $DPATH environment variable to override the user's home directory just for D tools. This is also intended to be used by DUB (dlang/dub#2281) when there is not the more explicit `$DUB_HOME` variable set on the system. This allows users who install their D compiler through the install.sh script to both have the compiler installations as well as the dub packages be stored elsewhere in the system than in their home folder. In case we have other tools that download their dependencies into the user's home directory, we should also make them support the same $DPATH environment variable.
This introduces the $DPATH environment variable to override the user's home directory just for D tools. This is also intended to be used by DUB (dlang/dub#2281) when there is not the more explicit `$DUB_HOME` variable set on the system. This allows users who install their D compiler through the install.sh script to both have the compiler installations as well as the dub packages be stored elsewhere in the system than in their home folder. In case we have other tools that download their dependencies into the user's home directory, we should also make them support the same $DPATH environment variable.
This introduces the $DPATH environment variable to override the user's home directory just for D tools. This is also intended to be used by DUB (dlang/dub#2281) when there is not the more explicit `$DUB_HOME` variable set on the system. This allows users who install their D compiler through the install.sh script to both have the compiler installations as well as the dub packages be stored elsewhere in the system than in their home folder. In case we have other tools that download their dependencies into the user's home directory, we should also make them support the same $DPATH environment variable.
Hi 👋 I've been working on something similar (I guess now I'll just wait for this to merge), and just wanted to share some thoughts from my implementation. I also considered something like I am not sure how common this is on Windows or Mac, but a lot of Linux programs use environment variables to control the location of their config/cache/etc files (see this page for some examples). In the end I settled for As for "...it's not persistent unless you edit your shell config", well yes, but users are already used to doing this. zsh even has a special config file pretty much for this purpose ( My impl for reference. |
I made it now so that environment variables can only change both folders at once, but you can use the settings for finer control of user settings and repository path, or use the general "dubHome" setting to set both. Additionally for package maintainers and sysadmins it's probably interesting to have environment variables in the settings, for example to have a different user store for each user, so I added that as well. See the changelog entry for details https://github.com/dlang/dub/blob/5addac0e22036cf6b328bda72ac87c47d55d0331/changelog/dpath.dd |
74ff66d
to
09df591
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized we read /etc/
before /var/lib
...
The idea of a "dub home" is a bit weird: We don't have a unified "root location". We have the badly-named Repository
(see the private struct
in packagemanager.d
) and we tackled on config files on top of that.
Also what's the relationship with customCachePaths
?
changelog/dpath.dd
Outdated
```json | ||
{ | ||
"dubHome": "/path/to/dub", // sets both package store and config location | ||
|
||
// OR | ||
|
||
"userSettings": "/path/to/dub/settings/folder", | ||
"localRepository": "/path/to/dub/repository/folder" | ||
} | ||
``` | ||
|
||
Additionally, these config paths will have environment variables using the `$VARIABLE` syntax resolved. | ||
|
||
The following list describes which path is going to be picked, from top to bottom, stopping whenever one is found: | ||
|
||
- `$DUB_HOME` environment variable | ||
- `$DPATH` environment variable | ||
- system-wide settings.json: `"userSettings"` property | ||
- system-wide settings.json: `"dubHome"` property (only for userSettings) | ||
- through all settings.json: `"localRepository"` property | ||
- through all settings.json: `"dubHome"` property (only for localRepository) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait isn't that what customCachePaths
is for ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this overrides the built-in dub location, so it would never even attempt to read anything from the built-in path, while for customCachePaths it's just an addition of paths.
source/dub/dub.d
Outdated
// override default userSettings + localRepository if a $DPATH or | ||
// $DUB_HOME environment variable is set. | ||
bool overrideUserSettings; | ||
bool overrideLocalRepository; | ||
{ | ||
string dpathOverride = environment.get("DUB_HOME"); | ||
if (!dpathOverride.length) { | ||
dpathOverride = environment.get("DPATH"); | ||
if (dpathOverride.length) | ||
dpathOverride = (NativePath(dpathOverride) ~ "dub/").toNativeString(); | ||
|
||
} | ||
if (dpathOverride.length) { | ||
overrideUserSettings = true; | ||
overrideLocalRepository = true; | ||
|
||
m_dirs.userSettings = NativePath(dpathOverride); | ||
m_dirs.localRepository = m_dirs.userSettings; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we move that logic in SpecialDirs.make
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's difficult as the state variables overrideUserSettings and overrideLocalRepository are later used to determine if custom path logic should be applied.
source/dub/dub.d
Outdated
// Override user + local package path from /etc/dub/settings.json | ||
// Then continues loading local settings from these folders. (keeping | ||
// global /etc/dub/settings.json settings intact) | ||
// | ||
// Don't use it if either $DPATH or $DUB_HOME are set. | ||
if (!overrideUserSettings) { | ||
if (m_config.userSettings.length) { | ||
m_dirs.userSettings = NativePath(m_config.userSettings.expandEnvironmentVariables); | ||
|
||
overrideUserSettings = true; | ||
} else if (m_config.dubHome.length) { | ||
m_dirs.userSettings = NativePath(m_config.dubHome.expandEnvironmentVariables); | ||
|
||
overrideUserSettings = true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The circular dependency is IMO weird. I need a bit of time to think about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a little weird in the code, but I think it's great for user flexibility.
A use case here: package maintainer creates global settings.json in /var/lib/dub
which then specifies where the user-overridable config is located. On linux distros that have read-only filesystems with some special paths for writable things that might for example be useful. Or for users using non-standard paths like storing all dub things on a separate flash drive or something that just isn't mounted in /etc.
Additionally it's possible to make the config only per-user and use an environment variable like $HOME
inside the settings file so each user can have different dub settings.
Any chance we could get #2343 before, since it overhaul this part of the code and simplifies the logic ? I can then rebase your branch on top of it, if you'd like. |
I don't think that's the case, the systemSettings path is the very first config that is read, everything after that overrides the configs. |
My bad, I meant the other way around 🤦 |
I strongly feel that we should not read /etc first, but /var/lib, like currently already done. I think the idea behind that is:
|
8ec873b
to
43bd843
Compare
One use-case that might be important is the default placement path. If you prefer we can tackle it in a separate PR, but for me it makes much more sense to think of them together (I thought the scope of this PR was originally bigger). |
I think a new setting to set the default placement location should be part of a separate PR. |
I though you were planning to tie the location of (I too have possibly misunderstood the scope of these changes). |
rebased to new yaml loader |
no the default placement location setting I was talking about would set a default for the |
Ohh, that makes sense. My bad. |
@Geod24 what's your opinion on this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The env approach is sound, the settings code still makes me uneasy but makes much more sense now, made a few suggestions.
adjusted to review, can rebase if it's fine now |
fixed left-overs |
thanks! |
fix #229
I chose not to add a setting for this to make it easier for other apps
in the ecosystem to understand how to locate and change the dub folder,
to parse packages, manipulate them, maintain them, etc.
Having a setting would require other users to potentially locate the
config files (which has a bunch of exceptions), parse a JSON and find
an optional value. Limiting it to an environment variable means that
also tools like scripts can easily find the location of this.