aboutsummaryrefslogtreecommitdiff
path: root/src/Package.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Package.cpp')
-rw-r--r--src/Package.cpp168
1 files changed, 116 insertions, 52 deletions
diff --git a/src/Package.cpp b/src/Package.cpp
index c1c00be..a2aaf52 100644
--- a/src/Package.cpp
+++ b/src/Package.cpp
@@ -9,6 +9,83 @@ static Document *packageList = nullptr;
namespace sibs
{
+ // TODO: Use containsPlatform in Conf.hpp instead? dont need a vector of string when we can use vector of enum
+ bool containsPlatform(const vector<string> &supportedPlatforms, const char *platform)
+ {
+ for(const string &supportedPlatform : supportedPlatforms)
+ {
+ if(strcmp(supportedPlatform.c_str(), platform) == 0 || strcmp(supportedPlatform.c_str(), "any") == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ Result<PackageMetadata> getPackageMetadata(Value::ConstObject jsonObj)
+ {
+ const auto &description = jsonObj["description"];
+ if(!description.IsString()) return Result<PackageMetadata>::Err("Expected description to be a string");
+ const auto &version = jsonObj["version"];
+ if(!version.IsString()) return Result<PackageMetadata>::Err("Expected version to be a string");
+ const auto &platforms = jsonObj["platforms"];
+ if(!platforms.IsArray() || platforms.GetArray().Empty()) return Result<PackageMetadata>::Err("Expected platforms to be an array of strings");
+ const auto &urls = jsonObj["urls"];
+ if(!urls.IsArray() || urls.GetArray().Empty()) return Result<PackageMetadata>::Err("Expected urls to be an array of string");
+
+ PackageMetadata packageMetadata;
+ packageMetadata.description.assign(description.GetString(), description.GetStringLength());
+ packageMetadata.version.assign(version.GetString(), version.GetStringLength());
+
+ const auto &platformsArray = platforms.GetArray();
+ packageMetadata.platforms.reserve(platformsArray.Size());
+ for(int i = 0; i < platformsArray.Size(); ++i)
+ {
+ const auto &platformElement = platformsArray[i];
+ if(!platformElement.IsString())
+ return Result<PackageMetadata>::Err("Expected platforms to only contain strings");
+ packageMetadata.platforms.push_back(platformElement.GetString());
+ }
+
+ const auto &urlsArray = urls.GetArray();
+ packageMetadata.urls.reserve(urlsArray.Size());
+ for(int i = 0; i < urlsArray.Size(); ++i)
+ {
+ const auto &urlElement = urlsArray[i];
+ if(!urlElement.IsString())
+ return Result<PackageMetadata>::Err("Expected urls to only contain strings");
+ packageMetadata.urls.push_back(urlElement.GetString());
+ }
+
+ return Result<PackageMetadata>::Ok(packageMetadata);
+ }
+
+ Result<string> getPackageUrl(const PackageMetadata &packageMetadata, const char *packageName, const char *packageVersion, const char *platform)
+ {
+ if(strcmp(packageMetadata.version.c_str(), packageVersion) != 0)
+ {
+ string errMsg = "Package \"";
+ errMsg += packageName;
+ errMsg += "\" does not exist for version \"";
+ errMsg += packageVersion;
+ errMsg += "\"";
+ return Result<string>::Err(errMsg);
+ }
+
+ if(!containsPlatform(packageMetadata.platforms, platform))
+ {
+ string errMsg = "Package \"";
+ errMsg += packageName;
+ errMsg += "\" with version \"";
+ errMsg += packageVersion;
+ errMsg += "\" does not support platform \"";
+ errMsg += platform;
+ errMsg += "\"";
+ return Result<string>::Err(errMsg);
+ }
+
+ return Result<string>::Ok(packageMetadata.urls[0]);
+ }
+
// TODO: Always downloading is fine right now because the package list is small. This should later be modified to use local cache.
// The package file should be stored locally (at ~/.sibs/packages.json) and the version file should also be stored.
// First we check if the version is incorrect and if it, we download the new packages.json file.
@@ -40,75 +117,62 @@ namespace sibs
return Result<Document*>::Ok(packageList);
}
- Result<string> Package::getPackageUrl(const char *packageName, const char *packageVersion)
+ Result<string> Package::getPackageUrl(const char *packageName, const char *packageVersion, const char *platform)
{
Result<Document*> packageList = Package::getPackageList("https://raw.githubusercontent.com/DEC05EBA/sibs_packages/master/packages.json");
if(!packageList)
return Result<string>::Err(packageList);
const Document &packageDoc = *packageList.unwrap();
- const Value &packageMetaData = packageDoc[packageName];
- if(!packageMetaData.IsObject())
- {
- string errMsg = "No package with the name \"";
- errMsg += packageName;
- errMsg += "\" was found";
- return Result<string>::Err(errMsg);
- }
-
- const Value &packageVersions = packageMetaData["versions"];
- if(!packageVersions.IsObject())
- {
- string errMsg = "Package file is corrupt. ";
- errMsg += packageName;
- errMsg += ".versions is not a json object";
- return Result<string>::Err("errMsg");
- }
-
- const Value &package = packageVersions[packageVersion];
- if(!package.IsObject())
- {
- string errMsg = "Package file is corrupt. ";
- errMsg += packageName;
- errMsg += ".versions.";
- errMsg += packageVersion;
- errMsg += " is not a json object";
- return Result<string>::Err(errMsg);
- }
- const Value &packageUrlsValue = package["urls"];
- if(!packageUrlsValue.IsArray())
+ const Value &packageMetaDataJson = packageDoc[packageName];
+ if(packageMetaDataJson.IsObject())
{
- string errMsg = "Package file is corrupt. ";
- errMsg += packageName;
- errMsg += ".versions.";
- errMsg += packageVersion;
- errMsg += ".urls is not a json array";
- return Result<string>::Err(errMsg);
+ Result<PackageMetadata> packageMetadataResult = getPackageMetadata(packageMetaDataJson.GetObject());
+ if(!packageMetadataResult) return Result<string>::Err(packageMetadataResult);
+ return ::sibs::getPackageUrl(packageMetadataResult.unwrap(), packageName, packageVersion, platform);
}
-
- auto packageUrls = packageUrlsValue.GetArray();
- if(packageUrls.Empty())
+ else if(packageMetaDataJson.IsArray())
{
- string errMsg = "Package file is corrupt. ";
+ int i = 0;
+ for(const auto &packageData : packageMetaDataJson.GetArray())
+ {
+ if(!packageData.IsObject())
+ {
+ string errMsg = "Package file is corrupt. ";
+ errMsg += packageName;
+ errMsg += "[";
+ errMsg += to_string(i);
+ errMsg += "] is not an object";
+ return Result<string>::Err(errMsg);
+ }
+
+ Result<PackageMetadata> packageMetadataResult = getPackageMetadata(packageMetaDataJson.GetObject());
+ if(packageMetadataResult)
+ {
+ Result<string> packageUrlResult = ::sibs::getPackageUrl(packageMetadataResult.unwrap(), packageName, packageVersion, platform);
+ if(packageUrlResult)
+ return packageUrlResult;
+ }
+
+ ++i;
+ }
+
+ string errMsg = "Package \"";
errMsg += packageName;
- errMsg += ".versions.";
+ errMsg += "\" with version \"";
errMsg += packageVersion;
- errMsg += ".urls is an empty json array";
+ errMsg += "\" does not exist or does not exist for platform \"";
+ errMsg += platform;
+ errMsg += "\"";
return Result<string>::Err(errMsg);
}
-
- const Value &packageUrlValue = packageUrls[0];
- if(!packageUrlValue.IsString())
+ else
{
- string errMsg = "Package file is corrupt. ";
+ string errMsg = "No package with the name \"";
errMsg += packageName;
- errMsg += ".versions.";
- errMsg += packageVersion;
- errMsg += ".urls[0] is not a string";
+ errMsg += "\" was found";
return Result<string>::Err(errMsg);
}
-
- return Result<std::string>::Ok(string(packageUrlValue.GetString(), packageUrlValue.GetStringLength()));
}
}