From 598e0522de924a50ea9c640955daab8512029eb4 Mon Sep 17 00:00:00 2001 From: gramanas Date: Tue, 9 Oct 2018 20:53:30 +0300 Subject: Better list --- README.html | 284 ++++++++++++++++++++++++++++------------------------- README.org | 18 +++- src/actionhelper.c | 21 ++-- src/actionparser.c | 8 +- src/actions.c | 37 ++++++- src/actions.h | 5 +- src/dblayer.c | 36 ++++--- src/dblayer.h | 2 +- 8 files changed, 248 insertions(+), 163 deletions(-) diff --git a/README.html b/README.html index 2180663..45839fd 100644 --- a/README.html +++ b/README.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + @@ -232,35 +232,35 @@ for the JavaScript code in this tag.

Table of Contents

-
-

ck

-
+
+

ck

+

The Config Keeper

-
-

build it

-
+
+

build it

+
-
-

requirements

-
+
+

requirements

+
  • clang (llvm) or gcc (gnu)
  • cmake
  • @@ -293,31 +293,31 @@ for the JavaScript code in this tag.
-
-

compiler

-
+
+

compiler

+
-
> export CC=clang
-# or
-> export CC=gcc
+
> export CC=clang
+# or
+> export CC=gcc
 
-
-

make

-
+
+

make

+
-
# clone the repo
+
# clone the repo
 > cd ~/code; git clone https://gitlab.com/grm-grm/ck
-# make a build directory and enter it
-> mkdir ~/ck_build; cd ~/ck_build;
-# run cmake
+# make a build directory and enter it
+> mkdir ~/ck_build; cd ~/ck_build;
+# run cmake
 > cmake ~/code/ck
-# run make
+# run make
 > make
-# run ck
+# run ck
 > ./ck
 
@@ -325,21 +325,21 @@ for the JavaScript code in this tag.
-
-

for devs

-
+
+

for devs

+
-
-

CMake options

-
+
+

CMake options

+

cmake accepts the following options:

-
option(CK_ASAN "Build with asan")
-option(CK_DEBUG "Build with debug symbols")
-option(CK_TESTS "Make the tests")
-option(CK_SHARED "Build with shared lib")
+
option(CK_ASAN "Build with asan")
+option(CK_DEBUG "Build with debug symbols")
+option(CK_TESTS "Make the tests")
+option(CK_SHARED "Build with shared lib")
 
@@ -356,24 +356,24 @@ Just build with address sanitizer enabled like so: llvm has better asan than gcc, so I use that.

-
# clone the repo
+
# clone the repo
 > cd ~/code; git clone https://gitlab.com/grm-grm/ck
-# make a build directory and enter it
-> mkdir ~/ck_build; cd ~/ck_build;
-# run cmake
+# make a build directory and enter it
+> mkdir ~/ck_build; cd ~/ck_build;
+# run cmake
 > cmake -DCK_ASAN=1 -DCK_DEBUG=1 -DCK_TESTS=1 ~/code/ck
-# run make
+# run make
 > make
-# run ck
+# run ck
 > ./ck
 
-
-

tests

-
+
+

tests

+

The testing "suite" is a bash script that runs regression and unit tests. Regression tests are under the tests/ directory @@ -382,9 +382,9 @@ under unit/ directory and test the code.

-
-

run tests

-
+
+

run tests

+

First make sure you build ck with the -DCK_TESTS=1 option. Then go to the build directory and type: @@ -396,9 +396,9 @@ go to the build directory and type:

-
-

test suite

-
+
+

test suite

+
$ ./test-ck -h
 ck test suite
@@ -416,9 +416,9 @@ flags:
 
-
-

manual

-
+
+

manual

+

ck's goal is to assist with the configuration file management. To that end it tries to provides a cli interface that is pretty straight-forward @@ -429,30 +429,31 @@ and intuitive. Example usage:

-
# initialize new ck
-$ ck init /path_to/where_you_want/your_configs/to_be \
+
# initialize new ck
+$ ck init /path_to/where_you_want/your_configs/to_be \
   /path_to/the_secret/directory
 
-# add emacs configs
-## primary config
+# add emacs configs
+## primary config
 $ ck add emacs ~/.emacs.d/orgconf.org -p
-## secret config, with passwords and naughty words
+## secret config, with passwords and naughty words
 $ ck add emacs ~/.emacs.d/accounts.org -s
-## and another one for emacs
+## and another one for emacs
 $ ck add emacs ~/.emacs.d/init.el
 
-# add tmux config
+# add tmux config
 $ ck add tmux ~/.tmux.conf -p
 
-# list the configs
+# list the configs
 $ ck list tree
 $ ck list paths -t lisp
 $ ck list programs -t python
+$ ck list -p emacs
 
-# search the configs
+# search the configs
 $ ck search search-term
-$ ck search "\"search term with spaces\""
-$ ck search "\(" #escape symbols
+$ ck search "\"search term with spaces\""
+$ ck search "\(" #escape symbols
 
@@ -468,9 +469,9 @@ of flags one has to pass to ck.

-
-

ck configuration

-
+
+

ck configuration

+

ck uses sqlite to index the configuration files. The init action creates a .ck directory (under $HOME) @@ -498,13 +499,13 @@ directory of your choice. Usage:

-
$ ck config ~/ ... # the default behaviour
+
$ ck config ~/ ... # the default behaviour
 
-# /someplace/else must exist or
-# the action following it must be init
+# /someplace/else must exist or
+# the action following it must be init
 $ ck conf /someplace/else ... 
 
-# same thing
+# same thing
 $ ck c /someplace/else ... 
 $ ck -c /someplace/else ... 
 
@@ -512,13 +513,13 @@ $ ck -c /someplace/else ...
-
-

Actions

-
+
+

Actions

+
-
-

init

-
+
+

init

+

or i or -i

@@ -540,17 +541,17 @@ Use init to initialize a new ck database. Usage:

-
# initialize new ck
-$ ck init /path_to/where_you_want/your_configs/to_be \
+
# initialize new ck
+$ ck init /path_to/where_you_want/your_configs/to_be \
   /path_to/the_secret/directory
 
-
-

add

-
+
+

add

+

or a or -a

@@ -584,24 +585,33 @@ sure to use the same name. Usage:

-
# add config to ck
+
# add config to ck
 $ ck add program_name config_path [-s] [-p]
 
-
-

list

-
+
+

list

+

or ls or l or -l

-List can show the paths or the programs that ck keeps track of. +List stuff ck knows about.

+

+You can use the keywords: +

+
    +
  • paths: to print all the paths ck tracks
  • +
  • programs: to print all the programs ck tracks
  • +
  • -p progName: (without the "<>") to print the paths of a specific program
  • +
+

With the flag -t and then one of the follwing types one can change the way the list is printed: @@ -614,7 +624,7 @@ the way the list is printed:

Using the keyword tree ck can list the configurations under their -corresponding program. +corresponding program, in a treelike structure.

@@ -622,24 +632,34 @@ Passing the -a flag will enable the listing of config attributes (secret It is best used with tree or plain paths.

+

+With the keyword ckconf ck will list it's own configuration values (in ckrc). +

+

Usage:

-
# list tree structure, with attributes
+
# list tree structure, with attributes
 $ ck list tree -a
-# list paths in python
+# list paths in python
 $ ck l paths -t python
-# list programs in lisp
+# list programs in lisp
 $ ck ls programs -t lisp
+# list emacs' configurations [with attributes]
+$ ck ls -p emacs [-a]
+# list bash configurations in lisp
+$ ck ls -p bash -t lisp
+# list ck configuration
+$ ck -l ckconf
 
-
-

search

-
+
+

search

+

or s or -s

@@ -660,13 +680,13 @@ To search for terms with spaces you have to put them in quotes. Usage:

-
# search for parenthesis
-$ ck search \(
-# search term with spaces
-$ ck search "This is a space"
-# both
-$ ck search "(add 2 4)"
-# and a normal one
+
# search for parenthesis
+$ ck search \(
+# search term with spaces
+$ ck search "This is a space"
+# both
+$ ck search "(add 2 4)"
+# and a normal one
 $ ck search alias
 
@@ -677,20 +697,20 @@ a different pattern matching program you can do it like so:

-
# with xargs
-$ ck ls paths | xargs grep -E 'A|B'
-# or in bash
-$ for i in $(ck ls paths); do grep -E 'A|B' $i; done
-# or in zsh
-$ for i ($(ck ls paths)) grep -E 'A|B' $i
+
# with xargs
+$ ck ls paths | xargs grep -E 'A|B'
+# or in bash
+$ for i in $(ck ls paths); do grep -E 'A|B' $i; done
+# or in zsh
+$ for i ($(ck ls paths)) grep -E 'A|B' $i
 
-
-

edit

-
+
+

edit

+

or e or -e

@@ -719,17 +739,17 @@ print the avaliable configurations and exit. Usage:

-
# suppose this is our ck instance
+
# suppose this is our ck instance
 $ ck list tree -a
 emacs:
 |- init.el
 |- accounts.el [s]
 |- orgconf.org [p]
 
-# edit the primary emacs config
+# edit the primary emacs config
 $ ck edit emacs
 
-# edit a specific emacs config, other than the primary
+# edit a specific emacs config, other than the primary
 $ ck edit emacs accounts.el
 
@@ -739,7 +759,7 @@ $ ck edit emacs accounts.el
-

Created: 2018-10-08 Mon 23:46

+

Created: 2018-10-09 Tue 20:53

Validate

diff --git a/README.org b/README.org index 446ff02..c03a093 100644 --- a/README.org +++ b/README.org @@ -112,6 +112,7 @@ Example usage: $ ck list tree $ ck list paths -t lisp $ ck list programs -t python + $ ck list -p emacs # search the configs $ ck search search-term @@ -200,7 +201,12 @@ Usage: *** list or ls or l or -l -List can show the *paths* or the *programs* that ck keeps track of. +List stuff ck knows about. + +You can use the keywords: +- *paths*: to print all the paths ck tracks +- *programs*: to print all the programs ck tracks +- *-p progName*: (without the "<>") to print the paths of a specific program With the flag *-t* and then one of the follwing types one can change the way the list is printed: @@ -209,11 +215,13 @@ the way the list is printed: - *lisp*: print like a lisp list Using the keyword *tree* ck can list the configurations under their -corresponding program. +corresponding program, in a treelike structure. Passing the *-a* flag will enable the listing of config attributes (secret or primary). It is best used with tree or plain paths. +With the keyword *ckconf* ck will list it's own configuration values (in ckrc). + Usage: #+BEGIN_SRC sh # list tree structure, with attributes @@ -222,6 +230,12 @@ Usage: $ ck l paths -t python # list programs in lisp $ ck ls programs -t lisp + # list emacs' configurations [with attributes] + $ ck ls -p emacs [-a] + # list bash configurations in lisp + $ ck ls -p bash -t lisp + # list ck configuration + $ ck -l ckconf #+END_SRC *** search diff --git a/src/actionhelper.c b/src/actionhelper.c index 3e898af..582333e 100644 --- a/src/actionhelper.c +++ b/src/actionhelper.c @@ -149,15 +149,12 @@ void add_make_link(const AddOpt *opt, const Conf *conf) { } } -int edit_make_options(cklist *args) { - UNUSED(args); -} - ListOpt list_make_options(cklist *args) { list_rewind(args); ListOpt listOpt = { ._lt = LT_NONE, ._lst = LST_PLAIN, + .pName = NULL, .attr = 0, .err = 0 }; @@ -195,8 +192,21 @@ ListOpt list_make_options(cklist *args) { else if (strcmp(list_get(args), "tree") == 0) { listOpt._lt = LT_TREE; } + else if (strcmp(list_get(args), "ckconf") == 0) { + listOpt._lt = LT_CKCONF; + } + else if (strcmp(list_get(args), "-p") == 0) { + if (list_next(args)) { + listOpt._lt = LT_PROG_CONFS; + listOpt.pName = list_get(args); + } + else { + listOpt.err = 1; + break; + } + } else { - listOpt.err = 1; + listOpt.err = 1; } } while(list_next(args)); } @@ -240,7 +250,6 @@ void print_LIST_result(int err) { if (!err) { return; } - ERR("Wrong list arguments"); } void print_SEARCH_result(int err) { diff --git a/src/actionparser.c b/src/actionparser.c index 7c1186a..1da1d2f 100644 --- a/src/actionparser.c +++ b/src/actionparser.c @@ -130,7 +130,7 @@ int parse_EDIT(UserOpt *opt) { int parse_LIST(UserOpt *opt) { /* List expects a maximum of than 3 arguments */ - if (optNum <= pos || optNum > pos + 4) { + if (optNum <= pos || optNum > pos + 5) { opt->err = PERR_LIST_WRONG; return -1; } @@ -329,13 +329,13 @@ void print_parser_error(UserOpt *opt) { sprintf(errStr, "Add config \nUsage: %s ProgramName ConfigPath [-s](secret) [-p](primary)", names); break; case PERR_DEL_WRONG: - sprintf(errStr, "Delete config or program\nUsage: %s ....", names); + sprintf(errStr, "Delete config or program\nUsage: %s {ProgramName} | {-c ConfigPath (as shown by ck list)}", names); break; case PERR_EDIT_WRONG: sprintf(errStr, "Edit config with $EDITOR (%s)\nUsage: %s ProgramName [configBasename]", getenv("EDITOR"), names); break; case PERR_LIST_WRONG: - sprintf(errStr, "List programs, configs and more\nUsage: %s value-to-list (or tree) [-t list-type] [-a]", names); + sprintf(errStr, "List programs, configs and more\nUsage: %s {programs|paths|-p ProgramName} [-t list-type] | {tree | ckconf} [-a]", names); break; case PERR_SEARCH_WRONG: sprintf(errStr, "Search through the configs with grep\nUsage: %s search-term", names); @@ -344,7 +344,7 @@ void print_parser_error(UserOpt *opt) { sprintf(errStr, "Usage: ........"); break; } - ERR("%s", errStr); + HELP("%s", errStr); } void print_parser_help() { diff --git a/src/actions.c b/src/actions.c index 4ff6816..1b4c9b5 100644 --- a/src/actions.c +++ b/src/actions.c @@ -134,8 +134,11 @@ int run_EDIT(UserOpt *opt, Conf *conf) { /* If the program has many configs */ else { HELP("Ambiguous config. Please type the config name after the program."); - cklist *paths = list_make_new(); - edit_get_avaliable_paths(&db, paths, pName); + char name[STR_M] = ""; + strcat(name, pName); + strcat(name, ":"); + cklist *paths = list_make_and_add(name); + get_program_paths(&db, paths, pName, 1, 0); list_print(paths); list_free(paths); goto error; @@ -147,8 +150,11 @@ int run_EDIT(UserOpt *opt, Conf *conf) { char *cName = list_get(opt->args); if (edit_get_config(&db, pName, confName, cName, &secret)) { ERR("Program %s doesn't have a config named %s", pName, cName); - cklist *paths = list_make_new(); - edit_get_avaliable_paths(&db, paths, pName); + char name[STR_M] = ""; + strcat(name, pName); + strcat(name, ":"); + cklist *paths = list_make_and_add(name); + get_program_paths(&db, paths, pName, 1, 0); list_print(paths); list_free(paths); goto error; @@ -171,7 +177,6 @@ int run_EDIT(UserOpt *opt, Conf *conf) { } int run_LIST(UserOpt *opt, Conf *conf) { - UNUSED(conf); DB db = open_DB(opt); if (db.ptr == NULL) { if (db.error == SQL_ERR_NO_TABLES) { @@ -186,6 +191,7 @@ int run_LIST(UserOpt *opt, Conf *conf) { if (listOpt.err) { goto error; } + char tmp[STR_L] = ""; switch(listOpt._lt) { case LT_PATH: list_get_paths(&db, the_list, listOpt.attr); @@ -197,6 +203,27 @@ int run_LIST(UserOpt *opt, Conf *conf) { list_get_path_program_tree(&db, the_list, listOpt.attr); list_print(the_list); goto close; + case LT_CKCONF: + strcat(tmp, "ck configuration directory path: "); + strcat(tmp, opt->confDir); + list_add(the_list, tmp); +#define X(var, str, name) \ + strcpy(tmp, ""); \ + strcat(tmp, name); \ + strcat(tmp, ": "); \ + strcat(tmp, conf->var); \ + list_add(the_list, tmp); + CONFIG_VARIABLES_TABLE; +#undef X + list_print(the_list); + goto close; + case LT_PROG_CONFS: + if (!program_exists(&db, listOpt.pName)) { + ERR("Program %s doesn't exist in the database.", listOpt.pName); + goto error; + } + get_program_paths(&db, the_list, listOpt.pName, 0, listOpt.attr); + break; case LT_NONE: goto error; } diff --git a/src/actions.h b/src/actions.h index c9da4fb..624ae30 100644 --- a/src/actions.h +++ b/src/actions.h @@ -56,10 +56,12 @@ struct DelOptions { typedef enum ListTypes ListType; enum ListTypes { + LT_NONE, LT_PATH, LT_PROGRAM, LT_TREE, - LT_NONE, + LT_CKCONF, + LT_PROG_CONFS }; typedef enum ListShowTypes ListShowType; @@ -73,6 +75,7 @@ typedef struct ListOptions ListOpt; struct ListOptions { ListType _lt; ListShowType _lst; + char *pName; int attr; int err; }; diff --git a/src/dblayer.c b/src/dblayer.c index 4290a7a..973d561 100644 --- a/src/dblayer.c +++ b/src/dblayer.c @@ -478,9 +478,10 @@ int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int sqlite3_finalize(stmt); return flag; } + return -1; } -int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName) { +int get_program_paths(DB *db, cklist *ckl, const char* pName, int bname, int attr) { int pid = get_program_id(db, pName); /* error */ if (pid == -2) { @@ -493,6 +494,10 @@ int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName) { int rc; char selection[STR_M] = COL_CONFIG_PATH; + strcat(selection, ","); + strcat(selection, COL_CONFIG_SECRET); + strcat(selection, ","); + strcat(selection, COL_CONFIG_PRIMARY); char condition[STR_M] = TBL_PROGRAM; strcat(condition, "."); strcat(condition, COL_PROGRAM_ID); @@ -506,21 +511,32 @@ int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName) { return -2; } - char name[STR_M] = ""; - strcat(name, pName); - strcat(name, ":"); - list_add(ckl, name); while (sqlite3_step(stmt) == SQLITE_ROW) { char *tmp = strdup((char *)sqlite3_column_text(stmt, 0)); char entry[STR_M] = ""; - strcat(entry, "|- "); - strcat(entry, basename(tmp)); + if (bname) { + strcat(entry, basename(tmp)); + } + else { + strcat(entry, tmp); + } + if (attr) { + /* secret */ + if (sqlite3_column_int(stmt, 1)) { + strcat(entry, " [s]"); + } + /* primary */ + if (sqlite3_column_int(stmt, 2)) { + strcat(entry, " [p]"); + } + } list_add(ckl, entry); free(tmp); } sqlite3_finalize(stmt); return 0; } + return -1; } int list_get_paths(DB *db, cklist *ckl, int attr) { @@ -732,15 +748,11 @@ int get_program_relations(DB *db, int pid) { int get_config_number(DB *db, char* pName) { int pid = get_program_id(db, pName); - /* error */ - if (pid == -2) { - return -1; - } - /* program exists */ if (pid > -1) { return get_program_relations(db, pid); } + return -1; } /* Removes the relationship of `cid` with the corresponding program. diff --git a/src/dblayer.h b/src/dblayer.h index 05ba5bd..c99f143 100644 --- a/src/dblayer.h +++ b/src/dblayer.h @@ -43,6 +43,7 @@ extern DB open_DB(const UserOpt *opt); extern void close_DB(DB *db); extern int program_exists(DB *db, const char *pName); +extern int get_program_paths(DB *db, cklist *ckl, const char* pName, int basename, int attr); /********/ /* init */ @@ -66,7 +67,6 @@ extern int add_transaction_try(DB *db, const AddOpt * const opt); extern int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secret); extern int get_config_number(DB *db, char *pName); extern int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec); -extern int edit_get_avaliable_paths(DB *db, cklist *ckl, const char* pName); /********/ /* list */ -- cgit v1.2.3