diff --git a/source/app.d b/source/app.d
index eaf2bf4..da23361 100644
--- a/source/app.d
+++ b/source/app.d
@@ -146,7 +146,7 @@
dub.loadPackageFromCwd();
logInfo("Upgrading project in %s", dub.projectPath.toNativeString());
logDebug("dub initialized");
- dub.update(UpdateOptions.Reinstall | (annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None));
+ dub.update(UpdateOptions.Upgrade | (annotate ? UpdateOptions.JustAnnotate : UpdateOptions.None));
return 0;
case "install":
enforce(args.length >= 2, "Missing package name.");
@@ -188,16 +188,18 @@
enforce(args.length >= 2, "Missing path to package.");
dub.removeLocalPackage(args[1], install_system);
break;
- case "list-locals":
- case "list-system":
- case "list-user":
- auto toList = cmd == "list-locals"? InstallLocation.local
- : cmd == "list-system"? InstallLocation.systemWide
- : InstallLocation.userWide;
- logInfo(cmd == "list-locals"? "Locals:" : cmd == "list-system"? "System:" : "User:");
- foreach( p; dub.packageManager.getPackageIterator() )
- if( p.installLocation == toList)
- logInfo(" %s %s: %s", p.name, p.ver, p.path.toNativeString());
+ case "add-path":
+ enforce(args.length >= 2, "Missing search path.");
+ dub.addSearchPath(args[1], install_system);
+ break;
+ case "remove-path":
+ enforce(args.length >= 2, "Missing search path.");
+ dub.removeSearchPath(args[1], install_system);
+ break;
+ case "list-installed":
+ logInfo("Installed packages:");
+ foreach (p; dub.packageManager.getPackageIterator())
+ logInfo(" %s %s: %s", p.name, p.ver, p.path.toNativeString());
logInfo("");
break;
case "run":
@@ -322,9 +324,7 @@
add-local
Adds a local package directory (e.g. a git repository)
remove-local Removes a local package directory
- list-locals Prints a list of all locals
- list-system Prints a list of all system wide installed packages.
- list-user Prints a list of all user installed packages.
+ list-installed Prints a list of all installed packages
generate Generates project files using the specified generator:
visuald, mono-d, build, rdmd
describe Prints a JSON description of the project and its
diff --git a/source/dub/dub.d b/source/dub/dub.d
index 0631d79..a207041 100644
--- a/source/dub/dub.d
+++ b/source/dub/dub.d
@@ -50,12 +50,12 @@
/// dependencies up and running. An instance manages one application.
class Dub {
private {
- Path m_cwd, m_tempPath;
- Path m_root;
+ PackageManager m_packageManager;
PackageSupplier[] m_packageSuppliers;
+ Path m_cwd, m_tempPath;
Path m_userDubPath, m_systemDubPath;
Json m_systemConfig, m_userConfig;
- PackageManager m_packageManager;
+ Path m_projectPath;
Project m_project;
}
@@ -79,14 +79,15 @@
m_systemConfig = jsonFromFile(m_systemDubPath ~ "settings.json", true);
m_packageSuppliers = ps;
- m_packageManager = new PackageManager(m_systemDubPath ~ "packages/", m_userDubPath ~ "packages/");
+ m_packageManager = new PackageManager(m_userDubPath, m_systemDubPath);
+ updatePackageSearchPath();
}
/// Returns the name listed in the package.json of the current
/// application.
@property string projectName() const { return m_project.name; }
- @property Path projectPath() const { return m_root; }
+ @property Path projectPath() const { return m_projectPath; }
@property string[] configurations() const { return m_project.configurations; }
@@ -99,9 +100,9 @@
void loadPackage(Path path)
{
- m_root = path;
- m_packageManager.projectPackagePath = m_root ~ ".dub/packages/";
- m_project = new Project(m_packageManager, m_root);
+ m_projectPath = path;
+ updatePackageSearchPath();
+ m_project = new Project(m_packageManager, m_projectPath);
}
string getDefaultConfiguration(BuildPlatform platform) const { return m_project.getDefaultConfiguration(platform); }
@@ -202,16 +203,24 @@
enforce(pinfo.type != Json.Type.Undefined, "No package "~packageId~" was found matching the dependency "~dep.toString());
string ver = pinfo["version"].get!string;
- if( auto pack = m_packageManager.getPackage(packageId, ver, location) ){
+ Path install_path;
+ final switch (location) {
+ case InstallLocation.local: install_path = m_cwd; break;
+ case InstallLocation.projectLocal: install_path = m_project.mainPackage.path ~ ".dub/packages/"; break;
+ case InstallLocation.userWide: install_path = m_userDubPath ~ "packages/"; break;
+ case InstallLocation.systemWide: install_path = m_systemDubPath ~ "packages/"; break;
+ }
+
+ if( auto pack = m_packageManager.getPackage(packageId, ver, install_path) ){
logInfo("Package %s %s (%s) is already installed with the latest version, skipping upgrade.",
- packageId, ver, location);
+ packageId, ver, install_path);
return pack;
}
logInfo("Downloading %s %s...", packageId, ver);
logDebug("Acquiring package zip file");
- auto dload = m_root ~ ".dub/temp/downloads";
+ auto dload = m_projectPath ~ ".dub/temp/downloads";
auto tempfname = packageId ~ "-" ~ (ver.startsWith('~') ? ver[1 .. $] : ver) ~ ".zip";
auto tempFile = m_tempPath ~ tempfname;
string sTempFile = tempFile.toNativeString();
@@ -220,7 +229,10 @@
scope(exit) remove(sTempFile);
logInfo("Installing %s %s...", packageId, ver);
- return m_packageManager.install(tempFile, pinfo, location);
+ auto clean_package_version = ver[ver.startsWith("~") ? 1 : 0 .. $];
+ Path dstpath = install_path ~ (packageId ~ "-" ~ clean_package_version);
+
+ return m_packageManager.install(tempFile, pinfo, dstpath);
}
/// Uninstalls a given package from the list of installed modules.
@@ -247,7 +259,7 @@
/// Note: as wildcard string only "*" is supported.
/// @param location_
void uninstall(string package_id, string version_, InstallLocation location_) {
- enforce(!package_id.empty);
+ /+enforce(!package_id.empty);
Package[] packages;
const bool wildcardOrEmpty = version_ == UninstallVersionWildcard || version_.empty;
if(location_ == InstallLocation.local) {
@@ -290,21 +302,27 @@
logInfo("Uninstalled %s, version %s.", package_id, pack.vers);
}
catch logError("Failed to uninstall %s, version %s. Continuing with other packages (if any).", package_id, pack.vers);
- }
+ }+/
}
void addLocalPackage(string path, string ver, bool system)
{
- auto abs_path = Path(path);
- if( !abs_path.absolute ) abs_path = m_cwd ~ abs_path;
- m_packageManager.addLocalPackage(abs_path, Version(ver), system ? LocalPackageType.system : LocalPackageType.user);
+ m_packageManager.addLocalPackage(makeAbsolute(path), Version(ver), system ? LocalPackageType.system : LocalPackageType.user);
}
void removeLocalPackage(string path, bool system)
{
- auto abs_path = Path(path);
- if( !abs_path.absolute ) abs_path = m_cwd ~ abs_path;
- m_packageManager.removeLocalPackage(abs_path, system ? LocalPackageType.system : LocalPackageType.user);
+ m_packageManager.removeLocalPackage(makeAbsolute(path), system ? LocalPackageType.system : LocalPackageType.user);
+ }
+
+ void addSearchPath(string path, bool system)
+ {
+ m_packageManager.addSearchPath(makeAbsolute(path), system ? LocalPackageType.system : LocalPackageType.user);
+ }
+
+ void removeSearchPath(string path, bool system)
+ {
+ m_packageManager.removeSearchPath(makeAbsolute(path), system ? LocalPackageType.system : LocalPackageType.user);
}
void createEmptyPackage(Path path)
@@ -405,4 +423,16 @@
else commands ~= "cp -r "~dub_path~"public/* docs/";
runCommands(commands);
}
+
+ private void updatePackageSearchPath()
+ {
+ auto p = environment.get("DUBPATH");
+ Path[] paths;
+ version(Windows) if (p.length) paths ~= p.split(":").map!(p => Path(p))().array();
+ else if (p.length) paths ~= p.split(";").map!(p => Path(p))().array();
+ m_packageManager.searchPath = paths;
+ }
+
+ private Path makeAbsolute(Path p) const { return p.absolute ? p : m_cwd ~ p; }
+ private Path makeAbsolute(string p) const { return makeAbsolute(Path(p)); }
}
diff --git a/source/dub/package_.d b/source/dub/package_.d
index ed9a4c1..83fdf06 100644
--- a/source/dub/package_.d
+++ b/source/dub/package_.d
@@ -50,19 +50,17 @@
static struct LocalPackageDef { string name; Version version_; Path path; }
private {
- InstallLocation m_location;
Path m_path;
PackageInfo m_info;
}
- this(InstallLocation location, Path root)
+ this(Path root)
{
- this(jsonFromFile(root ~ PackageJsonFilename), location, root);
+ this(jsonFromFile(root ~ PackageJsonFilename), root);
}
- this(Json packageInfo, InstallLocation location = InstallLocation.local, Path root = Path())
+ this(Json packageInfo, Path root = Path())
{
- m_location = location;
m_path = root;
// check for default string import folders
@@ -90,6 +88,28 @@
{
scope(failure) logError("Failed to parse package description in %s", root.toNativeString());
m_info.parseJson(packageInfo);
+
+ // try to run git to determine the version of the package if no explicit version was given
+ if (m_info.version_.length == 0) {
+ import dub.internal.std.process;
+ try {
+ auto branch = execute(["git", "--git-dir="~(root~".git").toNativeString(), "rev-parse", "--abbrev-ref", "HEAD"]);
+ enforce(branch.status == 0, "git rev-parse failed: " ~ branch.output);
+ if (branch.output.strip() == "HEAD") {
+ //auto ver = execute("git",)
+ enforce(false, "oops");
+ } else {
+ m_info.version_ = "~" ~ branch.output.strip();
+ }
+ } catch (Exception e) {
+ logDebug("Failed to run git: %s", e.msg);
+ }
+
+ if (m_info.version_.length == 0) {
+ logDebug("Failed to determine version of package %s at %s. Assuming ~master.", m_info.name, this.path.toNativeString());
+ m_info.version_ = "~master";
+ } else logDebug("Determined package version using GIT: %s %s", m_info.name, m_info.version_);
+ }
}
// generate default configurations if none are defined
@@ -119,7 +139,6 @@
@property string vers() const { return m_info.version_; }
@property Version ver() const { return Version(m_info.version_); }
@property const(PackageInfo) info() const { return m_info; }
- @property installLocation() const { return m_location; }
@property Path path() const { return m_path; }
@property Path packageInfoFile() const { return m_path ~ "package.json"; }
@property const(Dependency[string]) dependencies() const { return m_info.dependencies; }
diff --git a/source/dub/packagemanager.d b/source/dub/packagemanager.d
index f20bea9..4305907 100644
--- a/source/dub/packagemanager.d
+++ b/source/dub/packagemanager.d
@@ -17,6 +17,7 @@
import dub.utils;
import std.algorithm : countUntil, filter, sort, canFind;
+import std.array;
import std.conv;
import std.digest.sha;
import std.exception;
@@ -28,8 +29,21 @@
enum JournalJsonFilename = "journal.json";
enum LocalPackagesFilename = "local-packages.json";
+
+private struct Repository {
+ Path path;
+ Path packagePath;
+ Path[] searchPath;
+ Package[] localPackages;
+
+ this(Path path)
+ {
+ this.path = path;
+ this.packagePath = path ~"packages/";
+ }
+}
+
enum LocalPackageType {
- temporary,
user,
system
}
@@ -37,27 +51,32 @@
class PackageManager {
private {
- Path m_systemPackagePath;
- Path m_userPackagePath;
- Path m_projectPackagePath;
- Package[][string] m_systemPackages;
- Package[][string] m_userPackages;
- Package[string] m_projectPackages;
- Package[] m_localTemporaryPackages;
- Package[] m_localUserPackages;
- Package[] m_localSystemPackages;
+ Repository[LocalPackageType] m_repositories;
+ Path[] m_searchPath;
+ Package[][string] m_packages;
+ Package[] m_temporaryPackages;
}
- this(Path system_package_path, Path user_package_path, Path project_package_path = Path())
+ this(Path user_path, Path system_path)
{
- m_systemPackagePath = system_package_path;
- m_userPackagePath = user_package_path;
- m_projectPackagePath = project_package_path;
+ m_repositories[LocalPackageType.user] = Repository(user_path);
+ m_repositories[LocalPackageType.system] = Repository(system_path);
refresh();
}
- @property Path projectPackagePath() const { return m_projectPackagePath; }
- @property void projectPackagePath(Path path) { m_projectPackagePath = path; refresh(); }
+ @property void searchPath(Path[] paths) { m_searchPath = paths.dup; refresh(); }
+ @property const(Path)[] searchPath() const { return m_searchPath; }
+
+ @property const(Path)[] completeSearchPath()
+ const {
+ auto ret = appender!(Path[])();
+ ret.put(m_searchPath);
+ ret.put(m_repositories[LocalPackageType.user].searchPath);
+ ret.put(m_repositories[LocalPackageType.user].packagePath);
+ ret.put(m_repositories[LocalPackageType.system].searchPath);
+ ret.put(m_repositories[LocalPackageType.system].packagePath);
+ return ret.data;
+ }
Package getPackage(string name, Version ver)
{
@@ -67,10 +86,22 @@
return null;
}
- Package getPackage(string name, string ver, InstallLocation location)
+ Package getPackage(string name, string ver, Path in_path)
{
- foreach(ep; getPackageIterator(name)){
- if( ep.installLocation == location && ep.vers == ver )
+ return getPackage(name, Version(ver), in_path);
+ }
+ Package getPackage(string name, Version ver, Path in_path)
+ {
+ foreach( p; getPackageIterator(name) )
+ if (p.ver == ver && p.path.startsWith(in_path))
+ return p;
+ return null;
+ }
+
+ Package getPackage(string name, string ver)
+ {
+ foreach (ep; getPackageIterator(name)) {
+ if (ep.vers == ver)
return ep;
}
return null;
@@ -94,32 +125,19 @@
{
int iterator(int delegate(ref Package) del)
{
- // first search project local packages
- foreach( p; m_localTemporaryPackages )
- if( auto ret = del(p) ) return ret;
- foreach( p; m_projectPackages )
- if( auto ret = del(p) ) return ret;
+ foreach (tp; m_temporaryPackages)
+ if (auto ret = del(tp)) return ret;
- // then local packages
- foreach( p; m_localUserPackages )
- if( auto ret = del(p) ) return ret;
+ // first search local packages
+ foreach (tp; LocalPackageType.min .. LocalPackageType.max+1)
+ foreach (p; m_repositories[cast(LocalPackageType)tp].localPackages)
+ if (auto ret = del(p)) return ret;
- // then local packages
- foreach( p; m_localSystemPackages )
- if( auto ret = del(p) ) return ret;
-
- // then user installed packages
- foreach( pl; m_userPackages )
+ // and then all packages gathered from the search path
+ foreach( pl; m_packages )
foreach( v; pl )
if( auto ret = del(v) )
return ret;
-
- // finally system-wide installed packages
- foreach( pl; m_systemPackages )
- foreach( v; pl )
- if( auto ret = del(v) )
- return ret;
-
return 0;
}
@@ -130,57 +148,23 @@
{
int iterator(int delegate(ref Package) del)
{
- // first search project local packages
- foreach( p; m_localTemporaryPackages )
- if( p.name == name )
- if( auto ret = del(p) ) return ret;
- if( auto pp = name in m_projectPackages )
- if( auto ret = del(*pp) ) return ret;
-
- // then local packages
- foreach( p; m_localUserPackages )
- if( p.name == name )
- if( auto ret = del(p) ) return ret;
-
- // then local packages
- foreach( p; m_localSystemPackages )
- if( p.name == name )
- if( auto ret = del(p) ) return ret;
-
- // then user installed packages
- if( auto pp = name in m_userPackages )
- foreach( v; *pp )
- if( auto ret = del(v) )
- return ret;
-
- // finally system-wide installed packages
- if( auto pp = name in m_systemPackages )
- foreach( v; *pp )
- if( auto ret = del(v) )
- return ret;
-
+ foreach (p; getPackageIterator())
+ if (p.name == name)
+ if (auto ret = del(p)) return ret;
return 0;
}
return &iterator;
}
- Package install(Path zip_file_path, Json package_info, InstallLocation location)
+ Package install(Path zip_file_path, Json package_info, /*InstallLocation location*/Path destination)
{
auto package_name = package_info.name.get!string();
auto package_version = package_info["version"].get!string();
auto clean_package_version = package_version[package_version.startsWith("~") ? 1 : 0 .. $];
logDebug("Installing package '%s' version '%s' to location '%s' from file '%s'",
- package_name, package_version, to!string(location), zip_file_path.toNativeString());
-
- Path destination;
- final switch( location ){
- case InstallLocation.local: destination = Path(package_name); break;
- case InstallLocation.projectLocal: enforce(!m_projectPackagePath.empty, "no project path set."); destination = m_projectPackagePath ~ package_name; break;
- case InstallLocation.userWide: destination = m_userPackagePath ~ (package_name ~ "/" ~ clean_package_version); break;
- case InstallLocation.systemWide: destination = m_systemPackagePath ~ (package_name ~ "/" ~ clean_package_version); break;
- }
+ package_name, package_version, destination.toNativeString(), zip_file_path.toNativeString());
if( existsFile(destination) ){
throw new Exception(format("%s %s needs to be uninstalled prior installation.", package_name, package_version));
@@ -262,21 +246,16 @@
if( existsFile(destination~PackageJsonFilename) )
logInfo("%s has been installed with version %s", package_name, package_version);
- auto pack = new Package(location, destination);
+ auto pack = new Package(destination);
- final switch( location ){
- case InstallLocation.local: break;
- case InstallLocation.projectLocal: m_projectPackages[package_name] = pack; break;
- case InstallLocation.userWide: m_userPackages[package_name] ~= pack; break;
- case InstallLocation.systemWide: m_systemPackages[package_name] ~= pack; break;
- }
+ m_packages[package_name] ~= pack;
return pack;
}
void uninstall(in Package pack)
{
- logTrace("Uninstall %s, version %s, path '%s'", pack.name, pack.vers, pack.path);
+ /+logTrace("Uninstall %s, version %s, path '%s'", pack.name, pack.vers, pack.path);
enforce(!pack.path.empty, "Cannot uninstall package "~pack.name~" without a path.");
// remove package from package list
@@ -356,12 +335,12 @@
throw new Exception("Alien files found in '"~pack.path.toNativeString()~"', needs to be deleted manually.");
rmdir(pack.path.toNativeString());
- logInfo("Uninstalled package: '"~pack.name~"'");
+ logInfo("Uninstalled package: '"~pack.name~"'");+/
}
Package addLocalPackage(in Path path, in Version ver, LocalPackageType type)
{
- Package[]* packs = getLocalPackageList(type);
+ Package[]* packs = &m_repositories[type].localPackages;
auto info = jsonFromFile(path ~ PackageJsonFilename, false);
string name;
if( "name" !in info ) info["name"] = path.head.toString();
@@ -375,7 +354,7 @@
}
}
- auto pack = new Package(info, InstallLocation.local, path);
+ auto pack = new Package(info, path);
*packs ~= pack;
@@ -386,7 +365,7 @@
void removeLocalPackage(in Path path, LocalPackageType type)
{
- Package[]* packs = getLocalPackageList(type);
+ Package[]* packs = &m_repositories[type].localPackages;
size_t[] to_remove;
foreach( i, entry; *packs )
if( entry.path == path )
@@ -399,60 +378,38 @@
writeLocalPackageList(type);
}
+ Package addTemporaryPackage(Path path, Version ver)
+ {
+ auto info = jsonFromFile(path ~ PackageJsonFilename, false);
+ string name;
+ if( "name" !in info ) info["name"] = path.head.toString();
+ info["version"] = ver.toString();
+
+ auto pack = new Package(info, path);
+ m_temporaryPackages ~= pack;
+ return pack;
+ }
+
+ void addSearchPath(Path path, LocalPackageType type)
+ {
+ m_repositories[type].searchPath ~= path;
+ writeLocalPackageList(type);
+ }
+
+ void removeSearchPath(Path path, LocalPackageType type)
+ {
+ m_repositories[type].searchPath = m_repositories[type].searchPath.filter!(p => p != path)().array();
+ writeLocalPackageList(type);
+ }
+
void refresh()
{
- // rescan the system and user package folder
- void scanPackageFolder(Path path, ref Package[][string] packs, InstallLocation location)
- {
- packs = null;
- if( path.existsDirectory() ){
- logDebug("iterating dir %s", path.toNativeString());
- try foreach( pdir; iterateDirectory(path) ){
- logDebug("iterating dir %s entry %s", path.toNativeString(), pdir.name);
- if( !pdir.isDirectory ) continue;
- Package[] vers;
- auto pack_path = path ~ pdir.name;
- foreach( vdir; iterateDirectory(pack_path) ){
- if( !vdir.isDirectory ) continue;
- auto ver_path = pack_path ~ vdir.name;
- if( !existsFile(ver_path ~ PackageJsonFilename) ) continue;
- try {
- auto p = new Package(location, ver_path);
- vers ~= p;
- } catch( Exception e ){
- logError("Failed to load package in %s: %s", ver_path, e.msg);
- }
- }
- packs[pdir.name] = vers;
- }
- catch(Exception e) logDebug("Failed to enumerate %s packages: %s", location, e.toString());
- }
- }
- scanPackageFolder(m_systemPackagePath, m_systemPackages, InstallLocation.systemWide);
- scanPackageFolder(m_userPackagePath, m_userPackages, InstallLocation.userWide);
-
-
- // rescan the project package folder
- m_projectPackages = null;
- if( !m_projectPackagePath.empty && m_projectPackagePath.existsDirectory() ){
- logDebug("iterating dir %s", m_projectPackagePath.toNativeString());
- try foreach( pdir; m_projectPackagePath.iterateDirectory() ){
- if( !pdir.isDirectory ) continue;
- auto pack_path = m_projectPackagePath ~ pdir.name;
- if( !existsFile(pack_path ~ PackageJsonFilename) ) continue;
-
- try {
- auto p = new Package(InstallLocation.projectLocal, pack_path);
- m_projectPackages[pdir.name] = p;
- } catch( Exception e ){
- logError("Failed to load package in %s: %s", pack_path, e.msg);
- }
- }
- catch(Exception e) logDebug("Failed to enumerate project packages: %s", e.toString());
- }
-
// load locally defined packages
- void scanLocalPackages(Path list_path, ref Package[] packs){
+ void scanLocalPackages(LocalPackageType type)
+ {
+ Path list_path = m_repositories[type].packagePath;
+ Package[] packs;
+ Path[] paths;
try {
logDebug("Looking for local package map at %s", list_path.toNativeString());
if( !existsFile(list_path ~ LocalPackagesFilename) ) return;
@@ -462,16 +419,20 @@
foreach( pentry; packlist ){
try {
auto name = pentry.name.get!string();
- auto ver = pentry["version"].get!string();
auto path = Path(pentry.path.get!string());
- auto info = Json.EmptyObject;
- if( existsFile(path ~ PackageJsonFilename) ) info = jsonFromFile(path ~ PackageJsonFilename);
- if( "name" in info && info.name.get!string() != name )
- logWarn("Local package at %s has different name than %s (%s)", path.toNativeString(), name, info.name.get!string());
- info.name = name;
- info["version"] = ver;
- auto pp = new Package(info, InstallLocation.local, path);
- packs ~= pp;
+ if (name == "*") {
+ paths ~= path;
+ } else {
+ auto ver = pentry["version"].get!string();
+ auto info = Json.EmptyObject;
+ if( existsFile(path ~ PackageJsonFilename) ) info = jsonFromFile(path ~ PackageJsonFilename);
+ if( "name" in info && info.name.get!string() != name )
+ logWarn("Local package at %s has different name than %s (%s)", path.toNativeString(), name, info.name.get!string());
+ info.name = name;
+ info["version"] = ver;
+ auto pp = new Package(info, path);
+ packs ~= pp;
+ }
} catch( Exception e ){
logWarn("Error adding local package: %s", e.msg);
}
@@ -479,9 +440,37 @@
} catch( Exception e ){
logDebug("Loading of local package list at %s failed: %s", list_path.toNativeString(), e.msg);
}
+ m_repositories[type].localPackages = packs;
+ m_repositories[type].searchPath = paths;
}
- scanLocalPackages(m_systemPackagePath, m_localSystemPackages);
- scanLocalPackages(m_userPackagePath, m_localUserPackages);
+ scanLocalPackages(LocalPackageType.system);
+ scanLocalPackages(LocalPackageType.user);
+
+ // rescan the system and user package folder
+ void scanPackageFolder(Path path)
+ {
+ if( path.existsDirectory() ){
+ logTrace("iterating dir %s", path.toNativeString());
+ try foreach( pdir; iterateDirectory(path) ){
+ logTrace("iterating dir %s entry %s", path.toNativeString(), pdir.name);
+ if( !pdir.isDirectory ) continue;
+ auto pack_path = path ~ pdir.name;
+ if( !existsFile(pack_path ~ PackageJsonFilename) ) continue;
+ Package p;
+ try {
+ p = new Package(pack_path);
+ m_packages[p.name] ~= p;
+ } catch( Exception e ){
+ logError("Failed to load package in %s: %s", pack_path, e.msg);
+ }
+ }
+ catch(Exception e) logDebug("Failed to enumerate %s packages: %s", path.toNativeString(), e.toString());
+ }
+ }
+
+ m_packages = null;
+ foreach (p; this.completeSearchPath)
+ scanPackageFolder(p);
}
alias ubyte[] Hash;
@@ -514,20 +503,17 @@
return hash[0..$];
}
- private Package[]* getLocalPackageList(LocalPackageType type)
- {
- final switch(type){
- case LocalPackageType.user: return &m_localUserPackages;
- case LocalPackageType.system: return &m_localSystemPackages;
- case LocalPackageType.temporary: return &m_localTemporaryPackages;
- }
- }
-
private void writeLocalPackageList(LocalPackageType type)
{
- Package[]* packs = getLocalPackageList(type);
Json[] newlist;
- foreach( p; *packs ){
+ foreach (p; m_repositories[type].searchPath) {
+ auto entry = Json.EmptyObject;
+ entry.name = "*";
+ entry.path = p.toNativeString();
+ newlist ~= entry;
+ }
+
+ foreach (p; m_repositories[type].localPackages) {
auto entry = Json.EmptyObject;
entry["name"] = p.name;
entry["version"] = p.ver.toString();
@@ -535,12 +521,7 @@
newlist ~= entry;
}
- Path path;
- final switch(type){
- case LocalPackageType.user: path = m_userPackagePath; break;
- case LocalPackageType.system: path = m_systemPackagePath; break;
- case LocalPackageType.temporary: return;
- }
+ Path path = m_repositories[type].packagePath;
if( !existsDirectory(path) ) mkdirRecurse(path.toNativeString());
writeJsonFile(path ~ LocalPackagesFilename, Json(newlist));
}
diff --git a/source/dub/project.d b/source/dub/project.d
index c7c0b82..f500908 100644
--- a/source/dub/project.d
+++ b/source/dub/project.d
@@ -146,7 +146,7 @@
{
scope(failure){
logDebug("Failed to initialize project. Assuming defaults.");
- m_main = new Package(serializeToJson(["name": "unknown"]), InstallLocation.local, m_root);
+ m_main = new Package(serializeToJson(["name": "unknown"]), m_root);
}
m_dependencies = null;
@@ -160,11 +160,11 @@
logWarn("There was no '"~PackageJsonFilename~"' found for the application in '%s'.", m_root.toNativeString());
auto json = Json.EmptyObject;
json.name = "unknown";
- m_main = new Package(json, InstallLocation.local, m_root);
+ m_main = new Package(json, m_root);
return;
}
- m_main = new Package(InstallLocation.local, m_root);
+ m_main = new Package(m_root);
m_main.warnOnSpecialCompilerFlags();
if (m_main.name != m_main.name.toLower()) {
logWarn("Package names should always be lower case, please change from '%s' to '%s'!",
@@ -183,7 +183,7 @@
Path path = vspec.path;
if( !path.absolute ) path = pack.path ~ path;
logDebug("Adding local %s %s", path, vspec.version_);
- p = m_packageManager.addLocalPackage(path, vspec.version_, LocalPackageType.temporary);
+ p = m_packageManager.addTemporaryPackage(path, vspec.version_);
} else {
p = m_packageManager.getBestPackage(name, vspec);
}
@@ -262,7 +262,8 @@
/// Actions which can be performed to update the application.
- Action[] determineActions(PackageSupplier[] packageSuppliers, int option) {
+ Action[] determineActions(PackageSupplier[] packageSuppliers, int option)
+ {
scope(exit) writeDubJson();
if(!m_main) {
@@ -301,51 +302,23 @@
installed[p.name] = p;
}
- // To see, which could be uninstalled
- Package[string] unused = installed.dup;
- unused.remove(m_main.name);
// Check against installed and add install actions
Action[] actions;
- Action[] uninstalls;
foreach( string pkg, d; graph.needed() ) {
auto p = pkg in installed;
// TODO: auto update to latest head revision
if(!p || (!d.dependency.matches(p.vers) && !d.dependency.matches(Version.MASTER))) {
- if(!p) logDebug("Application not complete, required package '"~pkg~"', which was not found.");
- else logDebug("Application not complete, required package '"~pkg~"', invalid version. Required '%s', available '%s'.", d.dependency, p.vers);
- actions ~= Action.install(pkg, InstallLocation.projectLocal, d.dependency, d.packages);
+ if(!p) logDebug("Triggering installation of required package '"~pkg~"', which is not installed.");
+ else logDebug("Triggering installation of required package '"~pkg~"', which doesn't match the required versionh. Required '%s', available '%s'.", d.dependency, p.vers);
+ actions ~= Action.install(pkg, InstallLocation.userWide, d.dependency, d.packages);
} else {
logDebug("Required package '"~pkg~"' found with version '"~p.vers~"'");
- if( option & UpdateOptions.Reinstall ) {
- if( p.installLocation != InstallLocation.local ){
- Dependency[string] em;
- // user and system packages are not uninstalled (could be needed by other projects)
- if (p.installLocation == InstallLocation.projectLocal || p.ver.isBranch)
- uninstalls ~= Action.uninstall(*p, em);
- actions ~= Action.install(pkg, p.installLocation, d.dependency, d.packages);
- } else {
- logInfo("Skipping local package %s at %s", p.name, p.path.toNativeString());
- }
- }
-
- if( (pkg in unused) !is null )
- unused.remove(pkg);
+ if( option & UpdateOptions.Upgrade )
+ actions ~= Action.install(pkg, InstallLocation.userWide, d.dependency, d.packages);
}
}
- // Add uninstall actions
- foreach( pname, pkg; unused ){
- if( pkg.installLocation != InstallLocation.projectLocal )
- continue;
- logDebug("Superfluous package found: '"~pname~"', version '"~pkg.vers~"'");
- Dependency[string] em;
- uninstalls ~= Action.uninstall(pkg, em);
- }
-
- // Ugly "uninstall" comes first
- actions = uninstalls ~ actions;
-
return actions;
}
@@ -433,7 +406,8 @@
}
}
- private bool gatherMissingDependencies(PackageSupplier[] packageSuppliers, DependencyGraph graph) {
+ private bool gatherMissingDependencies(PackageSupplier[] packageSuppliers, DependencyGraph graph)
+ {
RequestedDependency[string] missing = graph.missing();
RequestedDependency[string] oldMissing;
while( missing.length > 0 ) {
@@ -477,7 +451,7 @@
if( !p && reqDep.dependency.optional ) continue;
// Try an already installed package first
- if( p && p.installLocation != InstallLocation.local && needsUpToDateCheck(pkg) ){
+ if( p && needsUpToDateCheck(pkg) ){
logInfo("Triggering update of package %s", pkg);
p = null;
}
@@ -611,7 +585,7 @@
{
None = 0,
JustAnnotate = 1<<0,
- Reinstall = 1<<1
+ Upgrade = 1<<1
};