Skip to content

Commit

Permalink
add env + config for package + settings locations
Browse files Browse the repository at this point in the history
fix #229
  • Loading branch information
WebFreak001 committed Jul 29, 2022
1 parent 17d8c94 commit 8ec873b
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 1 deletion.
41 changes: 41 additions & 0 deletions changelog/dpath.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
DUB settings & packages directory placement overhauled

You can now configure where DUB places its downloaded packages and where the user configuration is stored through environment variables or through the dub configuration. You need to use an environment variable or the system-wide dub configuration to specify where the user configuration is stored.

By default DUB stores the packages on
- Windows: `%APPDATA%/dub/{packages/,settings.json}`
- Posix: `$HOME/.dub/{packages/,settings.json}`

now if the `DUB_HOME` environment variable is set it instead stores the packages (and other config) in
- `$DUB_HOME/{packages/,settings.json}`

alternatively if `DUB_HOME` isn't set, but `DPATH` is set, the following path is used:
- `$DPATH/dub/{packages/,settings.json}`

The `DPATH` environment variable is intended to be used by all D tooling related things doing user-space installation of things. It can be used to avoid cluttering the home folder.

Additionally to environment variables it is possible to configure the package placement path + settings.json path through DUB's settings.json file. To configure where the user-editable settings.json is placed you need to adjust the system-wide dub configuration.

In the settings.json you can set the following fields:

```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)
85 changes: 84 additions & 1 deletion source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,32 @@ class Dub {
m_packageManager = new PackageManager(override_path);
}

private void init(NativePath root_path)
private void loadConfigAndSetDirs(NativePath root_path)
{
this.m_dirs = SpecialDirs.make();

// 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;
}
}

// load system-wide configs:
m_config = new DubConfig(jsonFromFile(m_dirs.systemSettings ~ "settings.json", true), m_config);

auto dubFolderPath = NativePath(thisExePath).parentPath;
Expand All @@ -285,11 +307,48 @@ class Dub {
}
}

// 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;
}
}

// load user config:
m_config = new DubConfig(jsonFromFile(m_dirs.userSettings ~ "settings.json", true), m_config);

// load per-package config:
if (!root_path.empty)
m_config = new DubConfig(jsonFromFile(root_path ~ "dub.settings.json", true), m_config);

// resolve directories from config
if (!overrideLocalRepository) {
if (m_config.localRepository.length) {
m_dirs.localRepository = NativePath(m_config.localRepository.expandEnvironmentVariables);

overrideLocalRepository = true;
} else if (m_config.dubHome.length) {
m_dirs.localRepository = NativePath(m_config.dubHome.expandEnvironmentVariables);

overrideLocalRepository = true;
}
}
}

private void init(NativePath root_path)
{
loadConfigAndSetDirs(root_path);

determineDefaultCompiler();

m_defaultArchitecture = m_config.defaultArchitecture;
Expand Down Expand Up @@ -1920,4 +1979,28 @@ private class DubConfig {
if (m_parentConfig) return m_parentConfig.defaultPostRunEnvironments;
return null;
}

@property string dubHome()
const {
if(auto pv = "dubHome" in m_data)
return (*pv).get!string;
if (m_parentConfig) return m_parentConfig.dubHome;
return null;
}

@property string userSettings()
const {
if(auto pv = "userSettings" in m_data)
return (*pv).get!string;
if (m_parentConfig) return m_parentConfig.userSettings;
return null;
}

@property string localRepository()
const {
if(auto pv = "localRepository" in m_data)
return (*pv).get!string;
if (m_parentConfig) return m_parentConfig.localRepository;
return null;
}
}
8 changes: 8 additions & 0 deletions source/dub/project.d
Original file line number Diff line number Diff line change
Expand Up @@ -1426,6 +1426,7 @@ private string[] processVarsWithGlob(Project, Package)(string var, in Project pr
.filter!(name => globMatch(name, res))
.array;
}

/// Expand variables using `$VAR_NAME` or `${VAR_NAME}` syntax.
/// `$$` escapes itself and is expanded to a single `$`.
private string expandVars(alias expandVar)(string s)
Expand Down Expand Up @@ -1511,6 +1512,13 @@ unittest
assert(expandVars!expandVar("$${DUB_EXE:-dub}") == "${DUB_EXE:-dub}");
}

string expandEnvironmentVariables(string s)
{
import std.process : environment;

return expandVars!(v => environment.get(v))(s);
}

// Keep the following list up-to-date if adding more build settings variables.
/// List of variables that can be used in build settings
package(dub) immutable buildSettingsVars = [
Expand Down
11 changes: 11 additions & 0 deletions test/dpath-variable.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

. $(dirname "${BASH_SOURCE[0]}")/common.sh
export DPATH="${CURR_DIR}/dpath-variable/dpath"
rm -rf "$DPATH"
cd ${CURR_DIR}/dpath-variable
${DUB} upgrade

if [[ ! -f "$DPATH/dub/packages/gitcompatibledubpackage-1.0.1/gitcompatibledubpackage/dub.json" ]]; then
die $LINENO 'Did not get dependencies installed into $DPATH.'
fi
1 change: 1 addition & 0 deletions test/dpath-variable/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dpath
6 changes: 6 additions & 0 deletions test/dpath-variable/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "dpath-variable",
"dependencies": {
"gitcompatibledubpackage": "1.0.1"
}
}
3 changes: 3 additions & 0 deletions test/dpath-variable/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
void main()
{
}

0 comments on commit 8ec873b

Please sign in to comment.