Package dependencies.

This commit is contained in:
James Turner 2013-03-02 15:14:09 +00:00
parent 439041c2f4
commit 413e89c955
5 changed files with 97 additions and 2 deletions

View File

@ -221,6 +221,11 @@ std::string Catalog::description() const
{
return getLocalisedString(m_props, "description");
}
SGPropertyNode* Catalog::properties() const
{
return m_props.ptr();
}
void Catalog::parseTimestamp()
{

View File

@ -65,6 +65,11 @@ public:
Package* getPackageById(const std::string& aId) const;
unsigned int ageInSeconds() const;
/**
* access the raw property data in the catalog
*/
SGPropertyNode* properties() const;
private:
Catalog(Root* aRoot);

View File

@ -2,9 +2,12 @@
#include <simgear/package/Package.hxx>
#include <cassert>
#include <boost/foreach.hpp>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/package/Catalog.hxx>
#include <simgear/package/Install.hxx>
#include <simgear/package/Root.hxx>
@ -93,6 +96,20 @@ unsigned int Package::revision() const
{
return m_props->getIntValue("revision");
}
SGPropertyNode* Package::properties() const
{
return m_props.ptr();
}
string_list Package::thumbnailUrls() const
{
string_list r;
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
r.push_back(dl->getStringValue());
}
return r;
}
string_list Package::downloadUrls() const
{
@ -121,6 +138,40 @@ std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char*
return aRoot->getStringValue(aName);
}
PackageList Package::dependencies() const
{
PackageList result;
BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
std::string depName = dep->getStringValue("package");
unsigned int rev = dep->getIntValue("revision", 0);
// prefer local hangar package if possible, in case someone does something
// silly with naming. Of course flightgear's aircraft search doesn't know
// about hanagrs, so names still need to be unique.
Package* depPkg = m_catalog->getPackageById(depName);
if (!depPkg) {
Root* rt = m_catalog->root();
depPkg = rt->getPackageById(depName);
if (!depPkg) {
throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
}
}
if (depPkg->revision() < rev) {
throw sg_range_exception("Couldn't find suitable revision of " + depName);
}
// forbid recursive dependency graphs, we don't need that level
// of complexity for aircraft resources
assert(depPkg->dependencies() == PackageList());
result.push_back(depPkg);
}
return result;
}
} // of namespace pkg
} // of namespace simgear

View File

@ -18,7 +18,10 @@ namespace pkg
// forward decls
class Install;
class Catalog;
class Package;
typedef std::vector<Package*> PackageList;
class Package
{
public:
@ -31,6 +34,14 @@ public:
std::string id() const;
/**
* access the raw property data in the package
*/
SGPropertyNode* properties() const;
/**
* hex-encoded MD5 sum of the download files
*/
std::string md5() const;
std::string getLocalisedProp(const std::string& aName) const;
@ -42,7 +53,19 @@ public:
bool matches(const SGPropertyNode* aFilter) const;
/**
* download URLs for the package
*/
string_list downloadUrls() const;
string_list thumbnailUrls() const;
/**
* Packages we depend upon.
* If the dependency list cannot be satisifed for some reason,
* this will raise an sg_exception.
*/
PackageList dependencies() const;
private:
friend class Catalog;
@ -57,7 +80,7 @@ private:
Catalog* m_catalog;
};
typedef std::vector<Package*> PackageList;
} // of namespace pkg

View File

@ -162,7 +162,18 @@ std::string Root::getLocale() const
void Root::scheduleToUpdate(Install* aInstall)
{
bool wasEmpty = m_updateDeque.empty();
if (!aInstall) {
sg_exception("missing argument to scheduleToUpdate");
}
PackageList deps = aInstall->package()->dependencies();
BOOST_FOREACH(Package* dep, deps) {
// will internally schedule for update if required
// hence be careful, this method is re-entered in here!
dep->install();
}
bool wasEmpty = m_updateDeque.empty();
m_updateDeque.push_back(aInstall);
if (wasEmpty) {
aInstall->startUpdate();