From 4c6d49f7d8ee1e6e6b849f16dc821e83d8967af8 Mon Sep 17 00:00:00 2001 From: gramanas Date: Wed, 17 Oct 2018 20:00:57 +0300 Subject: [v0.7] Add help subcommand --- CMakeLists.txt | 2 +- src/actionhelper.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++------ src/actionhelper.h | 9 ++--- src/actionparser.c | 61 +++++++++++++++++++------------- src/actionparser.h | 1 + src/actions.c | 31 ++++++++++------ src/actions.h | 1 - src/ck.c | 4 ++- src/dblayer.c | 2 +- 9 files changed, 159 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e474e..1709ba4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ cmake_minimum_required (VERSION 3.5.6) project(ck C) # version set(ck_MAJOR_VERSION 0) -set(ck_MINOR_VERSION 4) +set(ck_MINOR_VERSION 7) # options option(CK_ASAN "Build with asan") diff --git a/src/actionhelper.c b/src/actionhelper.c index 14e8782..6507e7b 100644 --- a/src/actionhelper.c +++ b/src/actionhelper.c @@ -100,10 +100,6 @@ DelOpt del_make_options(cklist *args) { return delOpt; } delOpt.arg = list_get(args); - if (!util_is_file_rw(delOpt.arg)) { - delOpt.err = DEL_ERR_WRONG_PATH; - return delOpt; - } } else { delOpt.arg = list_get(args); } @@ -198,7 +194,7 @@ int init_create_config_file(UserOpt *opt) { ListOpt list_make_options(cklist *args) { list_rewind(args); ListOpt listOpt = { - ._lt = LT_NONE, + ._lt = LT_TREE, ._lst = LST_PLAIN, .pName = NULL, .attr = 0, @@ -280,10 +276,10 @@ void print_ADD_result(int err) { void print_DEL_result(int err) { if (!err) { - HELP("ckdb updated succesfully"); + HELP("ckdb updated succesfully."); return; } - ERR("Could not complete delete transaction"); + ERR("Could not complete delete transaction."); } void print_EDIT_result(int err) { @@ -311,8 +307,94 @@ void print_SEARCH_result(int err) { void print_HELP_result(int err) { if (!err) { - printf("succes\n"); - return; } - printf("failure\n"); +} + +void print_INIT_help() { + ckhelp("Initialize the database and create the file that holds"); + ckhelp("the paths where configurations will be stored."); + ckhelp("Namely the version control and the secret directories.\n"); + ckhelp("It takes two arguments:"); + ckhelp(" `version_control_dir`: the path to the version control directory"); + ckhelp(" `secret_dir`: the path to the secret directory"); + report_help(); +} + +void print_ADD_help() { + ckhelp("Add a config for ck to keep track of.\n"); + ckhelp("The file will be stored to the desired directory and will"); + ckhelp("be linked back to it's original position.\n"); + ckhelp("It takes the following arguments:"); + ckhelp(" `program_name`: the name of the config's program"); + ckhelp(" `path`: path to the configuration (can be relative)\n"); + ckhelp("It also takes the flags:"); + ckhelp(" `-p`: to mark a configuration as primary (so it will open with edit by default)"); + ckhelp(" `-s`: to mark a configuration as secret (to end up in the secret dir)\n"); + ckhelp("Note:\nThere can be only one primary config per program."); + ckhelp("It is advised to use your distribution's package name for the program_name."); + ckhelp("The arguments have to be in the order shown here (name -> path -> flags)"); + report_help(); +} + +void print_DEL_help() { + ckhelp("Delete a program/config from ck.\n"); + ckhelp("This will not interfere with any files or links, it will"); + ckhelp("just remove the program/config from the ck database.\n"); + ckhelp("To completely remove a program/config you have to manually"); + ckhelp("erase it from the folder it is stored. You can do it either before"); + ckhelp("or after running this command.\n"); + ckhelp("It takes one or two arguments:"); + ckhelp(" `program_name`: will delete all configs under that program."); + ckhelp(" `-c path`: will delete the config specified by the path.\n"); + ckhelp("Note:\nThe path that follows the -c option has to be the path shown"); + ckhelp("when you list the configurations of a program. (ck help list for more)"); + report_help(); +} + +void print_EDIT_help() { + ckhelp("Edit a config tracked by ck.\n"); + ckhelp("It takes one or two arguments:"); + ckhelp(" `program_name`: will open the primary config of that program (if set)"); + ckhelp(" `config_name`: will open the specified config\n"); + ckhelp("Note:\nIf a program has only one config, edit will open it even if it's not the primary."); + ckhelp("Edit will use the $EDITOR and if it's not set it falls back to nano."); + ckhelp("If there is ambiguity ck will list the available config names"); + ckhelp("for the program specified."); + report_help(); +} + +void print_LIST_help() { + ckhelp("List various stuff ck knows about.\n"); + ckhelp("List can work in a few different ways:"); + ckhelp(" `tree`: list all the programs and paths in a tree like structure."); + ckhelp(" `paths`: list all the configs ck keeps track."); + ckhelp(" `programs`: list all the programs ck keeps track."); + ckhelp(" `-p program_name`: list only the configs of the specified program."); + ckhelp(" `ckconf`: list the ck configuration values.\n"); + ckhelp("There are also some flags:"); + ckhelp(" `-a`: add the attributes next to the config paths (secret,primary)"); + ckhelp(" `-t`: change the list type. (does not work with tree or ckconf)"); + ckhelp(" `plain`: default plain listing"); + ckhelp(" `python`: enclose the list in [ , ]"); + ckhelp(" `lisp`: enclose the list in ( , )"); + report_help(); +} + +void print_SEARCH_help() { + ckhelp("Search through the configs ck keeps track of.\n"); + ckhelp("Search performs a grep with the supplied term to each"); + ckhelp("file ck keeps track and prints the results.\n"); + ckhelp("The exact grep command used is `grep -H -n`\n"); + ckhelp("It takes one argument:"); + ckhelp(" `search_term`\n"); + ckhelp("Note:\nIf you want to search for a phrase enclose it in \'\' or \"\""); + report_help(); +} + +void print_HELP_help() { + ckhelp("Get help for ck actions.\n"); + ckhelp("It takes one argument:"); + ckhelp(" `action`\n"); + ckhelp("Note:\nRunning ck without arguments will print all the available actions."); + report_help(); } diff --git a/src/actionhelper.h b/src/actionhelper.h index 5bcb7ac..eb544ce 100644 --- a/src/actionhelper.h +++ b/src/actionhelper.h @@ -53,11 +53,12 @@ extern void edit_print_suggested_configs(DB *db, const char *pName); /********/ extern ListOpt list_make_options(cklist *args); -/*****************/ -/* PRINT RESULTS */ -/*****************/ +/************************/ +/* PRINT RESULTS & HELP */ +/************************/ #define X(ACTION) \ - extern void print_##ACTION##_result(int err); + extern void print_##ACTION##_result(int err); \ + extern void print_##ACTION##_help(void); CK_ACTIONS #undef X diff --git a/src/actionparser.c b/src/actionparser.c index c8c70db..aee9732 100644 --- a/src/actionparser.c +++ b/src/actionparser.c @@ -148,7 +148,15 @@ int parse_SEARCH(UserOpt *opt) { } int parse_HELP(UserOpt *opt) { - return -1; + /* Help expects a maximum of 1 argument */ + if (optNum <= pos || optNum > pos + 1) { + opt->err = PERR_HELP_WRONG; + return -1; + } + + int arg_num = optNum - pos; + fill_args_list(arg_num, opt); + return 0; } @@ -164,26 +172,34 @@ int parse_vals(UserOpt *opt) { } } -void determine_action(UserOpt *opt) { - /* get action */ - if (next_token() == -1) { - opt->action = CK_WRONG_ACTION; - return; - } - +CkAction parser_get_action(const char *name, char *actionName) { int i; #define X(ACTION) \ for (i = 1; i < atoi(str##ACTION[0]) + 1; i++) { \ - if (strcmp(token, str##ACTION[i]) == 0) { \ - opt->action = CKA_##ACTION; \ - LOG("Action to perform: %s", str##ACTION[1]); \ - return; \ + if (strcmp(name, str##ACTION[i]) == 0) { \ + if (actionName) { \ + strcpy(actionName, str##ACTION[1]); \ + } \ + return CKA_##ACTION; \ } \ } CK_ACTIONS; #undef X + return CK_WRONG_ACTION; +} + +void determine_action(UserOpt *opt) { + /* get action */ + if (next_token() == -1) { + opt->action = CK_WRONG_ACTION; + return; + } - opt->action = CK_WRONG_ACTION; + char actionName[STR_S]; + opt->action = parser_get_action(token, actionName); + if (opt->action != CK_WRONG_ACTION) { + LOG("Action to perform: %s", actionName); + } return; } @@ -284,7 +300,7 @@ void verbose() { } void get_possible_action_strings(char *dest, CkAction ckAction) { - char buf[STR_S]; + char buf[STR_M]; switch (ckAction) { #define X(ACTION) \ case CKA_##ACTION: \ @@ -308,15 +324,15 @@ void get_possible_action_strings(char *dest, CkAction ckAction) { void print_parser_error(UserOpt *opt) { char errStr[STR_L]; - char names[STR_S]; + char names[STR_M]; get_possible_action_strings(names, opt->action); switch (opt->err) { case PERR_NOERR: return; case PERR_UNKONW_ACTION: - sprintf(errStr, "Unknown action: %s", token); - break; + ERR("Unknown action: %s", token); + return; case PERR_INIT_WRONG: sprintf(errStr, "Initialize database\nUsage: %s version_control_dir secret_dir", names); break; @@ -336,14 +352,13 @@ void print_parser_error(UserOpt *opt) { sprintf(errStr, "Search through the configs with grep\nUsage: %s search-term", names); break; case PERR_HELP_WRONG: - sprintf(errStr, "Usage: ........"); - break; + sprintf(errStr, "Get help for a ck action.\nUsage: %s action", names); } HELP("%s", errStr); } void print_parser_help() { - char names[STR_S]; + char names[STR_M]; ckhelp("ck - the config keeper"); ckhelp("Usage:"); get_possible_action_strings(names, CKA_INIT); @@ -359,7 +374,7 @@ void print_parser_help() { get_possible_action_strings(names, CKA_SEARCH); ckhelp("Search: \t%s", names); get_possible_action_strings(names, CKA_HELP); - ckhelp("Print this: \t%s", names); + ckhelp("Actions Help: \t%s", names); report_help(); } @@ -396,10 +411,6 @@ int parse_action(int argc, char* argv[], UserOpt *opt) { print_parser_error(opt); return -1; } - if (opt->action == CKA_HELP) { - print_parser_help(); - return -1; - } // parse values if (parse_vals(opt)) { diff --git a/src/actionparser.h b/src/actionparser.h index 38b0896..657acbc 100644 --- a/src/actionparser.h +++ b/src/actionparser.h @@ -70,6 +70,7 @@ struct UserOptions { extern int parse_action(int argc, char* argv[], UserOpt *opt); extern void print_parser_error(); extern void print_parser_help(); +extern CkAction parser_get_action(const char *name, char *actionName); extern void free_user_opt(UserOpt *opt); #endif // ACTIONPARSER_H diff --git a/src/actions.c b/src/actions.c index 74b6338..501d952 100644 --- a/src/actions.c +++ b/src/actions.c @@ -23,12 +23,12 @@ ERRLOG(action); int run_INIT(UserOpt * opt, Conf *conf) { UNUSED(conf); if (db_exists(opt)) { - printf("Current configuration file location: %s\n", opt->confDir); - PRINT_ERR("ck is already initialized."); - return 1; + ERR("ck is already initialized in %s", opt->confDir); + return -1; } if (init_create_config_file(opt)) { - return 1; + HELP("Cound not create config file."); + return -2; } DB db = init_make_DB(opt); if (db.error == SQL_NO_ERR) { @@ -42,7 +42,7 @@ int run_ADD(UserOpt * opt, Conf *conf) { DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { - PRINT_ERR("The database file is currupted. Run ck init anew."); + ERR("The database file is currupted. Run ck init anew."); } goto error; } @@ -78,7 +78,7 @@ int run_DEL(UserOpt * opt, Conf *conf) { DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { - PRINT_ERR("The database file is currupted. Run ck init anew."); + ERR("The database file is currupted. Run ck init anew."); } goto error; } @@ -104,7 +104,7 @@ int run_EDIT(UserOpt *opt, Conf *conf) { DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { - PRINT_ERR("The database file is currupted. Run ck init anew."); + ERR("The database file is currupted. Run ck init anew."); } return 1; } @@ -167,7 +167,7 @@ int run_LIST(UserOpt *opt, Conf *conf) { DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { - printf("no tables\n"); + ERR("The database file is currupted. Run ck init anew."); } return 1; } @@ -176,6 +176,7 @@ int run_LIST(UserOpt *opt, Conf *conf) { ListOpt listOpt = list_make_options(opt->args); if (listOpt.err) { + ERR("Wrong list options."); goto error; } char tmp[STR_L] = ""; @@ -211,8 +212,6 @@ int run_LIST(UserOpt *opt, Conf *conf) { } get_program_paths(&db, the_list, listOpt.pName, 0, listOpt.attr); break; - case LT_NONE: - goto error; } switch(listOpt._lst) { case LST_PLAIN: @@ -269,6 +268,16 @@ int run_SEARCH(UserOpt *opt, Conf *conf) { } int run_HELP(UserOpt *opt, Conf *conf) { - printf("Running %s\n", "help"); + UNUSED(conf); + switch(parser_get_action(list_get(opt->args), NULL)) { +#define X(ACTION) \ + case CKA_##ACTION: \ + print_##ACTION##_help(); \ + return 0; + CK_ACTIONS +#undef X + default: + ERR("Unknown action: %s", list_get(opt->args)); + } return 1; } diff --git a/src/actions.h b/src/actions.h index 495984e..dcc6a23 100644 --- a/src/actions.h +++ b/src/actions.h @@ -57,7 +57,6 @@ struct DelOptions { typedef enum ListTypes ListType; enum ListTypes { - LT_NONE, LT_PATH, LT_PROGRAM, LT_TREE, diff --git a/src/ck.c b/src/ck.c index a350a5f..8aeb6d1 100644 --- a/src/ck.c +++ b/src/ck.c @@ -34,6 +34,8 @@ #include "ckutil.h" #include "ckerrlog.h" +ERRLOG(main); + int main(int argc, char *argv[]) { initialize_errlog(argc, argv); UserOpt opt; @@ -47,7 +49,7 @@ int main(int argc, char *argv[]) { /* If the db doesn't exist ck is not initialized in the config * location specified in opt */ if (!db_exists(&opt)) { - printf("ck is not initialized in %s.\nRun ck init first.\n", opt.confDir); + ERR("ck is not initialized in %s.\nRun ck init first.\n", opt.confDir); goto error; } /* Finally parse the config file and exit on error */ diff --git a/src/dblayer.c b/src/dblayer.c index c4bb27b..da5d57e 100644 --- a/src/dblayer.c +++ b/src/dblayer.c @@ -809,7 +809,7 @@ int del_transaction_try(DB *db, char *arg, int conf) { // del conf int cid = get_config_id(db, arg); if (cid < 0) { - ERR("Config doesn't exist in the database."); + ERR("Config %s doesn't exist in the database.", arg); return -1; } if (delete_conf(db, cid)) { -- cgit v1.2.3