Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kdb rewrite base #4943

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8b39708
kdb-cli: add new main.c
hannes99 May 2, 2023
386b8ea
kdb-cli: add helper functions
hannes99 Sep 21, 2022
4f1c366
shell_recorder: add support for C cli warning/error format
hannes99 May 6, 2023
1561c10
kdb-cli: rewrite get command
hannes99 Sep 21, 2022
e252d68
kdb cli: add spec for c++ commands
hannes99 May 27, 2023
c96162a
CI: add line plugin to debian-bullseye-full-xdg build
hannes99 May 29, 2023
00df54b
kdb cli: add support for external commands, with and without spec
hannes99 May 27, 2023
0616860
kdb-cli: rewrite set
hannes99 Mar 1, 2023
0c97078
kdb: fix newline problem for record commands
hannes99 Jun 13, 2023
833ddc4
kdb: add more extensive help message for command misuse
hannes99 Jun 13, 2023
e05ca3d
doc: add tutorial for implementing a new command for kdb in C
hannes99 Jun 13, 2023
c938a25
Restyled by prettier-markdown
restyled-commits Jun 13, 2023
8b284a6
doc: add missing link
hannes99 Jun 13, 2023
4673c72
doc: opts: add that help message is now always generated
hannes99 Jun 14, 2023
5ee6a1c
doc: improve add-new-command tutorial
hannes99 Jun 14, 2023
0ef3013
kdb: fix memory leak when printing help message
hannes99 Jun 14, 2023
e21f235
Restyled by clang-format
restyled-commits Jun 14, 2023
d9b4eeb
Restyled by prettier-markdown
restyled-commits Jun 14, 2023
d90d6f1
kdb: move GET_OPTION and GET_OPTION_KEY to command.h
hannes99 Jun 16, 2023
29906e1
lib/kdb: add ELEKTRA_CLI_ERROR category
hannes99 Jun 16, 2023
515a13c
remove old merge-command leftovers
hannes99 Jun 16, 2023
7053e6b
doc: fix formatting/spelling problems
hannes99 Jun 16, 2023
6233506
fixup! lib/kdb: add ELEKTRA_CLI_ERROR category
hannes99 Jun 16, 2023
fbcc5a1
kdb: add test for external command specification
hannes99 Jun 17, 2023
fe6ba2e
kdb: add mountOdbc spec
hannes99 Jul 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ kdb get user:/tests/hello

kdb get user:/tests/hello/does/not/exist
# RET: 11
# STDERR: [Dd]id not find key 'user:/tests/hello/does/not/exist'
# STDERR: .*[Dd]id not find key 'user:/tests/hello/does/not/exist'

kdb rm user:/tests/hello
```
Expand Down
1 change: 1 addition & 0 deletions doc/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ It complements the man pages found [here](/doc/help).
## Internals

- [Algorithm](algorithm.md)
- [Add C command to KDB](kdb-add-new-command.md)
- [Plugins Ordering](plugins-ordering.md)
- [KDB Operations](kdb-operations.md)
10 changes: 10 additions & 0 deletions doc/dev/error-categorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ the values (`enum` plugin), etc.
Users should try a different value or fix the underlying specification and retry
again.

#### CLI ("C03300", concrete)

Command Line Interface (CLI) Errors are errors that occur due to problematic interactions with the application via the command line.
These types of errors typically involve an issue with the user's input or a misunderstanding of the application's expected command structure and specifications.

The primary focus of this category is on correctly executing command line instructions and ensuring communication between the user and the application is as intended.
CLI errors can occur when users attempt to execute commands that do not align with the application's requirements, despite the command's syntactical correctness.

By correctly categorizing and handling CLI errors, developers can improve the application's usability and robustness, ensuring accurate responses to user commands and better overall command line experience.

## Underlying design decision document

- [Decision Document](../decisions/6_implemented/error_codes.md) The underlying design
Expand Down
171 changes: 171 additions & 0 deletions doc/dev/kdb-add-new-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Implement new commands in C

Here we'll go over the basic requirements to implement a new command in C and integrate it in to the `kdb` CLI framework.

## 1. Files

First we need a header as well as a c file for the new command in `src/tools/kdb`.

### Header

The `<name>.h` has to look something like this:

```c
/**
* @file
*
* @brief Header for ... command
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*/

#ifndef ELEKTRA_KDB_..._H
#define ELEKTRA_KDB_..._H

#include <kdb.h>

/**
* Adds options specification of complete command to @spec
*
* @param spec the base spec where the commands spec should be added
*/
void add...Spec (KeySet * spec);

/**
* Executes the ... command
*
* @param options cli options and arguments as specified in addCompleteSpec()
* @param errorKey key where errors and warnings should be saved
*
* @retval 0 ... command ran without errors
* @retval 1 errors occurred, keyGetMeta (errorKey, "error/reason") for info
*
*/
int exec... (KeySet * options, Key * errorKey);

#endif // ELEKTRA_KDB_..._H
```

### `C` file

The `<name>.c` has to implement the two functions already described in the header file, in addition to those `COMMAND_NAME` has to be defined before `#include <command.h>`.
This is important because macros defined in `command.h` depend on `COMMAND_NAME` being defined.

```c
#define COMMAND_NAME "..." // your command name
...
#include <command.h>
...
```

In addition to `command.h`, it should also `#include <colors.h>`.
`command.h` and `colors.h` contain all the needed helper macros and functions.

#### Specification

`void add...Spec (KeySet * spec)` will contain the specification (for `elektraGetOpts`) of the new command.
It has to append it to the passed `KeySet * spec`, the framework will call this function to register its specification.
The function could look something like this:

```c
void addGetSpec (KeySet * spec)
{
ksAppendKey (spec, keyNew (COMMAND_SPEC_KEY (COMMAND_NAME), KEY_META, "description", "Get the value of an individual key.",
KEY_META, "command", COMMAND_NAME, KEY_END));
ksAppendKey (spec, keyNew (COMMAND_SPEC_KEY (COMMAND_NAME) "/all", KEY_META, "description", "Consider all of the keys", KEY_META,
"opt", "a", KEY_META, "opt/long", "all", KEY_META, "opt/arg", "none", KEY_END));
ksAppendKey (spec, keyNew (COMMAND_SPEC_KEY (COMMAND_NAME) "/name", KEY_META, "description", "The name of the key", KEY_META,
"args", "indexed", KEY_META, "args/index", "0", KEY_END));

ADD_BASIC_OPTIONS (spec, COMMAND_SPEC_KEY (COMMAND_NAME))
}
```

The `ADD_BASIC_OPTIONS` at the end adds options that are common across all commands to its spec, this includes things like `verbose: -v` or `debug: -d`.

#### Execution

The `int exec... (KeySet * options, Key * errorKey)` receives two parameters, `options` and `errorKey`.
Where `options` contains the passed options (as parsed by `elektraGetOpts`) and arguments and `errorKey` is where any errors or warnings have to be written to so the framework can properly print them.
It should start with the `GET_BASIC_OPTIONS` macro, this sets everything up needed for logging(and logging level), basic options and colored printing.
So afterward `CLI_PRINT` and `CLI_ERROR_PRINT` can be used.
When returning for the `exec` function the `RETURN (n)` macro should be used, it makes sure things allocated by `GET_BASIC_OPTIONS` are freed properly.
A basic version of this function could look something like this:

```c
int ret = 0;
hannes99 marked this conversation as resolved.
Show resolved Hide resolved
GET_BASIC_OPTIONS

bool all = false;
tmp = GET_OPTION_KEY (options, "all");
if (tmp != NULL)
{
elektraKeyToBoolean (GET_OPTION_KEY (options, "all"), &all);
keyDel (tmp);
}

...

Key * toLookUp = getKeyFromOptions (GET_OPTION (options, "name"), errorKey, verbose);
if (toLookUp == NULL)
{
RETURN (2)
}

...

if (found == NULL)
{
CLI_ERROR_PRINT (CLI_LOG_NONE, "Did not find key '%s'", RED (keyName (toLookUp)));
ret = 11;
goto cleanup;
}

if (keyGetNamespace (found) == KEY_NS_DEFAULT)
{
CLI_PRINT (CLI_LOG_VERBOSE, "The key was not found in any other namespace, taking the %s\n", BOLD ("default"));
}

...

cleanup:
...

RETURN (ret)
```

For getting keys from arguments the helper function `getKeyFromOptions` can the used.
It will resolve bookmarks and make sure the argument is a valid keyname.

## 2. Output

All output in the `exec` function should be done using either `CLI_PRINT` or `CLI_ERROR_PRINT` with the appropriate logging level.
Available logging levels are `CLI_LOG_NONE`, `CLI_LOG_VERBOSE` and `CLI_LOG_DEBUG`.
By using `CLI_PRINT` or `CLI_ERROR_PRINT` logging levels are handled automatically.

## 3. Errors/Warning

If errors occur during the execution of your command, they should be set in `errorKey` and not printed directly.
This could look something like this:

```c
ELEKTRA_SET_INTERNAL_ERROR (errorKey, "could not copy key meta to errorKey");
hannes99 marked this conversation as resolved.
Show resolved Hide resolved
```

These error setting macros are available in `kdberrors.h`.
By setting the like this, they are later printed properly formatted by the framework.

## 4. "registering" the new command

You just have to `#include` your header file in [`main.c`](/src/tools/kdb/main.c) and add an element to the `command subcommands[]` array.

```c
command subcommands[] = {
...
{ "your-new-command-name", add...Spec, exec... },
};
```

## _5. Validate_

After following these steps the new command will show up when typing `kdb --help` and `kdb <your-cmd-name> --help` will show a usage message based on the specification you have provided in the `add...Spec` function.
4 changes: 1 addition & 3 deletions doc/help/kdb-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ subcommand can only remove a user's cache files (i.e. not system wide).
## OPTIONS

- `-H`, `--help`:
Show the man page.
Show usage of command.
- `-V`, `--version`:
Print version info.
- `-p`, `--profile <profile>`:
hannes99 marked this conversation as resolved.
Show resolved Hide resolved
Use a different kdb profile.
- `-C`, `--color <when>`:
Print never/auto(default)/always colored output.
- `-v`, `--verbose`:
Expand Down
99 changes: 0 additions & 99 deletions doc/help/kdb-cmerge.md

This file was deleted.

11 changes: 4 additions & 7 deletions doc/help/kdb-complete.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

## SYNOPSIS

`kdb complete [path]`
`kdb complete path`

Where `path` is the path for which the user would like to receive completion suggestion.
If `path` is not specified, it will show every possible completion. It's synonymous
to calling `kdb complete ""`.
Calling `kdb complete ""` will show every possible completion.
hannes99 marked this conversation as resolved.
Show resolved Hide resolved
hannes99 marked this conversation as resolved.
Show resolved Hide resolved

## DESCRIPTION

Expand All @@ -22,11 +21,9 @@ originates from.
## OPTIONS

- `-H`, `--help`:
Show the man page.
Show usage of command.
- `-V`, `--version`:
Print version info.
- `-p`, `--profile <profile>`:
Use a different kdb profile.
- `-C`, `--color <when>`:
Print never/auto(default)/always colored output.
- `-m`, `--min-depth <min-depth>`:
Expand Down Expand Up @@ -69,7 +66,7 @@ kdb complete user:/ --max-depth=1
# STDOUT-REGEX: .+

# list all possible namespaces or mount points, only the current level
kdb complete --max-depth=1
kdb complete "" --max-depth=1
# STDOUT-REGEX: .+

# list suggestions for /tests/complete/examples/kdb-complete, only the current level
Expand Down
4 changes: 1 addition & 3 deletions doc/help/kdb-convert.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ If either `import-file` or `export-file` are not specified, `stdin` and `stdout`
## OPTIONS

- `-H`, `--help`:
Show the man page.
Show usage of command.
- `-V`, `--version`:
Print version info.
- `-p`, `--profile <profile>`:
Use a different kdb profile.
- `-C`, `--color <when>`:
Print never/auto(default)/always colored output.
- `-v`, `--verbose`:
Expand Down
4 changes: 1 addition & 3 deletions doc/help/kdb-cp.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ This command will return the following values as an exit status:
## OPTIONS

- `-H`, `--help`:
Show the man page.
Show usage of command.
- `-V`, `--version`:
Print version info.
- `-p`, `--profile <profile>`:
Use a different kdb profile.
- `-C`, `--color <when>`:
Print never/auto(default)/always colored output.
- `-r`, `--recursive`:
Expand Down
4 changes: 1 addition & 3 deletions doc/help/kdb-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ The user should specify the format that the current configuration or keys are in
## OPTIONS

- `-H`, `--help`:
Show the man page.
Show usage of command.
- `-V`, `--version`:
Print version info.
- `-p`, `--profile <profile>`:
Use a different kdb profile.
- `-C`, `--color <when>`:
Print never/auto(default)/always colored output.
- `-s`, `--strategy <name>`:
Expand Down