fix: better way to validate the config, add options to git clone
This commit is contained in:
parent
5691727d64
commit
bdd1ee23d8
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-05-01 20:59+0300\n"
|
||||
"POT-Creation-Date: 2024-05-01 23:04+0300\n"
|
||||
"PO-Revision-Date: 2024-05-01 13:34+0300\n"
|
||||
"Last-Translator: <ngn@ngn.tf>\n"
|
||||
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
|
||||
@ -23,76 +23,100 @@ msgstr ""
|
||||
|
||||
#: src/config.c:18
|
||||
#, c-format
|
||||
msgid "Configuration target %s does not have \"dst\" field"
|
||||
msgid "Configuration target \"%s\" does not have \"dst\" field"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:23
|
||||
#, c-format
|
||||
msgid "Configuration target %s does not have \"src\" field"
|
||||
msgid "Configuration target \"%s\" does not have \"src\" field"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:53
|
||||
#: src/config.c:32
|
||||
msgid "Configuration does not have a name field"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:58
|
||||
#: src/config.c:37
|
||||
msgid "Configuration does not have an author field"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:63
|
||||
#: src/config.c:42
|
||||
msgid "Configuration does not have any targets"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:117
|
||||
#: src/config.c:120
|
||||
#, c-format
|
||||
msgid "Key %s is unknown"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:160
|
||||
#: src/config.c:156
|
||||
msgid "Configuration file not found"
|
||||
msgstr ""
|
||||
|
||||
#: src/config.c:170
|
||||
msgid "Failed to parse configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:66
|
||||
#: src/log.c:150
|
||||
msgid "y"
|
||||
msgstr ""
|
||||
|
||||
#: src/log.c:150
|
||||
msgid "Y"
|
||||
msgstr ""
|
||||
|
||||
#: src/log.c:152
|
||||
msgid "n"
|
||||
msgstr ""
|
||||
|
||||
#: src/log.c:152
|
||||
msgid "N"
|
||||
msgstr ""
|
||||
|
||||
#: src/log.c:155
|
||||
msgid "Please answer with y/n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:74
|
||||
#, c-format
|
||||
msgid "Failed to access paths (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:74
|
||||
#: src/main.c:82
|
||||
msgid "Failed to lock, mc is already running"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:77
|
||||
#: src/main.c:85
|
||||
msgid "Failed to lock, did you mess up your directory permissions?"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:86
|
||||
#, c-format
|
||||
msgid "%s: command failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:90
|
||||
#, c-format
|
||||
msgid "%s: command successful"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:94
|
||||
#, c-format
|
||||
msgid "MatterLinux Configuration Manager (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:95
|
||||
msgid "Different operations are done using different commands\n"
|
||||
msgid "%s: command failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:98
|
||||
msgid "pull down a configuration"
|
||||
#, c-format
|
||||
msgid "%s: command successful"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:101
|
||||
msgid "build the configuration in the current directory"
|
||||
#: src/main.c:102
|
||||
#, c-format
|
||||
msgid "MatterLinux Configuration Manager (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:103
|
||||
msgid "Different operations are done using different commands\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:106
|
||||
msgid "pull down a configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:109
|
||||
msgid "build the configuration in the current directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.c:111
|
||||
msgid ""
|
||||
"Licensed under GPLv3, see <https://www.gnu.org/licenses/> for more "
|
||||
"information"
|
||||
@ -102,21 +126,58 @@ msgstr ""
|
||||
msgid "Please specify a config name or a URL"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:55
|
||||
#: src/pull.c:56
|
||||
#, c-format
|
||||
msgid "Cloning %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:60
|
||||
#: src/pull.c:61
|
||||
#, c-format
|
||||
msgid "Failed to clone the %s: %s"
|
||||
msgid "Failed to clone the %s:"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:70
|
||||
#: src/pull.c:72
|
||||
#, c-format
|
||||
msgid "Failed to chdir to %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:76
|
||||
#: src/pull.c:77
|
||||
msgid "Failed to load the configuration file (mc.cfg):"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:82
|
||||
msgid "Loaded repository configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:83
|
||||
msgid "Configuration details:\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:84
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:85
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:87
|
||||
msgid "Keywords"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:92
|
||||
msgid "Do you want to continue?"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:95
|
||||
msgid "Checking all the targets"
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:99
|
||||
#, c-format
|
||||
msgid "Failed to access the source for the target \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: src/pull.c:105
|
||||
msgid "All the targets are OK"
|
||||
msgstr ""
|
||||
|
72
src/config.c
72
src/config.c
@ -15,18 +15,44 @@ bool target_is_valid(target_t *target) {
|
||||
}
|
||||
|
||||
if (NULL == target->dst) {
|
||||
error_set(_("Configuration target %s does not have \"dst\" field"), target->name);
|
||||
error_set(_("Configuration target \"%s\" does not have \"dst\" field"), target->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == target->src) {
|
||||
error_set(_("Configuration target %s does not have \"src\" field"), target->name);
|
||||
error_set(_("Configuration target \"%s\" does not have \"src\" field"), target->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool config_is_valid(config_t *config) {
|
||||
if (NULL == config->name) {
|
||||
error_set(_("Configuration does not have a name field"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == config->author) {
|
||||
error_set(_("Configuration does not have an author field"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == config->t_last) {
|
||||
error_set(_("Configuration does not have any targets"));
|
||||
return false;
|
||||
}
|
||||
|
||||
target_t *cur = config->t_first;
|
||||
while(cur){
|
||||
if(!target_is_valid(cur))
|
||||
return false;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool config_add_target(config_t *config, char *name) {
|
||||
target_t *new = malloc(sizeof(target_t));
|
||||
clist_init(&new->requires);
|
||||
@ -48,25 +74,6 @@ bool config_add_target(config_t *config, char *name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool config_is_valid(config_t *config) {
|
||||
if (NULL == config->name) {
|
||||
error_set(_("Configuration does not have a name field"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == config->author) {
|
||||
error_set(_("Configuration does not have an author field"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == config->t_last) {
|
||||
error_set(_("Configuration does not have any targets"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int config_handler(void *data, const char *section, const char *key, const char *value) {
|
||||
#define MATCH(s, k) eq((char *)section, s) && eq((char *)key, k)
|
||||
#define MATCHKEY(k) eq((char *)key, k)
|
||||
@ -85,17 +92,12 @@ int config_handler(void *data, const char *section, const char *key, const char
|
||||
} else if (MATCH("details", "keywords")) {
|
||||
clist_from_str(&config->keywords, (char *)value);
|
||||
return 1;
|
||||
}else if(eq((char*)section, "details")) {
|
||||
goto UNKNOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(NULL == config->t_last || (NULL != config->t_last->name && !eq(config->t_last->name, (char*)section))){
|
||||
if (NULL != config->t_last) {
|
||||
if (!target_is_valid(config->t_last)) {
|
||||
errno = ConfigInvalid;
|
||||
debug("invalid %s %s", config->t_last->name, section);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
debug("adding new target => %s", section);
|
||||
config_add_target(config, strdup(section));
|
||||
}
|
||||
@ -107,13 +109,14 @@ int config_handler(void *data, const char *section, const char *key, const char
|
||||
config->t_last->dst = strdup(value);
|
||||
return 1;
|
||||
} else if (MATCHKEY("src")) {
|
||||
config->t_last->dst = strdup(value);
|
||||
config->t_last->src = strdup(value);
|
||||
return 1;
|
||||
} else if (MATCHKEY("requires")) {
|
||||
clist_from_str(&config->t_last->requires, strdup(value));
|
||||
return 1;
|
||||
}
|
||||
|
||||
UNKNOWN:
|
||||
error_set(_("Key %s is unknown"), key);
|
||||
errno = ConfigUnknown;
|
||||
return 0;
|
||||
@ -140,10 +143,17 @@ void config_free(config_t *config) {
|
||||
}
|
||||
|
||||
clist_free(&config->keywords);
|
||||
|
||||
config->name = NULL;
|
||||
config->author = NULL;
|
||||
config->t_first = NULL;
|
||||
config->t_last = NULL;
|
||||
clist_init(&config->keywords);
|
||||
}
|
||||
|
||||
bool config_load(config_t *config, char *path) {
|
||||
if (!exists(path) || is_dir(path)) {
|
||||
error_set(_("Configuration file not found"));
|
||||
errno = ConfigNotFound;
|
||||
return false;
|
||||
}
|
||||
@ -156,7 +166,7 @@ bool config_load(config_t *config, char *path) {
|
||||
|
||||
if (ini_parse(path, config_handler, config) < 0) {
|
||||
config_free(config);
|
||||
if (errno != ConfigUnknown && errno != ConfigInvalid) {
|
||||
if (errno != ConfigUnknown) {
|
||||
error_set(_("Failed to parse configuration file"));
|
||||
errno = ConfigParseFail;
|
||||
}
|
||||
|
@ -23,3 +23,4 @@ typedef struct config {
|
||||
} config_t;
|
||||
|
||||
bool config_load(config_t *, char *);
|
||||
void config_free(config_t *);
|
||||
|
43
src/log.c
43
src/log.c
@ -1,5 +1,8 @@
|
||||
#include "log.h"
|
||||
#include "env.h"
|
||||
#include "intl.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -88,6 +91,17 @@ void error(const char *msg, ...) {
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void details(const char *msg, ...) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
||||
printf(" "COLOR_RESET);
|
||||
vprintf(msg, args);
|
||||
printf(COLOR_RESET "\n");
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void success(const char *msg, ...) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
@ -112,3 +126,32 @@ void debug(const char *msg, ...) {
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void input(const char *msg, ...) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
||||
printf(COLOR_BOLD COLOR_CYAN ">>> " COLOR_RESET COLOR_BOLD);
|
||||
vprintf(msg, args);
|
||||
printf(COLOR_RESET);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
bool yesno(const char *msg){
|
||||
char question[strlen(msg)+12], inp[2] = {'n','\0'}, c;
|
||||
sprintf(question, "%s [y/n]? ", msg);
|
||||
|
||||
while(true){
|
||||
input(question);
|
||||
scanf("%c", &c);
|
||||
inp[0] = c;
|
||||
|
||||
if(eq(inp, _("y")) || eq(inp, _("Y")))
|
||||
return true;
|
||||
else if(eq(inp, _("n")) || eq(inp, _("N")))
|
||||
return false;
|
||||
|
||||
error(_("Please answer with y/n"));
|
||||
}
|
||||
}
|
||||
|
11
src/log.h
11
src/log.h
@ -4,15 +4,20 @@
|
||||
#define COLOR_RED "\x1b[31m"
|
||||
#define COLOR_BOLD "\x1b[1m"
|
||||
#define COLOR_BLUE "\x1b[34m"
|
||||
#define COLOR_CYAN "\x1b[36m"
|
||||
#define COLOR_GREEN "\x1b[32m"
|
||||
#define COLOR_MAGENTA "\x1b[35m"
|
||||
#define COLOR_UNDERLINE "\x1b[4m"
|
||||
#define COLOR_RESET "\x1b[0m"
|
||||
|
||||
void bar_init();
|
||||
bool bar(float, float);
|
||||
void bar_free();
|
||||
|
||||
void info(const char *msg, ...);
|
||||
void error(const char *msg, ...);
|
||||
void success(const char *msg, ...);
|
||||
void info(const char *, ...);
|
||||
void error(const char *, ...);
|
||||
void details(const char *, ...);
|
||||
void success(const char *, ...);
|
||||
void debug(const char *, ...);
|
||||
void input(const char *, ...);
|
||||
bool yesno(const char *);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -51,7 +52,14 @@ struct CmdMap cmdmap[] = {
|
||||
{.name = "mc-gen", .lock = false, .func = gen_cmd },
|
||||
};
|
||||
|
||||
void handler(int sig){
|
||||
unlock();
|
||||
printf("\e[?25h");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
signal(SIGINT, handler);
|
||||
setbuf(stdout, NULL);
|
||||
setlocale(LC_ALL, "");
|
||||
textdomain("mc");
|
||||
|
41
src/pull.c
41
src/pull.c
@ -17,7 +17,7 @@
|
||||
|
||||
#define _(x) gettext(x)
|
||||
|
||||
int fetch_progress(const git_indexer_progress *stats, void *data) {
|
||||
int pull_progress(const git_indexer_progress *stats, void *data){
|
||||
bar(stats->indexed_objects, stats->total_objects);
|
||||
return 0;
|
||||
}
|
||||
@ -29,6 +29,7 @@ bool pull_cmd() {
|
||||
}
|
||||
|
||||
char *repo_url = NULL, *repo_root = NULL;
|
||||
config_t repo_cfg = {.name = NULL};
|
||||
bool ret = false;
|
||||
|
||||
if (url_is_local(args.list[1])) {
|
||||
@ -49,15 +50,16 @@ bool pull_cmd() {
|
||||
|
||||
git_repository *repo = NULL;
|
||||
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||
opts.fetch_opts.callbacks.transfer_progress = fetch_progress;
|
||||
opts.fetch_opts.callbacks.transfer_progress = pull_progress;
|
||||
opts.fetch_opts.callbacks.payload = NULL;
|
||||
|
||||
info(_("Cloning %s"), repo_url);
|
||||
bar_init();
|
||||
|
||||
if (git_clone(&repo, repo_url, repo_root, NULL) < 0) {
|
||||
if (git_clone(&repo, repo_url, repo_root, &opts) < 0) {
|
||||
const git_error *e = git_error_last();
|
||||
error(_("Failed to clone the %s: %s"), repo_url, e->message);
|
||||
error(_("Failed to clone the %s:"), repo_url);
|
||||
details(e->message);
|
||||
bar_free();
|
||||
goto END;
|
||||
}
|
||||
@ -71,23 +73,40 @@ COPY:
|
||||
goto END;
|
||||
}
|
||||
|
||||
config_t repo_cfg;
|
||||
if (!config_load(&repo_cfg, "mc.cfg")) {
|
||||
error(_("Failed to load the configuration file (mc.cfg):"));
|
||||
printf(" %s\n", errch);
|
||||
details(errch);
|
||||
goto END;
|
||||
}
|
||||
|
||||
info("Configuration details:");
|
||||
printf(COLOR_BOLD " Name" COLOR_RESET ": %s\n", repo_cfg.name);
|
||||
printf(COLOR_BOLD " Author" COLOR_RESET ": %s\n", repo_cfg.author);
|
||||
success(_("Loaded repository configuration"));
|
||||
info(_("Configuration details:\n"));
|
||||
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Name"), repo_cfg.name);
|
||||
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Author"), repo_cfg.author);
|
||||
|
||||
printf(COLOR_BOLD " Keywords" COLOR_RESET ":");
|
||||
printf(COLOR_BOLD " %s " COLOR_RESET "=> ", _("Keywords"));
|
||||
for (int i = 0; i < repo_cfg.keywords.s; i++)
|
||||
printf("%s ", repo_cfg.keywords.c[i]);
|
||||
printf("\n");
|
||||
printf("\n\n");
|
||||
|
||||
if(!yesno(_("Do you want to continue?")))
|
||||
goto END;
|
||||
|
||||
info(_("Checking all the targets"));
|
||||
target_t *cur = repo_cfg.t_first;
|
||||
while(NULL != cur){
|
||||
if(!exists(cur->src)){
|
||||
error(_("Failed to access the source for the target \"%s\""), cur->name);
|
||||
goto END;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
success(_("All the targets are OK"));
|
||||
|
||||
END:
|
||||
if(repo_cfg.name != NULL)
|
||||
config_free(&repo_cfg);
|
||||
free(repo_url);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user