Skip to content
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

Refactor loadConfig to not rely on class state #2757

Merged
merged 1 commit into from
Dec 26, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 38 additions & 20 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class Dub {
private void init()
{
this.m_dirs = SpecialDirs.make();
this.loadConfig();
this.m_config = this.loadConfig(this.m_dirs);
this.m_defaultCompiler = this.determineDefaultCompiler();
}

Expand All @@ -206,12 +206,23 @@ class Dub {
*
* This can be overloaded in child classes to prevent library / unittest
* dub from doing any kind of file IO.
* As this routine is used during initialization, the only assumption made
* in the base implementation is that `m_rootPath` has been populated.
* Child implementation should not rely on any other field in the base
* class having been populated.
*
* Params:
* dirs = An instance of `SpecialDirs` to read from and write to,
* as the configurations being read might set a `dubHome`.
*
* Returns:
* A populated `Settings` instance.
*/
protected void loadConfig()
protected Settings loadConfig(ref SpecialDirs dirs) const
{
import dub.internal.configy.Read;

void readSettingsFile (NativePath path_)
static void readSettingsFile (NativePath path_, ref Settings current)
{
// TODO: Remove `StrictMode.Warn` after v1.40 release
// The default is to error, but as the previous parser wasn't
Expand All @@ -220,10 +231,11 @@ class Dub {
if (path.exists) {
auto newConf = parseConfigFileSimple!Settings(path, StrictMode.Warn);
if (!newConf.isNull())
this.m_config = this.m_config.merge(newConf.get());
current = current.merge(newConf.get());
}
}

Settings result;
const dubFolderPath = NativePath(thisExePath).parentPath;

// override default userSettings + userPackages if a $DPATH or
Expand All @@ -240,17 +252,17 @@ class Dub {
if (dubHome.length) {
overrideDubHomeFromEnv = true;

m_dirs.userSettings = NativePath(dubHome);
m_dirs.userPackages = m_dirs.userSettings;
m_dirs.cache = m_dirs.userPackages ~ "cache";
dirs.userSettings = NativePath(dubHome);
dirs.userPackages = dirs.userSettings;
dirs.cache = dirs.userPackages ~ "cache";
}
}

readSettingsFile(m_dirs.systemSettings ~ "settings.json");
readSettingsFile(dubFolderPath ~ "../etc/dub/settings.json");
readSettingsFile(dirs.systemSettings ~ "settings.json", result);
readSettingsFile(dubFolderPath ~ "../etc/dub/settings.json", result);
version (Posix) {
if (dubFolderPath.absolute && dubFolderPath.startsWith(NativePath("usr")))
readSettingsFile(NativePath("/etc/dub/settings.json"));
readSettingsFile(NativePath("/etc/dub/settings.json"), result);
}

// Override user + local package path from system / binary settings
Expand All @@ -259,24 +271,26 @@ class Dub {
//
// Don't use it if either $DPATH or $DUB_HOME are set, as environment
// variables usually take precedence over configuration.
if (!overrideDubHomeFromEnv && this.m_config.dubHome.set) {
m_dirs.userSettings = NativePath(this.m_config.dubHome.expandEnvironmentVariables);
if (!overrideDubHomeFromEnv && result.dubHome.set) {
dirs.userSettings = NativePath(result.dubHome.expandEnvironmentVariables);
}

// load user config:
readSettingsFile(m_dirs.userSettings ~ "settings.json");
readSettingsFile(dirs.userSettings ~ "settings.json", result);

// load per-package config:
if (!this.m_rootPath.empty)
readSettingsFile(this.m_rootPath ~ "dub.settings.json");
readSettingsFile(this.m_rootPath ~ "dub.settings.json", result);

// same as userSettings above, but taking into account the
// config loaded from user settings and per-package config as well.
if (!overrideDubHomeFromEnv && this.m_config.dubHome.set) {
m_dirs.userPackages = NativePath(this.m_config.dubHome.expandEnvironmentVariables);
m_dirs.cache = m_dirs.userPackages ~ "cache";
if (!overrideDubHomeFromEnv && result.dubHome.set) {
dirs.userPackages = NativePath(result.dubHome.expandEnvironmentVariables);
dirs.cache = dirs.userPackages ~ "cache";
}
}

return result;
}

unittest
{
Expand Down Expand Up @@ -1840,8 +1854,12 @@ version(unittest) package final class TestDub : Dub
super(root, extras, skip);
}

/// Avoid loading user configuration
protected override void loadConfig() { /* No-op */ }
/// Avoid loading user configuration
protected override Settings loadConfig(ref SpecialDirs dirs) const
{
// No-op
return Settings.init;
}
}

private struct SpecialDirs {
Expand Down
Loading