aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GlobalLib.cpp2
-rw-r--r--src/Package.cpp168
-rw-r--r--src/main.cpp12
3 files changed, 129 insertions, 53 deletions
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index 0256685..3842388 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -318,7 +318,7 @@ namespace sibs
Result<bool> GlobalLib::downloadDependency(const Dependency &dependency)
{
- Result<string> packageUrlResult = Package::getPackageUrl(dependency.name.c_str(), dependency.version.c_str());
+ Result<string> packageUrlResult = Package::getPackageUrl(dependency.name.c_str(), dependency.version.c_str(), SYSTEM_PLATFORM_NAME);
if(!packageUrlResult)
return Result<bool>::Err(packageUrlResult);
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()));
}
}
diff --git a/src/main.cpp b/src/main.cpp
index d4de6e0..c626f11 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -43,6 +43,18 @@ using namespace std::chrono;
// TODO: Set c++ standard to c++11 and c standard to c98 - for consistency across different compilers and compiler version.
// It should be possible to override language version in project.conf
+// TODO: If file extension is common c extension (.c, ...) then remove cast checking (for example using malloc without casting result to result type)
+
+// TODO: When building a sibs project, add a hardlink in ~/.sibs/lib to it. This allows us to have dependency to a project that we can modify
+// without having to commit & push to remote
+
+// TODO: Check compiler flags generated by cmake and visual studio in debug and release mode and use the same ones when building sibs project.
+// There are certain compiler flags we do not currently have, for example _ITERATOR_DEBUG_LEVEL in debug mode which enables runtime checks.
+// You should be able to specify runtime checks as an option to `sibs build` and project specific config in .conf file.
+// Also add stack protection option. If it's enabled, shouldn't sibs prefer to compile dependencies from source?
+// and should this force static compilation so dependencies can also be built with protection and if dependencies dont exist
+// as static library/source, then fail build?
+
#if OS_FAMILY == OS_FAMILY_POSIX
#define ferr std::cerr
#else