-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Feature: Compile-time Configuration Framework
Microdragon needs a compile-time configuration framework to simplify configuring the kernel for users and developers alike. Additionally a command line tool should be made to simplify configuring the kernel for end users who don't know or don't want to dig deeper into the kernel.
The Config.toml File
The configuration framework will add a new files to crates besides their Cargo.toml file. This Config.toml will contain the compile time configuration of the crate and it's schema is defined by how the crate uses it. Each crate should supply a default Config.toml with sane default values and comments describing each option.
The value! Macro
The configuration framework should supply a proc-macro value! that reads out a value from the config with an optional default if it's missing. The general syntax should be as follows:
value!($option:lit $(, $( $default:expr )?)?);
The second $option parameter has to be a string literal. If the macro parameters isn't given as displayed, a compile_error! with a descriptive message should be generated to fail compilation and notify the developer. The $option parameter is used to find which key to return from the config. It's a string literal allowing the same dotted key syntax as defined in the TOML spec to access values in the Config.toml. This syntax is slightly extended by allowing arrays to be accessed by tier index, so the second element of foo = [ "A", "B", "C" ] can be accessed using foo.2 returning "B". This also works for arrays of tables, so bar inside foo = [ { bar = 1 } ] can be accessed using foo.0.bar. Most data types are returned as their respective literals by this macro. Arrays and tables cannot be returned, doing so will generate a compile_error!. Date and time types are returned as ISO-8601 formatted strings, assuming the build computer's local time zone. It is recommended to cache the Config.toml to prevent further disk I/O.
The #[config(...)] Macro
A version of the built-in #[cfg(...)] macro that reads it's values out of the Config.toml. Similar to it's built-in counterpart, it can use any(...), all(...) and not(...) to match multiple options and invert options. For actually matching an option, a syntax similar to the built-in is used, but instead of a simple identifier, the dotted notation as described above can be used, with one exception. Only quoted keys with " are allowed due to the way that rust macros work. For the matching option not only strings, but any literal should be supported, using the same conversion as described above for the value! macro. If the type of the resolved key is a bool, the the = true/false can be left out in which case the option matches, if the resolved bool is true.
The #[config_attr(..., ...)] Macro
A version of the built-in #[cfg_attr(...)] macro that reads it's values out of the Config.toml. It accepts the same syntax as described above for #[config(...)] as it's first parameter with the second being the attribute to insert, if the first parameter matches.
Configuration CLI
Finally a CLI tool should be crated to help configure the kernel for users who don't plant to delve too deep into the kernel's code and instead just want to configure and build the kernel, be it manual or automated with scripts. This CLI tool should support two modes of usage, one setting, getting and listing keys using command line arguments and another mode using a terminal UI.
Command Line Args Mode
The command line mode allows doing multiple operations at once, each returning one line in the result. The operations are as follows:
-s <key> <value>/--set <key> <value>- Sets the given
<key>to<value>in the current project's config. - The
<key>uses the same syntax as theconfig!macro. - The
<value>is type checked to have the same TOML data type as the existing value. - This operation prints a line of
<key> = <value>with the newly set<value>.
- Sets the given
-g <key>/--get <key>- Gets the given
<key>from the current project's config. - The
<key>uses the same syntax as theconfig!macro. - This operation prints a line of
<key> = <value>, with<value>being the value from the config.
- Gets the given
-l [key]/--list [key]- Lists the sub-keys of the given
[key]from the current project's config, if[key]is supplied. - List of key in the TOML root, if
[key]is missing. - This operation prints a line of
<key-1> <key-2> <key-3> ..., where<key-n>is one of the listed sub key.
- Lists the sub-keys of the given
-p <project-path>/--project <project-path>- Switches the current project to
<project-path>. - This is only valid if the tool is running in a cargo workspace, otherwise an error is returned.
- This operation prints no output.
- Switches the current project to
Terminal UI Mode
The terminal UI displays the config in a tree view, displaying a key's comment. The tree should be collapsed on start with the user expanding options they are interested in. The user should also be able to restrict their view onto a certain sub-tree, with the option to go back up a sub-tree restriction using a button press. Trying to go out of the root tree, will close the terminal UI. The key comments should be able to pick a widget for their option using a mnemonic line, otherwise a set of default widgets gets displayed. These mnemonic line are not displayed in the terminal UI. If the CLI is started in a cargo workspace, a tree of projects inside the workspace is displayed. Selecting a project, restricts the view onto that project's configuration tree. Trying to go out of that root tree will return the user back to the project select tree. Finally the terminal UI accepts some command line arguments too.
-p <project-path>/--project <project-path>- Makes the tool act as if it was opened in the given
<project-path>'s project, even though it is run in a cargo workspace. - This is only valid if the tool is running in a cargo workspace, otherwise an error is returned.
- Makes the tool act as if it was opened in the given
-r <key>/--restrict <key>- Restricts the displayed view to the given
<key>, similar to how the user could choose to. - If the terminal UI was opened with
-r, the restricted view acts as the root, so trying to get out of it will close the terminal UI. - If the terminal UI is run in a cargo workspace, this option additionally requires
-p.
- Restricts the displayed view to the given
Disambiguate -p <project-path>
The -p parameter is used in both command line mode and terminal UI mode. To disambiguate what mode should be used, the other arguments should be examined. If one of the unambiguous arguments is passed, -r for terminal UI mode and -s / -g / -l for command line mode, the corresponding mode should be use. If arguments from both modes are passed, the tool should error out with a message explaining the error. If only -p is passed, terminal UI mode should be assumed, since command line mode with only -p is basically a no-op.
Terminal UI Comment Mnemonics
Limit:- Takes an optional
<min>and an optional<max>in the form of<min> - <max>
- Takes an optional
Slider:- Takes the limits from
Limit:if present, but a custom range can be provided in the same format asLimit:
- Takes the limits from
Stepper:- Takes the limits from
Limit:if present, but a custom range can be provided in the same format asLimit: - After the optional limits, either a list of steps, separated by spaces, can be passed or an expression of
every <step>meaning the steps will be all values from the min to the max, increasing by<step>each time.
- Takes the limits from
Enum:- Following is a list of enum values per line in the format
<value> - <description>
- Following is a list of enum values per line in the format