diff --git a/source/dub/commandline.d b/source/dub/commandline.d index b00220d..759dc45 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -254,8 +254,7 @@ PackageSupplier ps = getRegistryPackageSupplier(urls.front); urls.popFront; if (!urls.empty) - ps = new FallbackPackageSupplier(ps, - urls.map!(u => getRegistryPackageSupplier(u)).array); + ps = new FallbackPackageSupplier(ps ~ urls.map!getRegistryPackageSupplier.array); return ps; }) .array; @@ -309,7 +308,7 @@ args.getopt("skip-registry", &skipRegistry, [ "Sets a mode for skipping the search on certain package registry types:", " none: Search all configured or default registries (default)", - " standard: Don't search the main registry (e.g. "~defaultRegistryURL~")", + " standard: Don't search the main registry (e.g. "~defaultRegistryURLs[0]~")", " configured: Skip all default and user configured registries", " all: Only search registries specified with --registry", ]); diff --git a/source/dub/dub.d b/source/dub/dub.d index f6e3682..4dd013c 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -59,9 +59,11 @@ registerCompiler(new LDCCompiler); } -/// The URL to the official package registry. -enum defaultRegistryURL = "https://code.dlang.org/"; -enum fallbackRegistryURLs = [ +deprecated("use defaultRegistryURLs") enum defaultRegistryURL = defaultRegistryURLs[0]; + +/// The URL to the official package registry and it's default fallback registries. +enum defaultRegistryURLs = [ + "https://code.dlang.org/", // fallback in case of HTTPS problems "http://code.dlang.org/", "https://code-mirror.dlang.io/", @@ -74,17 +76,12 @@ This will contain a single package supplier that points to the official package registry. - See_Also: `defaultRegistryURL` + See_Also: `defaultRegistryURLs` */ PackageSupplier[] defaultPackageSuppliers() { - logDiagnostic("Using dub registry url '%s'", defaultRegistryURL); - return [ - new FallbackPackageSupplier( - new RegistryPackageSupplier(URL(defaultRegistryURL)), - fallbackRegistryURLs.map!(x => cast(PackageSupplier) new RegistryPackageSupplier(URL(x))).array - ) - ]; + logDiagnostic("Using dub registry url '%s'", defaultRegistryURLs[0]); + return [new FallbackPackageSupplier(defaultRegistryURLs.map!getRegistryPackageSupplier.array)]; } /** Returns a registry package supplier according to protocol. diff --git a/source/dub/packagesuppliers/fallback.d b/source/dub/packagesuppliers/fallback.d index 7a691a9..0fabba3 100644 --- a/source/dub/packagesuppliers/fallback.d +++ b/source/dub/packagesuppliers/fallback.d @@ -5,20 +5,19 @@ package abstract class AbstractFallbackPackageSupplier : PackageSupplier { - protected PackageSupplier m_default; - protected PackageSupplier[] m_fallbacks; + protected PackageSupplier[] m_suppliers; - this(PackageSupplier default_, PackageSupplier[] fallbacks) + this(PackageSupplier[] suppliers) { - m_default = default_; - m_fallbacks = fallbacks; + assert(suppliers.length); + m_suppliers = suppliers; } override @property string description() { import std.algorithm.iteration : map; import std.format : format; - return format("%s (fallback %s)", m_default.description, m_fallbacks.map!(x => x.description)); + return format("%s (fallbacks %-(%s, %))", m_suppliers[0].description, m_suppliers[1 .. $].map!(x => x.description)); } // Workaround https://issues.dlang.org/show_bug.cgi?id=2525 @@ -40,19 +39,33 @@ { import std.format : format; enum fallback = q{ - import std.range : back, dropBackOne; - import dub.internal.vibecompat.core.log : logDebug; - scope (failure) + import dub.internal.vibecompat.core.log : logDiagnostic; + + Exception firstEx; + try + return m_suppliers[0].%1$s(args); + catch (Exception e) { - foreach (m_fallback; m_fallbacks.dropBackOne) - { - try - return m_fallback.%1$s(args); - catch(Exception) - logDebug("Package supplier %s failed. Trying next fallback.", m_fallback); - } - return m_fallbacks.back.%1$s(args); + logDiagnostic("Package supplier %%s failed with '%%s', trying fallbacks.", + m_suppliers[0].description, e.msg); + m_suppliers = m_suppliers[1 .. $]; + firstEx = e; } - return m_default.%1$s(args); + + foreach (fallback; m_suppliers) + { + try + { + scope (success) logDiagnostic("Fallback %%s succeeded", fallback.description); + return fallback.%1$s(args); + } + catch(Exception e) + { + logDiagnostic("Fallback package supplier %%s failed with '%%s'.", + fallback.description, e.msg); + m_suppliers = m_suppliers[1 .. $]; + } + } + throw firstEx; }.format(__traits(identifier, func)); }