rdd-howto – step-by-step introduction to rdd(1).
Description
rdd(1) takes user-described libraries, constructs executable script from them and launches. Data used inside the script and list of called functions are given by a user (in command line or config files). Script construction and launch can be repeated several times, if a user wants to launch his code for the series of objects.
Hello, world!
hello.sh
main() { printf "%s\n" "Hello, world!" }
rdd.def
[first] rdd_map_libs = shell hello.sh
And launch this:
$ rdd first object main
The result you should see:
Hello, world!
Now we'll see what lies behind all that.
First to mention is no function calls inside hello.sh.
There is only implementation of main.
Note the absence of shebang #!/bin/sh in hello.sh
as well (and no execution permissions on file).
The next file rdd.def
contains some data in INI format.
The name first
of data section is arbitrary. It contains variables, describing properties of the code we want to use.
The variable rdd_map_libs
contains files with the used code. First word-specificator tells the file is written in shell
language.
Our library is assigned without absolute path - in that case path is interpreted as relative to the root of working directory.
Launch string has the following meaning.
$ rdd first object main
first is the name of the data section we chose to use in the launch. Input data for our script code is calculated from here. The argument is the adjective of the launch.
object is the name of some entity we operate on. Objects are needed, when one repeats his actions in cycle for some list, and each entry of the list may define it's custom properties. The argument is the noun of the launch.
main is the name of the shell function we launch. The argument is the verb of the launch.
Each of the three main parameters above can be given explicitly by variable.
- rdd_prf_entry is the name of data section.
- rdd_list_entry is the name of used objects.
- rdd_map_entry is the name of the launched function.
Now let's shorten the launch string and save all parameters to config file.
rdd.def
for short command string:
[first] rdd_map_entry = main rdd_list_entry = object rdd_map_libs = shell hello.sh
With key data, saved inside config, the launch looks like:
$ rdd firstParameter first to initialise rdd_prf_entry is still required, as we need to know data section, which contains all other necessary data.
The variant with two arguments is also possible:
$ rdd first objectFunction name is ommitted with two arguments given.
Hello, friends
hello.sh with friends:
hello_print() { printf "%s\n" "Hello, ${rdd_atom_id}" } hello_length() { hello_print | wc -c } hello_profiled_print() { printf "%s" "${rdd_prf_entry}: " hello_print } hello_all() { hello_print hello_length }
Launch string with several values:
$ rdd first thing,more_thing hello_print,hello_lengthAnd the result:
Hello, thing 13 Hello, more_thing 18Here one can see the launch of two functions hello_print and hello_length.
Moreover, they are called twice: for the object thing and more_thing.
The code also demonstrates simple usage of input data, described above, inside functions.
Let's extend our configuration file also.
rdd.def
with several data sections:
[first] rdd_map_entry = hello_print, hello_length rdd_list_entry = thing, more_thing rdd_map_libs = shell hello.sh [second] rdd_map_entry = hello_profiled_print, hello_length rdd_list_entry = thing, more_thing, side_thing rdd_map_libs = shell hello.sh
Launch the example:
$ rdd firstAnd the result, same as the previous one:
Hello, thing 13 Hello, more_thing 18
Change the name for argument:
$ rdd secondThe result:
second: Hello, thing 13 second: Hello, more_thing 18 second: Hello, side_thing 18All parameters are hidden in config now, and we can manage launches with short command line.
Data combination
To get rid off that, we can combine data sections.
rdd.def with structured data sections
[first] rdd_map_entry = hello_print, hello_length rdd_list_entry = thing, more_thing rdd_prf_id = shell [second] rdd_map_entry = hello_profiled_print, hello_length rdd_list_entry = thing, more_thing, side_thing rdd_prf_id = shell [shell] rdd_map_libs = shell hello.shThe launch and results remain the same:
$ rdd first
Hello, thing 13 Hello, more_thing 18
$ rdd second
second: Hello, thing 13 second: Hello, more_thing 18 second: Hello, side_thing 18
But this time we describe the data only once. Lang variables reside in separate section, and first
and second
sections include it.
To use some data section inside other section, rdd_prf_id
is used.
The command line equivalent for data inclusion is:
$ rdd first,shell
Define more data sections to include several ones at once and see their priorities.
rdd.def for chainloading
[add_some] last_data = some uniq_some_data = qwerty [add_another] last_data = another uniq_another_data = asdfgh [first] rdd_map_entry = hello_print, hello_length,add_print rdd_list_entry = thing, more_thing rdd_prf_id = shell [second] rdd_map_entry = hello_profiled_print, hello_length rdd_list_entry = thing, more_thing, side_thing rdd_prf_id = shell [shell] rdd_map_libs = shell hello.sh, shell add.sh
Note the appearence of the new library file add.sh and printing method add_print.
add.sh
add_print() { printf "%s\n" "${last_data}" printf "%s\n" "${uniq_some_data}" printf "%s\n" "${uniq_another_data}" }The launch:
$ rdd first,add_some,add_anotherThe result:
Hello, thing 13 another qwerty asdfgh Hello, more_thing 18 another qwerty asdfgh
The most right data section in the list (as in command line, so inside config file) has the highest priority.
Thus the variable last_data
is taken from section add_another
as the most right one in command line.
At the same time non-overlapping variables uniq_some_data
and uniq_another_data
were gathered each from its own section.
rdd_prf_id
is not redefined, when mentioned in several sections.
Instead all mentioned sections are summarised and each met section is included.
The same data can be given in three forms, first has the most priority.
Options in command line:
$ rdd first some_var=valueValue in rdd.def file
Value in *.conf file inside rdd.conf.d/ dir at the root of working copy
To list all gathered data, datardd(1) is used:
$ datardd first
rdd_atom_id=thing rdd_list_entry=thing, more_thing rdd_map_libs=shell hello.sh, shell add.sh rdd_map_entry=hello_print, hello_length,add_print rdd_prf_all=shell,first rdd_prf_entry=firstThe output contains one set of data regardless of quantity of objects in configuration.
Objects and lists
rdd_list_path variable contains path to directory with such lists.
$ echo 'rdd_list_path = buildfiles' >> rdd.defWhen lists are set up, they can be used as:
$ rdd first,add_some list.srcwith example content of buildfiles/list.src
thing # comments are ingored # as well as empty strings more_thing
Lists can be nested, thus some list may contain another lists.
To show resulting list of objects, lsrdd(1) is used.
$ lsrdd first list.src
thing more_thing
Object may store their custom data.
rdd_atom_path
variable contains path to directory with atom data.
$ echo 'rdd_atom_path = atomfiles' >> rdd.defData of objects now is checked up in corresponding file atomfiles/NAME/atom.conf.
Priority of data from atom.conf is between rdd.conf.d/ and rdd.def.
Used example above will not demonstrate the data from atom.conf, as it stores all data in rdd.def with higher priority.
Script dumps
$ rdd first,add_some thingDumped scripts for all launches reside in var/dump/ directory.
For the launch above scripts lie in var/dump/thing_first_add_some/.
Note the name of final personal dir: it contains name of the object and data sections, given in command line, first and add_some. It does not contain section shell in the name, though the section is in use. That's because minimal identification for resulting data in dir name is used.
First essential file in dump dir is var/dump/thing_first_add_some/dump.sh.
It contains all the data and inclusion of libraries, declared for use in configs.
The file does not contain any calls. Its purpose is to make available needed data and functions to the scripts, doing nothing on itself.
var/dump/thing_first_add_some/dump.sh
last_data="some" rdd_atom_id="thing" rdd_list_entry="thing" rdd_list_path="buildfiles" rdd_map_libs="shell hello.sh, shell add.sh" rdd_map_entry="hello_print, hello_length,add_print" rdd_prf_all="shell,first,add_some" rdd_prf_entry="first,add_some" uniq_some_data="qwerty" . /home/user/poligon/hello.sh . /home/user/poligon/add.sh
Another essential file in dump dir is var/dump/thing_first_add_some/calldump.
It includes dump.sh
and calls all ordered functions.
This file is executed by rdd(1),
can be re-executed directly, saved and reused on regular purpose.
var/dump/thing_first_add_some/calldump
( #!/bin/sh < /dev/null . /home/user/poligon/var/dump/thing_first_add_some/dump.sh hello_print hello_length add_print )
See also
datardd(1), tool to output data from rdd config files.
dumprdd(1), tool to output language script, constructed from rdd config files.
droprdd(1), tool to write down script, constructed from rdd config files.
lsrdd(1), tool to output list of rdd objects.
rootrdd(1), tool to output root of rdd working directory.