summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Williams <andy@andywilliams.me>2017-10-22 19:31:45 +0100
committerAndy Williams <andy@andywilliams.me>2017-10-22 19:31:45 +0100
commit86e6ed85ca4f33a773f7c28551dc188b5b8aa311 (patch)
treefa71e9a18746aa390c6152d2a8cefe6c01823d86
parentdc4798e129069c997e42819318a534d3e3d2db26 (diff)
config: Store the versions we install
This allows us to do an immediate check if there is an update. Avoid hitting git for apps that are tracking released versions
-rw-r--r--src/bin/efler_main.c17
-rw-r--r--src/lib/Makefile.am1
-rw-r--r--src/lib/efler.c26
-rw-r--r--src/lib/efler_config.c321
-rw-r--r--src/lib/efler_config.h52
5 files changed, 401 insertions, 16 deletions
diff --git a/src/bin/efler_main.c b/src/bin/efler_main.c
index 5b10119..a1c0e90 100644
--- a/src/bin/efler_main.c
+++ b/src/bin/efler_main.c
@@ -16,6 +16,7 @@
16 16
17#include "efler.h" 17#include "efler.h"
18 18
19#include "efler_config.h"
19#include "efler_private.h" 20#include "efler_private.h"
20 21
21#define COPYRIGHT "Copyright © 2016 Andy Williams <andy@andywilliams.me> and various contributors (see AUTHORS)." 22#define COPYRIGHT "Copyright © 2016 Andy Williams <andy@andywilliams.me> and various contributors (see AUTHORS)."
@@ -448,7 +449,17 @@ static const Ecore_Getopt optdesc = {
448static void 449static void
449_main_list_item_print(Efler_App *app) 450_main_list_item_print(Efler_App *app)
450{ 451{
451 printf("%s: %s\n", app->id, app->version); 452 printf("%s: %s\n", app->id, app->version ?: "develop");
453 printf(" %s\n", app->description);
454}
455
456static void
457_main_list_item_print_installed(Efler_App *app)
458{
459 const char *version;
460
461 version = _efler_config_app_installed_version_get(app);
462 printf("%s: [%s]\n", app->id, version ?: "develop");
452 printf(" %s\n", app->description); 463 printf(" %s\n", app->description);
453} 464}
454 465
@@ -475,7 +486,7 @@ _main_installed()
475 486
476 EINA_LIST_FOREACH(efler_apps_testing_list(), item, app) 487 EINA_LIST_FOREACH(efler_apps_testing_list(), item, app)
477 if (efler_app_installed(app)) 488 if (efler_app_installed(app))
478 _main_list_item_print(app); 489 _main_list_item_print_installed(app);
479} 490}
480 491
481static void 492static void
@@ -500,7 +511,7 @@ _main_progress_cb(double progress EINA_UNUSED)
500static void 511static void
501_main_done_cb() 512_main_done_cb()
502{ 513{
503 printf(".\n"); 514 printf("\n");
504 515
505 fflush(stdout); 516 fflush(stdout);
506} 517}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 148add8..38b9566 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -15,6 +15,7 @@ includesdir = $(includedir)/efler-@VMAJ@
15 15
16libefler_la_SOURCES = \ 16libefler_la_SOURCES = \
17efler_private.h \ 17efler_private.h \
18efler_config.c \
18efler.c 19efler.c
19libefler_la_LIBADD = @EFL_LIBS@ -lm 20libefler_la_LIBADD = @EFL_LIBS@ -lm
20libefler_la_LDFLAGS = -no-undefined @EFL_LTLIBRARY_FLAGS@ 21libefler_la_LDFLAGS = -no-undefined @EFL_LTLIBRARY_FLAGS@
diff --git a/src/lib/efler.c b/src/lib/efler.c
index 3c5ee41..45f094c 100644
--- a/src/lib/efler.c
+++ b/src/lib/efler.c
@@ -8,6 +8,7 @@
8 8
9#include "efler.h" 9#include "efler.h"
10 10
11#include "efler_config.h"
11#include "efler_private.h" 12#include "efler_private.h"
12 13
13static int _efler_init = 0; 14static int _efler_init = 0;
@@ -49,6 +50,7 @@ efler_init(void)
49 EINA_LOG_ERR("efler can not create its log domain."); 50 EINA_LOG_ERR("efler can not create its log domain.");
50 goto shutdown_eina; 51 goto shutdown_eina;
51 } 52 }
53 _efler_config_init();
52 54
53 _efler_apps_add("efl", "EFL", "v1.20.4", "core/efl", "autogen", 55 _efler_apps_add("efl", "EFL", "v1.20.4", "core/efl", "autogen",
54 "The EFL package - good to keep this up to date first :)"); 56 "The EFL package - good to keep this up to date first :)");
@@ -110,6 +112,7 @@ efler_shutdown(void)
110 free(app); 112 free(app);
111 } 113 }
112 114
115 _efler_config_shutdown();
113 eina_log_domain_unregister(_efler_lib_log_dom); 116 eina_log_domain_unregister(_efler_lib_log_dom);
114 _efler_lib_log_dom = -1; 117 _efler_lib_log_dom = -1;
115 118
@@ -149,8 +152,8 @@ efler_storage_update_blocking(void *data, Ecore_Thread *thread EINA_UNUSED)
149 152
150 progress = (Efler_Progress *) data; 153 progress = (Efler_Progress *) data;
151 done = 0; 154 done = 0;
152 count = eina_list_count(efler_apps_list()); 155 count = eina_list_count(efler_apps_testing_list());
153 EINA_LIST_FOREACH(efler_apps_list(), item, app) 156 EINA_LIST_FOREACH(efler_apps_testing_list(), item, app)
154 { 157 {
155 if (!efler_app_installed(app)) 158 if (!efler_app_installed(app))
156 continue; 159 continue;
@@ -280,27 +283,23 @@ efler_app_icon_path_get(Efler_App *app)
280EAPI Eina_Bool 283EAPI Eina_Bool
281efler_app_installed(Efler_App *app) 284efler_app_installed(Efler_App *app)
282{ 285{
283 char *appdir; 286 return _efler_config_app_installed_get(app);
284 Eina_Bool installed;
285
286 appdir = efler_storage_app_path_get(app);
287 installed = ecore_file_is_dir(appdir);
288 free(appdir);
289
290 return installed;
291} 287}
292 288
293EAPI Eina_Bool 289EAPI Eina_Bool
294efler_app_current(Efler_App *app) 290efler_app_current(Efler_App *app)
295{ 291{
296 const char *path; 292 const char *path, *version;
297 293
298 path = efler_storage_app_path_get(app); 294 path = efler_storage_app_path_get(app);
299 chdir(path); 295 chdir(path);
300 296
301 // TODO store our installed version and compare!!!
302 if (app->version != NULL) 297 if (app->version != NULL)
303 return EINA_FALSE; 298 {
299 version = _efler_config_app_installed_version_get(app);
300
301 return version && !strcmp(version, app->version);
302 }
304 303
305 if (efler_exe_wait("[[ $(git rev-parse HEAD) == $(git rev-parse @{u}) ]]") == 0) 304 if (efler_exe_wait("[[ $(git rev-parse HEAD) == $(git rev-parse @{u}) ]]") == 0)
306 return EINA_TRUE; 305 return EINA_TRUE;
@@ -409,6 +408,7 @@ _efler_app_build(Efler_Progress *progress)
409 _efler_app_sudo("make install", progress); 408 _efler_app_sudo("make install", progress);
410// rm $BUILD_DIR/${NAME}/${FAILED_FILE} 409// rm $BUILD_DIR/${NAME}/${FAILED_FILE}
411 410
411 _efler_config_app_installed_version_set(app);
412 progress->done_cb(); 412 progress->done_cb();
413} 413}
414 414
diff --git a/src/lib/efler_config.c b/src/lib/efler_config.c
new file mode 100644
index 0000000..f2289a1
--- /dev/null
+++ b/src/lib/efler_config.c
@@ -0,0 +1,321 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Eet.h>
6#include <Eina.h>
7#include <Efreet.h>
8#include <Ecore_File.h>
9
10#include "efler_config.h"
11
12#include "efler_private.h"
13
14#define EFLER_CONFIG_NAME PACKAGE_NAME
15
16# define EFLER_CONFIG_LIMIT(v, min, max) \
17 if (v > max) v = max; else if (v < min) v = min;
18
19# define EFLER_CONFIG_DD_NEW(str, typ) \
20 _efler_config_descriptor_new(str, sizeof(typ))
21
22# define EFLER_CONFIG_DD_FREE(eed) \
23 if (eed) { eet_data_descriptor_free(eed); (eed) = NULL; }
24
25# define EFLER_CONFIG_VAL(edd, type, member, dtype) \
26 EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
27
28# define EFLER_CONFIG_SUB(edd, type, member, eddtype) \
29 EET_DATA_DESCRIPTOR_ADD_SUB(edd, type, #member, member, eddtype)
30
31# define EFLER_CONFIG_LIST(edd, type, member, eddtype) \
32 EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
33
34# define EFLER_CONFIG_HASH(edd, type, member, eddtype) \
35 EET_DATA_DESCRIPTOR_ADD_HASH(edd, type, #member, member, eddtype)
36
37# define EFLER_CONFIG_FILE_EPOCH 0x0001
38# define EFLER_CONFIG_FILE_GENERATION 0x0001
39# define EFLER_CONFIG_FILE_VERSION \
40 ((EFLER_CONFIG_FILE_EPOCH << 16) | EFLER_CONFIG_FILE_GENERATION)
41
42typedef Eet_Data_Descriptor Efler_Config_DD;
43
44/* local variables */
45static Efler_Config_DD *_efler_cfg_edd = NULL;
46static Efler_Config_DD *_efler_cfg_app_edd = NULL;
47
48/* external variables */
49Efler_Config *_efler_config = NULL;
50
51const char *
52_efler_config_dir_get(void)
53{
54 static char dir[PATH_MAX];
55
56 if (!dir[0])
57 snprintf(dir, sizeof(dir), "%s/efler", efreet_config_home_get());
58
59 return dir;
60}
61
62/* local functions */
63static Efler_Config_DD *
64_efler_config_descriptor_new(const char *name, int size)
65{
66 Eet_Data_Descriptor_Class eddc;
67
68 if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc),
69 name, size))
70 return NULL;
71
72 return (Efler_Config_DD *)eet_data_descriptor_stream_new(&eddc);
73}
74
75static void
76_efler_config_cb_free(void)
77{
78 Efler_Config_App *app;
79
80 EINA_LIST_FREE(_efler_config->apps, app)
81 {
82 if (app->id) eina_stringshare_del(app->id);
83 if (app->version) eina_stringshare_del(app->version);
84 free(app);
85 }
86
87 free(_efler_config);
88 _efler_config = NULL;
89}
90
91static void *
92_efler_config_domain_load(const char *dir, const char *domain, Eet_Data_Descriptor *edd)
93{
94 Eet_File *ef;
95 char buff[PATH_MAX];
96
97 if (!domain) return NULL;
98 snprintf(buff, sizeof(buff),
99 "%s/%s.cfg", dir, domain);
100 ef = eet_open(buff, EET_FILE_MODE_READ);
101 if (ef)
102 {
103 void *data;
104
105 data = eet_data_read(ef, edd, "config");
106 eet_close(ef);
107 if (data) return data;
108 }
109 return NULL;
110}
111
112static Eina_Bool
113_efler_config_domain_save(const char *dir, const char *domain, Eet_Data_Descriptor *edd, const void *data)
114{
115 Eet_File *ef;
116 char buff[PATH_MAX];
117
118 if (!domain) return 0;
119 snprintf(buff, sizeof(buff), "%s/", dir);
120 if (!ecore_file_exists(buff)) ecore_file_mkpath(buff);
121 snprintf(buff, sizeof(buff), "%s/%s.tmp", dir, domain);
122 ef = eet_open(buff, EET_FILE_MODE_WRITE);
123 if (ef)
124 {
125 char buff2[PATH_MAX];
126
127 snprintf(buff2, sizeof(buff2), "%s/%s.cfg", dir, domain);
128 if (!eet_data_write(ef, edd, "config", data, 1))
129 {
130 eet_close(ef);
131 return EINA_FALSE;
132 }
133 if (eet_close(ef) > 0) return EINA_FALSE;
134 if (!ecore_file_mv(buff, buff2)) return EINA_FALSE;
135 return EINA_TRUE;
136 }
137
138 return EINA_FALSE;
139}
140
141/* external functions */
142Eina_Bool
143_efler_config_init(void)
144{
145 elm_need_efreet();
146 if (!efreet_init()) return EINA_FALSE;
147
148 _efler_cfg_app_edd = EFLER_CONFIG_DD_NEW("Config_App", Efler_Config_App);
149 #undef T
150 #undef D
151 #define T Efler_Config_App
152 #define D _efler_cfg_app_edd
153 EFLER_CONFIG_VAL(D, T, id, EET_T_STRING);
154 EFLER_CONFIG_VAL(D, T, version, EET_T_STRING);
155
156 _efler_cfg_edd = EFLER_CONFIG_DD_NEW("Config", Efler_Config);
157 #undef T
158 #undef D
159 #define T Efler_Config
160 #define D _efler_cfg_edd
161 EFLER_CONFIG_VAL(D, T, version, EET_T_INT);
162
163 EFLER_CONFIG_LIST(D, T, apps, _efler_cfg_app_edd);
164
165 _efler_config_load();
166
167 return EINA_TRUE;
168}
169
170Eina_Bool
171_efler_config_shutdown(void)
172{
173 _efler_config_cb_free();
174
175 EFLER_CONFIG_DD_FREE(_efler_cfg_app_edd);
176 EFLER_CONFIG_DD_FREE(_efler_cfg_edd);
177
178 efreet_shutdown();
179
180 return EINA_TRUE;
181}
182
183void
184_efler_config_load(void)
185{
186 Eina_Bool save = EINA_FALSE;
187
188 _efler_config = _efler_config_domain_load(_efler_config_dir_get(), EFLER_CONFIG_NAME, _efler_cfg_edd);
189 if (_efler_config)
190 {
191 Eina_Bool reload = EINA_FALSE;
192
193 if ((_efler_config->version >> 16) < EFLER_CONFIG_FILE_EPOCH)
194 {
195 /* config too old */
196 reload = EINA_TRUE;
197 }
198 else if (_efler_config->version > EFLER_CONFIG_FILE_VERSION)
199 {
200 /* config too new, WTF ? */
201 reload = EINA_TRUE;
202 }
203
204 /* if too old or too new, clear it so we can create new */
205 if (reload) _efler_config_cb_free();
206 }
207
208 if (!_efler_config)
209 {
210 _efler_config = calloc(1, sizeof(Efler_Config));
211 save = EINA_TRUE;
212 }
213
214 /* define some convenient macros */
215#define IFCFG(v) if ((_efler_config->version & 0xffff) < (v)) {
216#define IFCFGELSE } else {
217#define IFCFGEND }
218
219 _efler_config->version = EFLER_CONFIG_FILE_VERSION;
220
221 if (save) _efler_config_save();
222}
223
224void
225_efler_config_save(void)
226{
227 if (!_efler_config_domain_save(_efler_config_dir_get(), EFLER_CONFIG_NAME, _efler_cfg_edd, _efler_config))
228 ERR("Could not save configuration");
229}
230
231void
232_efler_config_app_add(const char *id, const char *version)
233{
234 Efler_Config_App *app;
235 Eina_List *list, *next;
236
237 EINA_LIST_FOREACH_SAFE(_efler_config->apps, list, next, app)
238 {
239 if (strlen(app->id) == strlen(id) &&
240 !strncmp(app->id, id, strlen(app->id)))
241 _efler_config->apps = eina_list_remove_list(_efler_config->apps, list);
242 }
243
244 app = malloc(sizeof(*app));
245 app->id = eina_stringshare_add(id);
246 app->version = eina_stringshare_add(version);
247 _efler_config->apps = eina_list_prepend(_efler_config->apps, app);
248 _efler_config_save();
249}
250
251void
252_efler_config_app_remove(const char *id)
253{
254 Efler_Config_App *app;
255 Eina_List *list, *next;
256
257 EINA_LIST_FOREACH_SAFE(_efler_config->apps, list, next, app)
258 {
259 if (!strncmp(app->id, id, strlen(app->id)))
260 break;
261 }
262
263 _efler_config->apps = eina_list_remove(_efler_config->apps, app);
264 _efler_config_save();
265
266 eina_stringshare_del(app->id);
267 eina_stringshare_del(app->version);
268 free(app );
269}
270
271Eina_Bool
272_efler_config_app_installed_get(Efler_App *app)
273{
274 Efler_Config_App *item;
275 Eina_List *list;
276
277 EINA_LIST_FOREACH(_efler_config->apps, list, item)
278 {
279 if (!strncmp(item->id, app->id, strlen(item->id)))
280 return EINA_TRUE;
281 }
282
283 return EINA_FALSE;
284}
285
286const char *
287_efler_config_app_installed_version_get(Efler_App *app)
288{
289 Efler_Config_App *item;
290 Eina_List *list;
291
292 EINA_LIST_FOREACH(_efler_config->apps, list, item)
293 {
294 if (!strncmp(item->id, app->id, strlen(item->id)))
295 return item->version;
296 }
297
298 return NULL;
299}
300
301void
302_efler_config_app_installed_version_set(Efler_App *app)
303{
304 Efler_Config_App *item;
305 Eina_List *list;
306
307 if (!_efler_config_app_installed_get(app))
308 _efler_config_app_add(app->id, app->version);
309
310 EINA_LIST_FOREACH(_efler_config->apps, list, item)
311 {
312 if (strncmp(item->id, app->id, strlen(item->id)))
313 continue;
314
315 item->version = app->version;
316 break;
317 }
318
319 _efler_config_save();
320}
321
diff --git a/src/lib/efler_config.h b/src/lib/efler_config.h
new file mode 100644
index 0000000..36adebc
--- /dev/null
+++ b/src/lib/efler_config.h
@@ -0,0 +1,52 @@
1#ifndef _EFLER_CONFIG_H_
2# define _EFLER_CONFIG_H_ 1
3
4#include <Eina.h>
5
6#include "efler.h"
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12typedef struct _Efler_Config_App Efler_Config_App;
13typedef struct _Efler_Config Efler_Config;
14
15struct _Efler_Config_App
16{
17 const char *id;
18 const char *version;
19};
20
21struct _Efler_Config
22{
23 int version;
24
25 Eina_List *apps;
26};
27
28extern Efler_Config *_efler_config;
29
30// General configuration management
31
32Eina_Bool _efler_config_init(void);
33Eina_Bool _efler_config_shutdown(void);
34const char *_efler_config_dir_get(void);
35
36// Global configuration handling
37
38void _efler_config_load(void);
39void _efler_config_save(void);
40
41void _efler_config_app_add(const char *id, const char *version);
42void _efler_config_app_remove(const char *id);
43
44Eina_Bool _efler_config_app_installed_get(Efler_App *app);
45const char *_efler_config_app_installed_version_get(Efler_App *app);
46void _efler_config_app_installed_version_set(Efler_App *app);
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* _EFLER_CONFIG_H_ */