overview
divifetch is a build-time fetch script compiler.
instead of fetching system information on each run and dynamically assembling the output like the other fetch scripts, divifetch generates a C source file from a config, which you can compile into a standalone binary.
this approach allows for the resulting code to be mostly hard-coded at generation time. this also allows for the resulting binary to not have any runtime dependencies, to not waste time reading a config file at startup and to be as small as it should be.
usage
./generator [OPTIONS] *source configs*
options
| option <argument> | description | |
|---|---|---|
-h, --help |
display this help and exit | |
-v --version |
display the version number and exit | |
-S, --source |
generate the fetch and header generator source code | |
-s <file> |
specify a config file for source (default: config.conf) | |
-os <file> |
specify where to output the source code of the fetch program (default: src/fetch.c) | |
-ohg <file> |
specify where to output the source code of the header file generator (default: src/header.c) | |
-oh <file> |
specify where to output the header file for the fetch program (default: src/fetch.h) | |
-B, --build |
generate a build script | |
-b <file> |
specify the config file for build (default: build.conf) | |
-ob <file> |
specify where to output the build script (default: build.vsh) | |
-R, --run |
execute the the build script | |
-r <file> |
specify arguments to execute the build script with | |
-C, --genconf |
generate generate an example config file | |
-oc <file> |
specify where to output the example config (default: config.conf) |
if multiple are specified they will be randomly selected at runtime
getting started
# clone the repo
git clone https://git.divio.city/me/divifetch.git
cd divifetch
# compile the generator
./build.vsh
# generate, copy and edit the example config file
./generator --genconf -oc config.conf
vi config.conf
# generate the source code and build script
./generator
config file format
configs use a simple s-expression syntax.
-
a form is
(name arg1 arg2 ...) -
comments start with
;and run to end of line -
string values are quoted with
" -
-and_can be interchangeably used in field names
source config file format
global config
there is one config form per file. it sets global defaults that apply to all entries.
(config
(art-padding 3)
(art-file "ascii/cat.txt")
(art-prefix "\033[1m")
(art-suffix "\033[0m")
(key-prefix "\033[1m\033[34m")
(key-suffix "\033[0m: ")
(value-prefix "")
(value-suffix ""))
| field | type | description |
|---|---|---|
buffer-size |
int | the size of the buffer used to store the output of dynamic runtime modules (default: 128) |
art-padding |
int | the padding between the (default: 3) |
art-width |
int | (deprecated) if no padding is set, the column width reserved for the art |
art-file |
string | path to a text file containing the ascii art (if missing or empty the art column is left blank) |
art-prefix |
string | escape sequence inserted before each art line |
art-suffix |
string | escape sequence inserted after each art line |
key-prefix |
string | default escape sequence before each entry's key |
key-suffix |
string | default text/sequence after each entry's key (e.g. : ) |
value-prefix |
string | default escape sequence before each entry's value |
value-suffix |
string | default text/sequence after each entry's value |
underscore |
string | if no key value is set, replaces the _ in key with with the following substring |
key-case |
string | if no key value is set, how should the key be capitalised |
build-time |
string | default value for build-time |
new-print |
string | default value for new-print |
execute |
string | if set, the following command will be executed at fetch runtime |
entry types
each entry occupies one line of output.
lines are paired with art lines from top to bottom.
if there are more entries than art lines the art column is padded with spaces.
| field | description |
|---|---|
key |
the label shown before the value; defaults to the entry type |
value |
for static entries: the displayed value. for dynamic entries: optional argument passed to the module function |
key-prefix |
overrides the global key-prefix for this entry |
key-suffix |
overrides the global key-suffix for this entry |
value-prefix |
overrides the global value-prefix for this entry |
value-suffix |
overrides the global value-suffix for this entry |
build-time |
enabled if set to yes |
new-print |
if set to yes entry will be printed in a seperate printf/fputs statment if set to |
static entries
values are known at generation time and baked into the binary.
| entry type | description |
|---|---|
static |
the standard key/value entry |
plain |
like static but with all prefixes and suffixes stripped. useful for decorative lines or headers |
break |
an empty line (no key, no value, no prefixes) |
colors-normal |
prints the 8 standard terminal palette colors as colored blocks |
colors-bright |
prints the 8 bright terminal palette colors as colored blocks |
dynamic entries
values are resolved at runtime by calling a module function. the entry type must match a subdirectory name inside modules/.
if a module takes an argument (like mount), pass it as the second positional value or via the value field.
(mount "Mount (/)" "/")
; ^ ^
; key argument
per-entry fields
every entry (static or dynamic) accepts optional field overrides in named or positional form.
positional form
(static "OS" "Artix GNU/Linux")
; ^ ^
; key value
values are assigned in the following order:
key, value, key-prefix, key-suffix, value-prefix, value-suffix
named form
use (field-name value) pairs inside the entry form
(static
(key "OS")
(value "Artix GNU/Linux"))
both forms can be mixed
positional arguments come first, named pairs after
(static "OS"
(value "Artix GNU/Linux"))
key cases
| value | result |
|---|---|
lower |
abc xyz |
upper |
ABC XYZ |
first |
Abc xyz |
title |
Abc Xyz |
build time entries
(shell
(build-time yes))
the dynamic entry will be executed by the header file generator rather than at runtime if this is enabled.
ansi escape codes
strings in the config support ANSI escape sequences written as \033[...m.
for a reference on color and formatting codes see: https://jakob-bagterp.github.io/colorist-for-python/ansi-escape-codes/
common examples:
| code | effect |
|---|---|
\033[0m |
reset all formatting |
\033[1m |
bold |
\033[30m-\033[37m |
foreground colors (black → white) |
\033[90m-\033[97m |
bright foreground colors |
\033[38;2;R;G;Bm |
RGB foreground color |
module system
a dynamic module lives in a subdirectory of modules/ and consists of three files:
modules/
\--- kernel/
|--- module.h # header for the module
|--- module.c # source code defining the module function
\--- module.conf # configuration for the build template
the generator reads only the modules that are actually referenced in your config, so unused ones produce no code in the output binary.
module function signature
every module must contain a function following this convention:
// module without arguments
const char* kernel_module_preset(char* buf, size_t buf_size);
// module with an argument
const char* mount_module_preset(const char* arg, char* buf, size_t buf_size);
the function writes its result into buf (256 bytes) and returns a pointer to it.
writing a new module
- create a directory
modules/$NAME/ - add a
module.hheader file - add a source code file implementing
$NAME_module_preset - add a
module.conffile specifying which build template to use - use
$NAMEin your config
reference hello-world modules are provided for C, C++ and Rust.
entry type names with hyphens are converted to underscores when generating the function name
configuring build templates
build.conf
config
| field | description |
|---|---|
| exec | path to the V interpreter (default: #!/usr/bin/env -S v run) |
| cc | C compiler |
| cflags | flags for the C compiler |
| target | name for the fetch binary (default: divifetch) |
| target_head | name for the header file generator binary (default: headgen) |
| dest_dir | installation directory (default: /usr/local/bin) |
| build_dir | build directory (default: target) |
| custom | custom code to include in the build script source code |
| default | default task for the build script (default: crun) |
templates
| field | description |
|---|---|
| source-file | source file inside the module directory (required) |
| command | Makefile command used to compile the module (required) |
| object-extension | extension of the generated object file |
| archive | if yes, the object file is first packed into a static library before linking |
| linker-flags | additional flags appended to the final link command |
module.conf
a module may contain a module.conf file, where the language and per-module template overrides are specified.
(language c)
(template
(command "${cc} -O3 -march=native -flto -pipe -funswitch-loops -c ${source_file} -o ${output_file}"))
if no language is specified, the generator defaults to using the c template.
generated build script
the generated build script has the following tasks:
| task | description |
|---|---|
help |
display the help message and exit |
clean |
clean the build directory |
build |
build the fetch binary |
run |
execute the fetch binary |
header |
execute the header file generator |
generator |
build the divifetch generator |
regen |
execute the command that generated the build script again |
install |
install the fetch binary to dest_dir |
uninstall |
uninstall the fetch binary from dest_dir |