blob: c1c00be654e8a6d049dacec2586693c2dd878466 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#include "../include/Package.hpp"
#include "../include/curl.hpp"
#include "../external/rapidjson/error/en.h"
using namespace std;
using namespace rapidjson;
static Document *packageList = nullptr;
namespace sibs
{
// 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.
// We should only check if the package list is up to date once every 10 minute or so (make it configurable in a config file?)
// to improve build performance and reduce server load.
// Or maybe we dont have to do that at all....
Result<Document*> Package::getPackageList(const char *url)
{
if(packageList)
return Result<Document*>::Ok(packageList);
HttpResult httpResult = curl::get(url);
if(!httpResult.success)
return Result<Document*>::Err(httpResult.str, httpResult.httpCode);
Document *doc = new Document();
ParseResult parseResult = doc->Parse(httpResult.str.c_str());
if(!parseResult)
{
string errMsg = "Failed to parse package list json file: ";
errMsg += GetParseError_En(parseResult.Code());
errMsg += " (";
errMsg += to_string(parseResult.Offset());
errMsg += ")";
return Result<Document*>::Err(errMsg);
}
packageList = doc;
return Result<Document*>::Ok(packageList);
}
Result<string> Package::getPackageUrl(const char *packageName, const char *packageVersion)
{
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())
{
string errMsg = "Package file is corrupt. ";
errMsg += packageName;
errMsg += ".versions.";
errMsg += packageVersion;
errMsg += ".urls is not a json array";
return Result<string>::Err(errMsg);
}
auto packageUrls = packageUrlsValue.GetArray();
if(packageUrls.Empty())
{
string errMsg = "Package file is corrupt. ";
errMsg += packageName;
errMsg += ".versions.";
errMsg += packageVersion;
errMsg += ".urls is an empty json array";
return Result<string>::Err(errMsg);
}
const Value &packageUrlValue = packageUrls[0];
if(!packageUrlValue.IsString())
{
string errMsg = "Package file is corrupt. ";
errMsg += packageName;
errMsg += ".versions.";
errMsg += packageVersion;
errMsg += ".urls[0] is not a string";
return Result<string>::Err(errMsg);
}
return Result<std::string>::Ok(string(packageUrlValue.GetString(), packageUrlValue.GetStringLength()));
}
}
|