diff --git a/source/dub/dub.d b/source/dub/dub.d index fe5efe4..128b167 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -60,6 +60,7 @@ See_Also: `defaultRegistryURLs` */ +deprecated("This function wasn't intended for public use - open an issue with Dub if you need it") PackageSupplier[] defaultPackageSuppliers() { logDiagnostic("Using dub registry url '%s'", defaultRegistryURLs[0]); @@ -70,6 +71,7 @@ Allowed protocols are dub+http(s):// and maven+http(s)://. */ +deprecated("This function wasn't intended for public use - open an issue with Dub if you need it") PackageSupplier getRegistryPackageSupplier(string url) { switch (url.startsWith("dub+", "mvn+", "file://")) @@ -85,7 +87,7 @@ } } -unittest +deprecated unittest { auto dubRegistryPackageSupplier = getRegistryPackageSupplier("dub+https://code.dlang.org"); assert(dubRegistryPackageSupplier.description.canFind(" https://code.dlang.org")); @@ -320,19 +322,21 @@ { ps ~= registry_var .splitter(";") - .map!(url => getRegistryPackageSupplier(url)) + .map!(url => this.makePackageSupplier(url)) .array; } if (skip < SkipPackageSuppliers.configured) { ps ~= m_config.registryUrls - .map!(url => getRegistryPackageSupplier(url)) + .map!(url => this.makePackageSupplier(url)) .array; } if (skip < SkipPackageSuppliers.standard) - ps ~= defaultPackageSuppliers(); + ps ~= new FallbackPackageSupplier( + defaultRegistryURLs.map!(url => this.makePackageSupplier(url)) + .array); return ps; } @@ -363,6 +367,34 @@ .length == 1); } + /** + * Instantiate a `PackageSupplier` according to a given URL + * + * This is a factory function for `PackageSupplier`. Child classes may + * wish to override this to implement their own `PackageSupplier` logic, + * be it by extending this method's ability or replacing it. + * + * Params: + * url = The URL of the `PackageSupplier`. + * + * Returns: + * A new instance of a `PackageSupplier`. + */ + protected PackageSupplier makePackageSupplier(string url) const + { + switch (url.startsWith("dub+", "mvn+", "file://")) + { + case 1: + return new RegistryPackageSupplier(URL(url[4..$])); + case 2: + return new MavenRegistryPackageSupplier(URL(url[4..$])); + case 3: + return new FileSystemPackageSupplier(NativePath(url[7..$])); + default: + return new RegistryPackageSupplier(URL(url)); + } + } + /// ditto deprecated("This is an implementation detail. " ~ "Use `packageSuppliers` to get the computed list of package " ~ diff --git a/source/dub/test/base.d b/source/dub/test/base.d index 6f7c7b3..4e49876 100644 --- a/source/dub/test/base.d +++ b/source/dub/test/base.d @@ -8,6 +8,9 @@ version (unittest): +import std.array; +public import std.algorithm; + import dub.data.settings; public import dub.dependency; import dub.dub; @@ -50,4 +53,72 @@ // No-op return Settings.init; } + + /// See `MockPackageSupplier` documentation for this class' implementation + protected override PackageSupplier makePackageSupplier(string url) const + { + return new MockPackageSupplier(url); + } +} + +/** + * Implements a `PackageSupplier` that doesn't do any IO + * + * This `PackageSupplier` needs to be pre-loaded with `Package` it can + * find during the setup phase of the unittest. + */ +public class MockPackageSupplier : PackageSupplier +{ + /// Mapping of package name to packages, ordered by `Version` + protected Package[][string] pkgs; + + /// URL this was instantiated with + protected string url; + + /// + public this(string url) + { + this.url = url; + } + + /// + public override @property string description() + { + return "unittest PackageSupplier for: " ~ this.url; + } + + /// + public override Version[] getVersions(string package_id) + { + if (auto ppkgs = package_id in this.pkgs) + return (*ppkgs).map!(pkg => pkg.version_).array; + return null; + } + + /// + public override void fetchPackage( + NativePath path, string package_id, in VersionRange dep, bool pre_release) + { + assert(0, this.url ~ " - fetchPackage not implemented for: " ~ package_id); + } + + /// + public override Json fetchPackageRecipe( + string package_id, in VersionRange dep, bool pre_release) + { + import dub.recipe.json; + + if (auto ppkgs = package_id in this.pkgs) + foreach_reverse (pkg; *ppkgs) + if ((!pkg.version_.isPreRelease || pre_release) && + dep.matches(pkg.version_)) + return toJson(pkg.recipe); + return Json.init; + } + + /// + public override SearchResult[] searchPackages(string query) + { + assert(0, this.url ~ " - searchPackages not implemented for: " ~ query); + } }