35 Home
diviocity edited this page 2026-08-16 00:45:24 +00:00

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

  1. create a directory modules/$NAME/
  2. add a module.h header file
  3. add a source code file implementing $NAME_module_preset
  4. add a module.conf file specifying which build template to use
  5. use $NAME in 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