bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, std::vector<std::string>& preDeps, CAddonDatabase &database, std::pair<std::string, std::string> &failedDep) { if (addon == NULL) return true; // a NULL addon has no dependencies if (!database.Open()) return false; for (const auto& it : addon->GetDependencies()) { const std::string &addonID = it.id; const AddonVersion &version = it.requiredVersion; bool optional = it.optional; AddonPtr dep; bool haveAddon = CServiceBroker::GetAddonMgr().GetAddon(addonID, dep); if ((haveAddon && !dep->MeetsVersion(version)) || (!haveAddon && !optional)) { // we have it but our version isn't good enough, or we don't have it and we need it if (!database.GetAddon(addonID, dep) || !dep->MeetsVersion(version)) { // we don't have it in a repo, or we have it but the version isn't good enough, so dep isn't satisfied. CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.asString().c_str()); database.Close(); // fill in the details of the failed dependency failedDep.first = addonID; failedDep.second = version.asString(); return false; } } // at this point we have our dep, or the dep is optional (and we don't have it) so check that it's OK as well //! @todo should we assume that installed deps are OK? if (dep && std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end()) { preDeps.push_back(dep->ID()); if (!CheckDependencies(dep, preDeps, database, failedDep)) { database.Close(); return false; } } } database.Close(); return true; }
static CVariant Serialize(const AddonPtr& addon) { CVariant variant; variant["addonid"] = addon->ID(); variant["type"] = CAddonInfo::TranslateType(addon->Type(), false); variant["name"] = addon->Name(); variant["version"] = addon->Version().asString(); variant["summary"] = addon->Summary(); variant["description"] = addon->Description(); variant["path"] = addon->Path(); variant["author"] = addon->Author(); variant["thumbnail"] = addon->Icon(); variant["disclaimer"] = addon->Disclaimer(); variant["fanart"] = addon->FanArt(); variant["dependencies"] = CVariant(CVariant::VariantTypeArray); for (const auto& dep : addon->GetDependencies()) { CVariant info(CVariant::VariantTypeObject); info["addonid"] = dep.id; info["version"] = dep.requiredVersion.asString(); info["optional"] = dep.optional; variant["dependencies"].push_back(std::move(info)); } if (addon->Broken().empty()) variant["broken"] = false; else variant["broken"] = addon->Broken(); variant["extrainfo"] = CVariant(CVariant::VariantTypeArray); for (const auto& kv : addon->ExtraInfo()) { CVariant info(CVariant::VariantTypeObject); info["key"] = kv.first; info["value"] = kv.second; variant["extrainfo"].push_back(std::move(info)); } variant["rating"] = -1; return variant; }