-
Notifications
You must be signed in to change notification settings - Fork 123
Codegen: Ignore missing required keys in help mode #2944
Conversation
This comment has been minimized.
This comment has been minimized.
@@ -80,6 +80,10 @@ The following section lists news about the [modules](https://www.libelektra.org/ | |||
|
|||
- We now treat relative paths as relative to `KDB_DB_SPEC` instead of the current working directory. _(Klemens Böswirth)_ | |||
|
|||
### Spec | |||
|
|||
- There is now the config key `missing/log` that allows logging of all missing `require`d keys. _(Klemens Böswirth)_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we fail if a required key is missing? Why do we need the log as this should already be part of the error message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec
can be configured to ignore some or all errors. I don't really know why, but it's always been the case.- This is needed for the case where a program using the codegen API is called in "help mode", i.e.
app -h
orapp --help
. In such a case, we want to ignore missing required keys and simply print the help message.
How themissing/log
array helps detect this case, is documented in the relevant code:
libelektra/src/libs/highlevel/elektra.c
Lines 143 to 158 in ea74e58
Key * helpKey = ksLookupByName (config, "proc/elektra/gopts/help", 0); const Key * missingKeys = keyGetMeta (parentKey, "logs/spec/missing"); if (ignoreRequireInHelpMode == 1 && helpKey != NULL && missingKeys != NULL) { // proc/elektra/gopts/help was set -> we are in help mode // logs/spec/missing exists on parentKey -> spec detected missing keys // we ensured that spec uses conflict/get = ERROR -> the error in kdbGet must be from spec // --> we are in the error case that should be ignored // BUT: anything other than helpKey may be incorrect // and only helpKey should be used anyway // so create a new config KeySet Key * helpKeyDup = keyDup (helpKey); ksClear (config); ksAppendKey (config, helpKeyDup); }
There could technically be other problems from thespec
plugin as well, but sincegopts
runs first and was successful, there can't be any errors that would break the help message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec can be configured to ignore some or all errors. I don't really know why, but it's always been the case.
This is one of spec's anti-features. Thank you for documenting it but I would be in favor of removing these anti-features. If validation fails, the plugin should return an error.
This is needed for the case where a program using the codegen API is called in "help mode"
Ok. But wouldn't it be better to directly ask for a meta-key which says that we are in the help mode? We want the help to be printed no matter what errors happened in kdbOpen
or kdbGet
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If validation fails, the plugin should return an error.
IMO the option to switch to warnings instead might be useful.
- it allows spec to report more then one problem at once
- sometimes ignoring a problem is fine or even intended (e.g. when fixing the problem)
I agree, however, that ignoring all problems by default is bad. I think it was done, so that problems can still be fixed via kdb
, which would fail, if there are warnings or errors.
But wouldn't it be better to directly ask for a meta-key which says that we are in the help mode?
We are doing that. gopts
creates the key proc/elektra/gopts/help
, if we are in help mode. It is the key that was passed to elektraGetOpts
, which contains data for the help message.
We want the help to be printed no matter what errors happened in kdbOpen or kdbGet.
I thought about that, but I am not sure this is possible. Ignoring all errors from spec
should be fine, since gopts
already ran at that point. But ignoring all errors (no matter from where) could be problematic. Ignoring only missing required keys was the safest solution.
Required keys must be provided by the user/admin and cannot come from another source (Elektra, app developer, etc.). Therefore they will be missing until the user makes changes to the KDB. Before that, no other error should occur (°). If a user runs app
for the first time and receives an error about a missing required key, will:
- Know what to do and add the key, thereby fixing the problem.
- Try
app -h
/app --help
to find out more. The help message may or may not contain useful information. If not they may try 3. - Read some other documentation to find out more. Ideally this leads them to 1.
In any case after this the user definitely know how to interact with the KDB. Since we assumed that there won't be any errors before the KDB was changed, we can assume that the user caused other errors by changing the KDB.
Of course it would be nice to always show the help message, but since it depends on the specification being readable, that is somewhat impossible. One way around that (at least in applications using codegen) is to generate a fallback help message that is used, if we couldn't read the spec. This fallback help message would be based on the spec provided to the code generator. It would therefore not reflect any changes to the spec (e.g. description
or opt/help
) that the user made.
(°) assuming a correct installation. But broken installations cannot be ignored anyway, since they may interfere with the help message that is generated from the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it allows spec to report more then one problem at once
This would also be possible if the first error is as error and the others as warning.
sometimes ignoring a problem is fine or even intended (e.g. when fixing the problem)
We usually only add warnings during kdbGet() and errors only in kdbSet(). I would also expect that behavior in the spec plugin. We should document this behavior in a decision.
I thought about that,
Very nice write-up. Can you make a decision of what you wrote here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually only add warnings during kdbGet()
There are many cases, where kdbGet()
should return an error. The best example would be a broken storage file. The storage plugin should return an error and kdbGet()
should abort.
For the spec
plugin, it probably makes sense to have to option of switching between warnings and errors. In kdb
(and other configuration tools) warnings would be preferred, as a kdbGet()
is required before a kdbSet()
could fix the problems. In applications on the other hand errors are the better solution. They are easier to detect, since kdbGet()
uses a different return code for errors. The handling of actual errors is also easier in the high-level API (see #2952).
Can you make a decision of what you wrote here?
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note: The fallback help message only works with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR! I am not happy about hardcoded -h
and --help
but otherwise it is a nice PR.
## Assumptions | ||
|
||
- We assume that the application in question was correctly installed. | ||
- We assume `gopts` was mounted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this already default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gopts
is not mounted by default no. However, the file generated by the highlevel
template, include a kdbEnsure
contract, that mounts it, if it is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please copy this sentence into the decision.
|
||
libelektra_0.9 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should have been part of #2916. The functions were not part of any 0.8.x release, so they should not be versioned as libelektra_0.8
.
If we won't have another 0.9.x release and go straight to 1.0.0, they should actually be in libelektra_1.0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will definitely have a 0.9 release before 1.0.
@@ -43,6 +72,7 @@ int elektraGOptsGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * pa | |||
ksNew (30, keyNew ("system/elektra/modules/gopts", KEY_VALUE, "gopts plugin waits for your orders", KEY_END), | |||
keyNew ("system/elektra/modules/gopts/exports", KEY_END), | |||
keyNew ("system/elektra/modules/gopts/exports/get", KEY_FUNC, elektraGOptsGet, KEY_END), | |||
keyNew ("system/elektra/modules/gopts/exports/ishelpmode", KEY_FUNC, elektraGOptsIsHelpMode, KEY_END), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isinhelpmode or simply helpmode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you already merged this PR: Do you still want the change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was only a question. If you like ishelpmode best, we can keep it.
|
||
for (int i = 0; i < argc; ++i) | ||
{ | ||
if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not like that this is hardcoded here. -H
is very common (and also used in the kdb
tool). -h
has man other meanings.
Furthermore this is not properly parsed, e.g. -vh
would not be recognized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not like that this is hardcoded here.
-H
is very common (and also used in thekdb
tool).-h
has man other meanings.
Using -h
/--help
for help mode is already hard-coded in elektraGetOpts
(there it is properly parsed).
This function is not actually intended to accurately detect help mode (for that one should still check for the presence of proc/elektra/gopts/help
. It is only meant in case kdbGet()
failed.
Apart from kdb
tool, I have never seen -H
used in favour of -h
. The kdb
tool also takes a very unusual approach, since it opens the man-page instead of printing to stdout/stderr.
In fact most tools I know, use only --help
(if they support long options).
Furthermore this is not properly parsed, e.g.
-vh
would not be recognized.
See above #2944 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from kdb tool, I have never seen -H used in favour of -h.
Because of how the cmdline options in Elektra are implemented every option needs to have a short option. -H
was the most natural one as -h
is already "human readable".
The kdb tool also takes a very unusual approach, since it opens the man-page instead of printing to stdout/stderr.
It makes a lot of sense to not have a --help output and a separated man page. E.g. git also does it this way.
In fact most tools I know, use only --help (if they support long options).
I would prefer if we only hardcode --help
and drop support for -h
.
Thank you! |
Please make sure that such notes are documented in the documentation. Here nobody will read it. |
It is documented in the doxygen comment for |
Sorry, I do not see it. You mean src/plugins/gopts/gopts.c line 37-44? |
Yes |
If the user starts an application that has required keys with
-h
/--help
, it would result in an error and the help message wouldn't be printed. This changes that.It also adds the regenerated man page that is missing from #2942 (should've been part of
b18447e).
Basics
doc/news/_preparation_next_release.md
which contains_(my name)_
)Please always add something to the the release notes.
(first line should have
module: short statement
syntax)close #X
, should be in the commit messages.Checklist
Review