From 55ab80afe48abb6a66e40e1925c078bbbbf2f35f Mon Sep 17 00:00:00 2001 From: Tobias Pankrath Date: Sat, 14 Mar 2020 17:24:02 +0100 Subject: [PATCH] fetch: allow to fetch dependencies as well Dependency resolution and retrieval is copied from the dub build command. --- source/dub/commandline.d | 41 ++++++++++++++++++++++++++++++++----- source/dub/dub.d | 2 ++ source/dub/packagemanager.d | 21 ++++++++++++++++--- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/source/dub/commandline.d b/source/dub/commandline.d index 9784133de..6bc2fdb82 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -1455,6 +1455,9 @@ class FetchCommand : FetchRemoveCommand { override void prepare(scope CommandArgs args) { super.prepare(args); + args.getopt("shallow", &m_shallow, [ + "do not fetch missing dependencies" + ]); } override int execute(Dub dub, string[] free_args, string[] app_args) @@ -1465,29 +1468,57 @@ class FetchCommand : FetchRemoveCommand { auto location = dub.defaultPlacementLocation; auto name = free_args[0]; + Package pack = fetchMainTarget(dub, location, name); + if (pack && !m_shallow) + { + NativePath registryPath = (){ + import dub.project : PlacementLocation; + final switch (location) { + case PlacementLocation.system: + return PackageManager.repositoryPath(dub.specialDirs.systemSettings, location); + case PlacementLocation.user: + return PackageManager.repositoryPath(dub.specialDirs.localRepository, location); + case PlacementLocation.local: + return PackageManager.repositoryPath(dub.rootPath, location); + } + }(); + dub.packageManager.customCachePaths([registryPath]); + dub.loadPackage(pack.path); + // needs to be after loadPackage, bc otherwise it has no effect + dub.packageManager.disableDefaultSearchPaths(true); + dub.project.reinit(); + dub.upgrade(UpgradeOptions.select); + } + return 0; + } + Package fetchMainTarget(Dub dub, PlacementLocation location, string name) + { FetchOptions fetchOpts; fetchOpts |= FetchOptions.forceBranchUpgrade; - if (m_version.length) dub.fetch(name, Dependency(m_version), location, fetchOpts); + if (m_version.length) + return dub.fetch(name, Dependency(m_version), location, fetchOpts); else if (name.canFind("@", "=")) { const parts = name.splitPackageName; - dub.fetch(parts.name, Dependency(parts.version_), location, fetchOpts); + return dub.fetch(parts.name, Dependency(parts.version_), location, fetchOpts); } else { try { - dub.fetch(name, Dependency(">=0.0.0"), location, fetchOpts); + Package pack = dub.fetch(name, Dependency(">=0.0.0"), location, fetchOpts); logInfo( "Please note that you need to use `dub run ` " ~ "or add it to dependencies of your package to actually use/run it. " ~ "dub does not do actual installation of packages outside of its own ecosystem."); + return pack; } catch(Exception e){ logInfo("Getting a release version failed: %s", e.msg); logInfo("Retry with ~master..."); - dub.fetch(name, Dependency("~master"), location, fetchOpts); + return dub.fetch(name, Dependency("~master"), location, fetchOpts); } } - return 0; } +private: + bool m_shallow; } class InstallCommand : FetchCommand { diff --git a/source/dub/dub.d b/source/dub/dub.d index a08452ed4..7a300f481 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -316,6 +316,8 @@ class Dub { @property inout(PackageManager) packageManager() inout { return m_packageManager; } + @property SpecialDirs specialDirs() const { return m_dirs; } + @property inout(Project) project() inout { return m_project; } /** Returns the default compiler binary to use for building D code. diff --git a/source/dub/packagemanager.d b/source/dub/packagemanager.d index 76c2e0c31..b0273a3e0 100644 --- a/source/dub/packagemanager.d +++ b/source/dub/packagemanager.d @@ -67,13 +67,28 @@ class PackageManager { this(NativePath package_path, NativePath user_path, NativePath system_path, bool refresh_packages = true) { m_repositories = [ - Repository(package_path ~ ".dub/packages/"), - Repository(user_path ~ "packages/"), - Repository(system_path ~ "packages/")]; + Repository(repositoryPath(package_path, PlacementLocation.local)), + Repository(repositoryPath(user_path, PlacementLocation.user)), + Repository(repositoryPath(system_path, PlacementLocation.system)), + ]; if (refresh_packages) refresh(true); } + import dub.project : PlacementLocation; + /* Maps a placement location and path the corresponding repository path */ + static NativePath repositoryPath(NativePath base, PlacementLocation location) + { + with (PlacementLocation) final switch (location) + { + case local: + return base ~ ".dub/packages"; + case user: + case system: + return base ~ "packages/"; + } + } + /** Gets/sets the list of paths to search for local packages. */ @property void searchPath(NativePath[] paths)