Skip to content

Commit a60b8ff

Browse files
authored
Intergrating clib-uninstall (#245)
* Intergrating clib-uninstall * related: http-get.c #7
1 parent 2cead30 commit a60b8ff

File tree

7 files changed

+260
-6
lines changed

7 files changed

+260
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package-lock.json
1111
clib-build
1212
clib-update
1313
clib-upgrade
14+
clib-uninstall
1415

1516
test/package/package-*
1617
!test/package/package-*.c

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CC ?= cc
22
PREFIX ?= /usr/local
33

4-
BINS = clib clib-install clib-search clib-init clib-configure clib-build clib-update clib-upgrade
4+
BINS = clib clib-install clib-search clib-init clib-configure clib-build clib-update clib-upgrade clib-uninstall
55

66
ifdef EXE
77
BINS := $(addsuffix .exe,$(BINS))

deps/http-get/clib.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "http-get",
3-
"version": "0.3.0",
3+
"version": "0.4.0",
44
"repo": "clibs/http-get.c",
55
"description": "Simple HTTP GET requests backed by libcurl",
66
"keywords": [

deps/http-get/http-get.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
#ifndef HTTP_GET_H
1111
#define HTTP_GET_H 1
1212

13-
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
14-
#include <unistd.h>
15-
#endif
13+
#include <stdlib.h>
1614

17-
#define HTTP_GET_VERSION "0.3.0"
15+
#define HTTP_GET_VERSION "0.4.0"
1816

1917
typedef struct {
2018
char *data;

src/clib-uninstall.c

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
//
2+
// clib-uninstall.c
3+
//
4+
// Copyright (c) 2014 Stephen Mathieson
5+
// Copyright (c) 2021 clib authors
6+
//
7+
// MIT licensed
8+
//
9+
10+
#include "asprintf/asprintf.h"
11+
#include "commander/commander.h"
12+
#include "debug/debug.h"
13+
#include "fs/fs.h"
14+
#include "http-get/http-get.h"
15+
#include "logger/logger.h"
16+
#include "parse-repo/parse-repo.h"
17+
#include "parson/parson.h"
18+
#include "version.h"
19+
#include <stdlib.h>
20+
#include <string.h>
21+
22+
#define CLIB_UNINSTALL_DEFAULT_TARGET "make uninstall"
23+
24+
#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || \
25+
defined(__MINGW64__) || defined(__CYGWIN__)
26+
#define setenv(k, v, _) _putenv_s(k, v)
27+
#endif
28+
29+
const char *manifest_names[] = {"clib.json", "package.json", NULL};
30+
31+
debug_t debugger;
32+
33+
static void setopt_prefix(command_t *self) {
34+
setenv("PREFIX", (char *)self->arg, 1);
35+
debug(&debugger, "set prefix: %s", (char *)self->arg);
36+
}
37+
38+
static char *get_tarball_url(const char *owner, const char *name,
39+
const char *version) {
40+
char *tarball = NULL;
41+
int size = 0;
42+
43+
size = asprintf(&tarball, "https://github.com/%s/%s/archive/%s.tar.gz", owner,
44+
name, version);
45+
46+
if (-1 == size)
47+
return NULL;
48+
return tarball;
49+
}
50+
51+
static char *get_tar_filepath(const char *name, const char *version) {
52+
char *file = NULL;
53+
int size = asprintf(&file, "%s-%s.tar.gz", name, version);
54+
if (-1 == size)
55+
return NULL;
56+
return file;
57+
}
58+
59+
static char *get_tmp_tarball(const char *file) {
60+
char *tmp = NULL;
61+
int size = asprintf(&tmp, "/tmp/%s", file);
62+
if (-1 == size)
63+
return NULL;
64+
return tmp;
65+
}
66+
67+
static char *get_untar_command(const char *file) {
68+
char *cmd = NULL;
69+
int size = 0;
70+
size = asprintf(&cmd, "cd /tmp && tar -xf %s", file);
71+
if (-1 == size)
72+
return NULL;
73+
return cmd;
74+
}
75+
76+
static char *get_manifest_path(const char *dir) {
77+
char *path = NULL;
78+
int i = 0;
79+
80+
do {
81+
asprintf(&path, "%s/%s", dir, manifest_names[i]);
82+
83+
if (0 == fs_exists(path)) {
84+
return path;
85+
}
86+
87+
debug(&debugger, "Manifest file does not exist %s", path);
88+
89+
free(path);
90+
path = NULL;
91+
} while (NULL != manifest_names[++i]);
92+
93+
return NULL;
94+
}
95+
96+
static char *get_uninstall_target(const char *name, const char *version) {
97+
int size = 0;
98+
char *target = NULL;
99+
char *dir = NULL;
100+
char *manifest = NULL;
101+
const char *val = NULL;
102+
JSON_Value *root = NULL;
103+
JSON_Object *obj = NULL;
104+
105+
size = asprintf(&dir, "/tmp/%s-%s", name, version);
106+
if (-1 == size)
107+
return NULL;
108+
109+
manifest = get_manifest_path(dir);
110+
111+
if (NULL == manifest)
112+
goto done;
113+
114+
root = json_parse_file(manifest);
115+
if (!root)
116+
goto done;
117+
118+
obj = json_value_get_object(root);
119+
if (!obj)
120+
goto done;
121+
122+
val = json_object_get_string(obj, "uninstall");
123+
if (!val) {
124+
logger_warn("warning",
125+
"No uninstall target specified. Defaulting to '%s'.",
126+
CLIB_UNINSTALL_DEFAULT_TARGET);
127+
// default to "make uninstall"
128+
val = CLIB_UNINSTALL_DEFAULT_TARGET;
129+
}
130+
131+
size = asprintf(&target, "cd %s && %s", dir, val);
132+
if (-1 == size)
133+
return NULL;
134+
135+
done:
136+
if (root)
137+
json_value_free(root);
138+
free(dir);
139+
free(manifest);
140+
return target;
141+
}
142+
143+
static int clib_uninstall(const char *owner, const char *name,
144+
const char *version) {
145+
char *tarball = NULL;
146+
char *file = NULL;
147+
char *tarpath = NULL;
148+
char *cmd = NULL;
149+
char *target = NULL;
150+
int rc = -1;
151+
152+
// sanity
153+
if (!owner || !name || !version)
154+
return -1;
155+
156+
if (!(tarball = get_tarball_url(owner, name, version)))
157+
goto done;
158+
if (!(file = get_tar_filepath(name, version)))
159+
goto done;
160+
if (!(tarpath = get_tmp_tarball(file)))
161+
goto done;
162+
163+
logger_info("fetch", tarball);
164+
if (-1 == http_get_file(tarball, tarpath)) {
165+
logger_error("error", "failed to fetch tarball");
166+
goto done;
167+
}
168+
169+
if (!(cmd = get_untar_command(file)))
170+
goto done;
171+
172+
logger_info("untar", tarpath);
173+
if (0 != system(cmd)) {
174+
logger_error("error", "failed to untar");
175+
goto done;
176+
}
177+
178+
target = get_uninstall_target(name, version);
179+
if (!target)
180+
goto done;
181+
182+
rc = system(target);
183+
184+
done:
185+
free(tarball);
186+
free(file);
187+
free(tarpath);
188+
free(cmd);
189+
free(target);
190+
return rc;
191+
}
192+
193+
int main(int argc, char **argv) {
194+
int rc = 1;
195+
command_t program;
196+
197+
debug_init(&debugger, "clib-uninstall");
198+
199+
command_init(&program, "clib-uninstall", CLIB_VERSION);
200+
201+
program.usage = "[options] [name ...]";
202+
203+
command_option(&program, "-P", "--prefix <dir>",
204+
"change the prefix directory (usually '/usr/local')",
205+
setopt_prefix);
206+
207+
command_parse(&program, argc, argv);
208+
209+
if (0 == program.argc)
210+
command_help(&program);
211+
212+
for (int i = 0; i < program.argc; i++) {
213+
char *owner = parse_repo_owner(program.argv[i], NULL);
214+
if (!owner)
215+
goto cleanup;
216+
char *name = parse_repo_name(program.argv[i]);
217+
if (!name) {
218+
free(owner);
219+
goto cleanup;
220+
}
221+
222+
int res = clib_uninstall(owner, name, "master");
223+
free(owner);
224+
free(name);
225+
if (-1 == res) {
226+
logger_error("error", "Failed to uninstall %s", program.argv[i]);
227+
goto cleanup;
228+
}
229+
}
230+
231+
rc = 0;
232+
233+
cleanup:
234+
command_free(&program);
235+
return rc;
236+
}

src/clib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static const char *usage =
5050
" init Start a new project\n"
5151
" i, install [name...] Install one or more packages\n"
5252
" up, update [name...] Update one or more packages\n"
53+
" uninstall [name...] Uninstall executables\n"
5354
" upgrade [version] Upgrade clib to a specified or latest version\n"
5455
" configure [name...] Configure one or more packages\n"
5556
" build [name...] Build one or more packages\n"

test/uninstall.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
mkdir -p tmp/bin
4+
5+
clib install -c stephenmathieson/tabs-to-spaces@1.0.0 -P tmp > /dev/null || {
6+
echo >&2 "Failed to install stephenmathieson/tabs-to-spaces"
7+
exit 1
8+
}
9+
10+
clib uninstall stephenmathieson/tabs-to-spaces -P tmp
11+
12+
# ensure the un-installation worked
13+
command -v tmp/bin/t2s >/dev/null 2>&1 && {
14+
exit 0
15+
}
16+
17+
echo >&2 "Failed to uninstall stephenmathieson/tabs-to-spaces";
18+
exit 1

0 commit comments

Comments
 (0)