Skip to content

Commit bdb7199

Browse files
authored
Notifying the user if new version is available (#217)
* Notifying the user if new version is available #213
1 parent aa0bfc7 commit bdb7199

File tree

7 files changed

+118
-6
lines changed

7 files changed

+118
-6
lines changed

deps/http-get/clib.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "http-get",
3-
"version": "0.2.2",
3+
"version": "0.3.0",
44
"repo": "clibs/http-get.c",
55
"description": "Simple HTTP GET requests backed by libcurl",
66
"keywords": [
@@ -14,4 +14,4 @@
1414
"src/http-get.c",
1515
"src/http-get.h"
1616
]
17-
}
17+
}

deps/http-get/http-get.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ http_get_response_t *http_get_shared(const char *url, CURLSH *share) {
5555
curl_easy_setopt(req, CURLOPT_FOLLOWLOCATION, 1);
5656
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, http_get_cb);
5757
curl_easy_setopt(req, CURLOPT_WRITEDATA, (void *) res);
58+
curl_easy_setopt(req, CURLOPT_USERAGENT, "http-get.c/"HTTP_GET_VERSION);
5859

5960
int c = curl_easy_perform(req);
6061

deps/http-get/http-get.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <unistd.h>
1515
#endif
1616

17-
#define HTTP_GET_VERSION "0.1.0"
17+
#define HTTP_GET_VERSION "0.3.0"
1818

1919
typedef struct {
2020
char *data;

src/clib.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@
66
//
77

88
#include "asprintf/asprintf.h"
9+
#include "common/clib-cache.h"
910
#include "debug/debug.h"
11+
#include "fs/fs.h"
12+
#include "http-get/http-get.h"
13+
#include "logger/logger.h"
14+
#include "parson/parson.h"
15+
#include "path-join/path-join.h"
1016
#include "str-flatten/str-flatten.h"
1117
#include "strdup/strdup.h"
1218
#include "trim/trim.h"
1319
#include "version.h"
1420
#include "which/which.h"
21+
#include <stdbool.h>
1522
#include <stdio.h>
1623
#include <stdlib.h>
1724
#include <string.h>
@@ -22,6 +29,10 @@
2229
#define realpath(a, b) _fullpath(a, b, strlen(a))
2330
#endif
2431

32+
#define LATEST_RELEASE_ENDPOINT \
33+
"https://api.github.com/repos/clibs/clib/releases/latest"
34+
#define RELEASE_NOTIFICATION_EXPIRATION 3 * 24 * 60 * 60 // 3 days
35+
2536
debug_t debugger;
2637

2738
static const char *usage =
@@ -54,6 +65,77 @@ static const char *usage =
5465
} \
5566
})
5667

68+
static bool should_check_release(const char *path) {
69+
fs_stats *stat = fs_stat(path);
70+
71+
if (!stat) {
72+
return true;
73+
}
74+
75+
time_t modified = stat->st_mtime;
76+
time_t now = time(NULL);
77+
free(stat);
78+
79+
return now - modified >= RELEASE_NOTIFICATION_EXPIRATION;
80+
}
81+
82+
static void compare_versions(const JSON_Object *response,
83+
const char *marker_file_path) {
84+
const char *latest_version = json_object_get_string(response, "tag_name");
85+
86+
if (0 != strcmp(CLIB_VERSION, latest_version)) {
87+
logger_info("info",
88+
"You are using clib %s, a new version is avalable. You can "
89+
"upgrade with the following command: clib upgrade --tag %s",
90+
CLIB_VERSION, latest_version);
91+
}
92+
}
93+
94+
static void notify_new_release(void) {
95+
const char *marker_file_path =
96+
path_join(clib_cache_meta_dir(), "release-notification-checked");
97+
98+
if (!marker_file_path) {
99+
fs_write(marker_file_path, " ");
100+
return;
101+
}
102+
103+
if (!should_check_release(marker_file_path)) {
104+
debug(&debugger, "No need to check for new release yet");
105+
return;
106+
}
107+
108+
JSON_Value *root_json = NULL;
109+
JSON_Object *json_object = NULL;
110+
111+
http_get_response_t *res = http_get(LATEST_RELEASE_ENDPOINT);
112+
113+
if (!res->ok) {
114+
debug(&debugger, "Couldn't lookup latest release");
115+
goto cleanup;
116+
}
117+
118+
if (!(root_json = json_parse_string(res->data))) {
119+
debug(&debugger, "Unable to parse release JSON response");
120+
goto cleanup;
121+
}
122+
123+
if (!(json_object = json_value_get_object(root_json))) {
124+
debug(&debugger, "Unable to parse release JSON response object");
125+
goto cleanup;
126+
}
127+
128+
compare_versions(json_object, marker_file_path);
129+
fs_write(marker_file_path, " ");
130+
131+
cleanup:
132+
if (root_json)
133+
json_value_free(root_json);
134+
135+
free((void *)marker_file_path);
136+
http_get_free(res);
137+
}
138+
57139
int main(int argc, const char **argv) {
58140

59141
char *cmd = NULL;
@@ -65,6 +147,10 @@ int main(int argc, const char **argv) {
65147

66148
debug_init(&debugger, "clib");
67149

150+
clib_cache_meta_init();
151+
152+
notify_new_release();
153+
68154
// usage
69155
if (NULL == argv[1] || 0 == strncmp(argv[1], "-h", 2) ||
70156
0 == strncmp(argv[1], "--help", 6)) {

src/common/clib-cache.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
static char package_cache_dir[BUFSIZ];
3838
static char search_cache[BUFSIZ];
3939
static char json_cache_dir[BUFSIZ];
40+
static char meta_cache_dir[BUFSIZ];
4041
static time_t expiration;
4142

4243
static void json_cache_path(char *pkg_cache, char *author, char *name,
@@ -59,6 +60,18 @@ static int check_dir(char *dir) {
5960
return 0;
6061
}
6162

63+
int clib_cache_meta_init(void) {
64+
sprintf(meta_cache_dir, BASE_CACHE_PATTERN "/meta", BASE_DIR);
65+
66+
if (0 != check_dir(meta_cache_dir)) {
67+
return -1;
68+
}
69+
70+
return 0;
71+
}
72+
73+
const char *clib_cache_meta_dir(void) { return meta_cache_dir; }
74+
6275
int clib_cache_init(time_t exp) {
6376
expiration = exp;
6477

src/common/clib-cache.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@
2121
*/
2222
int clib_cache_init(time_t expiration);
2323

24+
/**
25+
* Initializes the internal cache directory
26+
*
27+
* @return 0 on success, -1 otherwise
28+
*/
29+
int clib_cache_meta_init(void);
30+
31+
/**
32+
* @return directory of internally cached data
33+
*/
34+
const char *clib_cache_meta_dir(void);
35+
2436
/**
2537
* @return The base base dir
2638
*/

src/common/clib-package.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,7 @@ int clib_package_install(clib_package_t *pkg, const char *dir, int verbose) {
14031403
if (0 != fetch) {
14041404
fetch_package_file_thread_data_t *data = fetch;
14051405
int *status;
1406-
pthread_join(data->thread, (void **) &status);
1406+
pthread_join(data->thread, (void **)&status);
14071407
if (NULL != status) {
14081408
rc = *status;
14091409
free(status);
@@ -1493,7 +1493,7 @@ int clib_package_install(clib_package_t *pkg, const char *dir, int verbose) {
14931493
while (--i >= 0) {
14941494
fetch_package_file_thread_data_t *data = fetchs[i];
14951495
int *status;
1496-
pthread_join(data->thread, (void **) &status);
1496+
pthread_join(data->thread, (void **)&status);
14971497
free(data);
14981498
fetchs[i] = NULL;
14991499

@@ -1523,7 +1523,7 @@ int clib_package_install(clib_package_t *pkg, const char *dir, int verbose) {
15231523
fetch_package_file_thread_data_t *data = fetchs[i];
15241524
int *status;
15251525

1526-
pthread_join(data->thread, (void **) &status);
1526+
pthread_join(data->thread, (void **)&status);
15271527

15281528
(void)pending--;
15291529
free(data);

0 commit comments

Comments
 (0)