Skip to content

Commit

Permalink
remove GeneratorSettings.cache
Browse files Browse the repository at this point in the history
instead the cache is a property of PackageManager

This way dub lib users don't have to try to figure out where the real
cache path is and can just continue using the generator and describe
APIs like in previous versions.

Customizing cache path is no longer easily possible and now must be done
through creating a custom PackageManager and use that on `new Project()`
to pass into the generators. If needed, APIs to modify m_dirs on
startup could be added to Dub subclasses in the future.
  • Loading branch information
WebFreak001 committed Sep 26, 2023
1 parent 2ea8838 commit be92035
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 77 deletions.
1 change: 0 additions & 1 deletion source/dub/commandline.d
Original file line number Diff line number Diff line change
Expand Up @@ -1878,7 +1878,6 @@ class DescribeCommand : PackageBuildCommand {
GeneratorSettings settings = this.baseSettings;
if (!settings.config.length)
settings.config = m_defaultConfig;
settings.cache = dub.cachePathDontUse(); // See function's description
// Ignore other options
settings.buildSettings.options = this.baseSettings.buildSettings.options & BuildOption.lowmem;

Expand Down
22 changes: 6 additions & 16 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class Dub {

m_packageSuppliers = this.computePkgSuppliers(additional_package_suppliers,
skip_registry, environment.get("DUB_REGISTRY", null));
m_packageManager = new PackageManager(m_rootPath, m_dirs.userPackages, m_dirs.systemSettings, false);
m_packageManager = new PackageManager(m_rootPath, m_dirs.userPackages, m_dirs.systemSettings, m_dirs.cache, false);

auto ccps = m_config.customCachePaths;
if (ccps.length)
Expand Down Expand Up @@ -199,7 +199,7 @@ class Dub {
// to prevent `init` from reading the project's settings.
init();
this.m_rootPath = root;
m_packageManager = new PackageManager(pkg_root);
m_packageManager = new PackageManager(pkg_root, m_dirs.cache);
}

deprecated("Use the overload that takes `(NativePath pkg_root, NativePath root)`")
Expand Down Expand Up @@ -698,7 +698,6 @@ class Dub {
*/
void generateProject(string ide, GeneratorSettings settings)
{
settings.cache = this.m_dirs.cache;
if (settings.overrideToolWorkingDirectory is NativePath.init)
settings.overrideToolWorkingDirectory = m_rootPath;
// With a requested `unittest` config, switch to the special test runner
Expand All @@ -719,7 +718,6 @@ class Dub {
*/
void testProject(GeneratorSettings settings, string config, NativePath custom_main_file)
{
settings.cache = this.m_dirs.cache;
if (settings.overrideToolWorkingDirectory is NativePath.init)
settings.overrideToolWorkingDirectory = m_rootPath;
if (!custom_main_file.empty && !custom_main_file.absolute) custom_main_file = m_rootPath ~ custom_main_file;
Expand Down Expand Up @@ -1343,22 +1341,14 @@ class Dub {
}

/**
* Compute and returns the path were artifacts are stored
* Compute and returns the path were artifacts are stored for the given
* package.
*
* Expose `dub.generator.generator : packageCache` with this instance's
* configured cache.
* See `dub.packagemanager : PackageManager.packageCache`
*/
protected NativePath packageCache (Package pkg) const
{
return .packageCache(this.m_dirs.cache, pkg);
}

/// Exposed because `commandLine` replicates `generateProject` for `dub describe`
/// instead of treating it like a regular generator... Remove this once the
/// flaw is fixed, and don't add more calls to this function!
package(dub) NativePath cachePathDontUse () const @safe pure nothrow @nogc
{
return this.m_dirs.cache;
return m_packageManager.packageCache(pkg);
}

/// Make a `GeneratorSettings` suitable to generate tools (DDOC, DScanner, etc...)
Expand Down
6 changes: 3 additions & 3 deletions source/dub/generators/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ class BuildGenerator : ProjectGenerator {
m_tempTargetExecutablePath = target_path = getTempDir() ~ format(".dub/build/%s-%s/%s/", packageName, pack.version_, build_id);
}
else
target_path = targetCacheDir(settings.cache, pack, build_id);
target_path = m_packageMan.targetCacheDir(pack, build_id);

if (!settings.force && isUpToDate(target_path, buildsettings, settings, pack, packages, additional_dep_files)) {
logInfo("Up-to-date", Color.green, "%s %s: target for configuration [%s] is up to date.",
Expand Down Expand Up @@ -316,7 +316,7 @@ class BuildGenerator : ProjectGenerator {
enum jsonFileName = "db.json";
enum lockFileName = "db.lock";

const pkgCacheDir = packageCache(settings.cache, pack);
const pkgCacheDir = m_packageMan.packageCache(pack);
auto lock = lockFile((pkgCacheDir ~ lockFileName).toNativeString(), 3.seconds);

const dbPath = pkgCacheDir ~ jsonFileName;
Expand Down Expand Up @@ -777,7 +777,7 @@ unittest { // issue #1235 - pass no library files to compiler command line when

auto desc = parseJsonString(`{"name": "test", "targetType": "library", "sourceFiles": ["foo.d", "`~libfile~`"]}`);
auto pack = new Package(desc, NativePath("/tmp/fooproject"));
auto pman = new PackageManager(pack.path, NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), false);
auto pman = new PackageManager(pack.path, NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), NativePath("/tmp/cache/"), false);
auto prj = new Project(pman, pack);

final static class TestCompiler : GDCCompiler {
Expand Down
62 changes: 7 additions & 55 deletions source/dub/generators/generator.d
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,13 @@ class ProjectGenerator
protected {
Project m_project;
NativePath m_tempTargetExecutablePath;
PackageManager m_packageMan;
}

this(Project project)
{
m_project = project;
m_packageMan = project.packageManager;
}

/** Performs the full generator process.
Expand Down Expand Up @@ -331,7 +333,7 @@ class ProjectGenerator

if (genSettings.filterVersions)
foreach (ref ti; targets.byValue)
inferVersionFilters(ti);
inferVersionFilters(m_packageMan, ti);

// mark packages as visited (only used during upwards propagation)
void[0][Package] visited;
Expand Down Expand Up @@ -629,7 +631,7 @@ class ProjectGenerator
}

// infer applicable version identifiers
private static void inferVersionFilters(ref TargetInfo ti)
private static void inferVersionFilters(PackageManager packageManager, ref TargetInfo ti)
{
import std.algorithm.searching : any;
import std.file : timeLastModified;
Expand All @@ -656,7 +658,7 @@ class ProjectGenerator
auto srcs = chain(bs.sourceFiles, bs.importFiles, bs.stringImportFiles)
.filter!(f => dexts.canFind(f.extension)).filter!exists;
// try to load cached filters first
const cacheFilePath = packageCache(NativePath(ti.buildSettings.targetPath), ti.pack)
const cacheFilePath = packageManager.packageCache(ti.pack)
~ "metadata_cache.json";
enum silent_fail = true;
auto cache = jsonFromFile(cacheFilePath, silent_fail);
Expand All @@ -683,7 +685,7 @@ class ProjectGenerator
catch (JSONException e)
{
logWarn("Exception during loading invalid package cache %s.\n%s",
ti.pack.path ~ ".dub/metadata_cache.json", e);
cacheFilePath.toNativeString(), e);
}

// use ctRegex for performance reasons, only small compile time increase
Expand Down Expand Up @@ -768,55 +770,6 @@ class ProjectGenerator
}
}

/**
* Compute and returns the path were artifacts are stored for a given package
*
* Artifacts are stored in:
* `$DUB_HOME/cache/$PKG_NAME/$PKG_VERSION[/+$SUB_PKG_NAME]/`
* Note that the leading `+` in the sub-package name is to avoid any ambiguity.
*
* Dub writes in the returned path a Json description file of the available
* artifacts in this cache location. This Json file is read by 3rd party
* software (e.g. Meson). Returned path should therefore not change across
* future Dub versions.
*
* Build artifacts are usually stored in a sub-folder named "build",
* as their names are based on user-supplied values.
*
* Params:
* cachePath = Base path at which the build cache is located,
* e.g. `$HOME/.dub/cache/`
* pkg = The package. Cannot be `null`.
*/
package(dub) NativePath packageCache(NativePath cachePath, in Package pkg)
{
import std.algorithm.searching : findSplit;

assert(pkg !is null);
assert(!cachePath.empty);

// For subpackages
if (const names = pkg.name.findSplit(":"))
return cachePath ~ names[0] ~ pkg.version_.toString()
~ ("+" ~ names[2]);
// For regular packages
return cachePath ~ pkg.name ~ pkg.version_.toString();
}

/**
* Compute and return the directory where a target should be cached.
*
* Params:
* cachePath = Base path at which the build cache is located,
* e.g. `$HOME/.dub/cache/`
* pkg = The package. Cannot be `null`.
* buildId = The build identifier of the target.
*/
package(dub) NativePath targetCacheDir(NativePath cachePath, in Package pkg, string buildId)
{
return packageCache(cachePath, pkg) ~ "build" ~ buildId;
}

/**
* Provides a unique (per build) identifier
*
Expand Down Expand Up @@ -853,7 +806,6 @@ package(dub) string computeBuildID(in BuildSettings buildsettings, string config
}

struct GeneratorSettings {
NativePath cache;
BuildPlatform platform;
Compiler compiler;
string config;
Expand Down Expand Up @@ -1234,7 +1186,7 @@ version(Posix) {

auto desc = parseJsonString(`{"name": "test", "targetType": "library", "preGenerateCommands": ["touch $PACKAGE_DIR/source/bar.d"]}`);
auto pack = new Package(desc, NativePath("dubtest/preGen".absolutePath));
auto pman = new PackageManager(pack.path, NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), false);
auto pman = new PackageManager(pack.path, NativePath("/tmp/foo/"), NativePath("/tmp/foo/"), NativePath("/tmp/cache/"), false);
auto prj = new Project(pman, pack);

final static class TestCompiler : GDCCompiler {
Expand Down
8 changes: 7 additions & 1 deletion source/dub/generators/targetdescription.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@ import dub.compilers.compiler;
import dub.description;
import dub.generators.generator;
import dub.internal.vibecompat.inet.path;
import dub.packagemanager;
import dub.project;

class TargetDescriptionGenerator : ProjectGenerator {
TargetDescription[] targetDescriptions;
size_t[string] targetDescriptionLookup;

private {
PackageManager m_packageMan;
}

this(Project project)
{
super(project);
m_packageMan = project.packageManager;
}

protected override void generateTargets(GeneratorSettings settings, in TargetInfo[string] targets)
Expand All @@ -47,7 +53,7 @@ class TargetDescriptionGenerator : ProjectGenerator {
d.buildSettings = ti.buildSettings.dup;
const buildId = computeBuildID(d.buildSettings, ti.config, settings);
const filename = settings.compiler.getTargetFileName(d.buildSettings, settings.platform);
d.cacheArtifactPath = (targetCacheDir(settings.cache, ti.pack, buildId) ~ filename).toNativeString();
d.cacheArtifactPath = (m_packageMan.targetCacheDir(ti.pack, buildId) ~ filename).toNativeString();
d.dependencies = ti.dependencies.dup;
d.linkDependencies = ti.linkDependencies.dup;

Expand Down
77 changes: 77 additions & 0 deletions source/dub/packagemanager.d
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ class PackageManager {
* of available packages.
*/
bool m_initialized;
/**
* Path where build artifacts are stored, e.g. `~/.dub/cache/` on POSIX.
*
* See dub.d SpecialDirs.cache for more details.
*
* To initialize with default DUB values, instantiate an instance of
* `DUB` and access its packageManager.
*/
NativePath m_cachePath;
}

/**
Expand All @@ -107,12 +116,22 @@ class PackageManager {
Params:
path = Path of the single repository
*/
deprecated("Obtain the package manager from `Dub` or instantiate with a cache path where binaries should go")
this(NativePath path)
{
this.m_internal.searchPath = [ path ];
this.refresh();
}

/// ditto
this(NativePath path, NativePath cachePath)
{
this.m_internal.searchPath = [ path ];
this.m_cachePath = cachePath;
this.refresh();
}

deprecated("Obtain the package manager from `Dub` or instantiate with a cache path where binaries should go")
this(NativePath package_path, NativePath user_path, NativePath system_path, bool refresh_packages = true)
{
m_repositories = [
Expand All @@ -123,6 +142,19 @@ class PackageManager {
if (refresh_packages) refresh();
}

/// ditto
this(NativePath package_path, NativePath user_path, NativePath system_path, NativePath cache_path, bool refresh_packages = true)
{
m_repositories = [
Location(package_path ~ ".dub/packages/"),
Location(user_path ~ "packages/"),
Location(system_path ~ "packages/")];

m_cachePath = cache_path;

if (refresh_packages) refresh();
}

/** Gets/sets the list of paths to search for local packages.
*/
@property void searchPath(NativePath[] paths)
Expand Down Expand Up @@ -1011,6 +1043,51 @@ symlink_exit:
}
}
}

/**
* Compute and returns the path were artifacts are stored for a given package
*
* Artifacts are stored in:
* `$DUB_HOME/cache/$PKG_NAME/$PKG_VERSION[/+$SUB_PKG_NAME]/`
* Note that the leading `+` in the sub-package name is to avoid any ambiguity.
*
* Dub writes in the returned path a Json description file of the available
* artifacts in this cache location. This Json file is read by 3rd party
* software (e.g. Meson). Returned path should therefore not change across
* future Dub versions.
*
* Build artifacts are usually stored in a sub-folder named "build",
* as their names are based on user-supplied values.
*
* Params:
* pkg = The package. Cannot be `null`.
*/
package(dub) NativePath packageCache(in Package pkg) const
{
import std.algorithm.searching : findSplit;

assert(pkg !is null);
assert(!m_cachePath.empty, "cannot use packageCache when no package cache path has been specified in constructor");

// For subpackages
if (const names = pkg.name.findSplit(":"))
return m_cachePath ~ names[0] ~ pkg.version_.toString()
~ ("+" ~ names[2]);
// For regular packages
return m_cachePath ~ pkg.name ~ pkg.version_.toString();
}

/**
* Compute and return the directory where a target should be cached.
*
* Params:
* pkg = The package. Cannot be `null`.
* buildId = The build identifier of the target.
*/
package(dub) NativePath targetCacheDir(in Package pkg, string buildId) const
{
return packageCache(pkg) ~ "build" ~ buildId;
}
}

deprecated(OverrideDepMsg)
Expand Down
2 changes: 1 addition & 1 deletion source/dub/project.d
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ class Project {
mainfile = getTempFile("dub_test_root", ".d");
else {
import dub.generators.build : computeBuildName;
mainfile = packageCache(settings.cache, this.rootPackage) ~
mainfile = m_packageManager.packageCache(this.rootPackage) ~
format("code/%s/dub_test_root.d",
computeBuildName(config, settings, import_modules));
}
Expand Down

0 comments on commit be92035

Please sign in to comment.