Skip to content

Commit f6062d5

Browse files
author
nshaheed
committed
logic to download and check latest manifest version
1 parent 72eefab commit f6062d5

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

include/fetch.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class FetchBase {
3030
fs::path temp_dir, FileType file_type,
3131
string checksum) = 0;
3232
virtual bool fetch_manifest(string url, fs::path dir) = 0;
33+
virtual optional<int> fetch_newest_manifest_version(string url) = 0;
3334
};
3435

3536
class Fetch : public FetchBase {
@@ -42,6 +43,14 @@ class Fetch : public FetchBase {
4243
// download the manifest from a remote host
4344
bool fetch_manifest(string url, fs::path dir);
4445

46+
// ping ccrma servers to find out what is the
47+
// newest available manifest version is. This
48+
// is to allows chump to inform users if there is
49+
// a newer version of chump that will be needed
50+
// to access a new manifest verison, in case
51+
// there is a breaking change to the manifest schema.
52+
optional<int> fetch_newest_manifest_version(string url);
53+
4554
public:
4655
bool isURL(string path);
4756

src/fetch.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,75 @@ bool Fetch::fetch_manifest(std::string url, fs::path dir) {
273273

274274
return true;
275275
}
276+
277+
struct MemoryStruct {
278+
char *memory;
279+
size_t size;
280+
};
281+
282+
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb,
283+
void *userp) {
284+
size_t realsize = size * nmemb;
285+
auto &mem = *static_cast<std::string *>(userp);
286+
mem.append(static_cast<char *>(contents), realsize);
287+
return realsize;
288+
}
289+
290+
optional<int> Fetch::fetch_newest_manifest_version(string url) {
291+
if (!isURL(url)) {
292+
std::cerr << "[chump]: not a URL!" << std::endl;
293+
return {};
294+
}
295+
296+
CURL *curl_handle;
297+
CURLcode res;
298+
299+
std::string chunk;
300+
301+
curl_global_init(CURL_GLOBAL_ALL);
302+
303+
/* init the curl session */
304+
curl_handle = curl_easy_init();
305+
306+
/* specify URL to get */
307+
curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
308+
309+
/* send all data to this function */
310+
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
311+
312+
/* we pass our 'chunk' struct to the callback function */
313+
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &chunk);
314+
315+
/* some servers do not like requests that are made without a user-agent
316+
field, so we provide one */
317+
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
318+
319+
/* get it! */
320+
res = curl_easy_perform(curl_handle);
321+
322+
/* check for errors */
323+
if (res != CURLE_OK) {
324+
fprintf(stderr, "[chump]: failed to fetch latest manifest version: %s\n",
325+
curl_easy_strerror(res));
326+
return {};
327+
}
328+
329+
/* cleanup curl stuff */
330+
curl_easy_cleanup(curl_handle);
331+
332+
// free(chunk.memory);
333+
334+
/* we are done with libcurl, so clean it up */
335+
curl_global_cleanup();
336+
337+
try {
338+
int ver_no = std::stoi(chunk);
339+
return ver_no;
340+
} catch (std::invalid_argument const &ex) {
341+
std::cerr << "[chump]: failed to fetch latest manifest version: "
342+
<< ex.what() << std::endl;
343+
return {};
344+
}
345+
346+
return {};
347+
}

src/manager.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,21 @@ fs::path Manager::install_path(Package pkg) {
470470
}
471471

472472
bool Manager::update_manifest() {
473+
optional<int> newest_manifest_version = fetch->fetch_newest_manifest_version(
474+
"https://chuck.stanford.edu/release/chump/manifest/"
475+
"latest-manifest.version");
476+
477+
if (newest_manifest_version &&
478+
newest_manifest_version.value() > MANIFEST_VERSION_NO) {
479+
std::cerr
480+
<< "[chump] there are newer packages available that this version of "
481+
"chump cannot manage. visit https://chuck.stanford.edu/release/ and "
482+
"install the latest version of chuck (which includes an updated "
483+
"version of chump). once you have done this, rerun chump for the "
484+
"latest, greatest, chumpiest experience available\n";
485+
std::cerr << "[chump] ~~ don't be a lump, update chump ~~\n";
486+
}
487+
473488
// Create a temporary directory to download our manifest to
474489
fs::path temp_dir = {fs::temp_directory_path() /= std::tmpnam(nullptr)};
475490
fs::create_directory(temp_dir);
@@ -478,7 +493,7 @@ bool Manager::update_manifest() {
478493
bool result = fetch->fetch_manifest(manifest_url, temp_dir);
479494

480495
if (!result) {
481-
std::cerr << "[chump]: failed to fetch manifest.json, exiting."
496+
std::cerr << "[chump]: failed to fetch manifest.json, continuing..."
482497
<< std::endl;
483498
return false;
484499
}

0 commit comments

Comments
 (0)