:toc: preamble
:sectnums:

= Care and feeding of your initramfs generator

This guide attempts to outline the style used in the mkinitcpio codebase.

== Bash v. POSIX

Never use POSIX syntax if Bash offers a construct of its own, even if the
two are effectively identical. This means always using double braces over
the inferior `[` and `test`.

== Variable usage and naming conventions

There are three classifications of variables in mkinitcpio.

=== Local variables

All lower case, and scoped within functions. Use
freely, as they are well contained. Unless you are introducing a new
option, this is what you want to use.

[source,bash]
----
local foo="$1"
----

=== Global variables

These are known to mkinitcpio internally, but are global in scope. They carry
runtime configuration and data collected during the image generation process.
These are always lower case, but carry a leading underscore to denote that
they are global. It is helpful to prefix these variables instead with a `_f_` or
`_d_` if they refer to a file or directory, respectively.

[source,bash]
----
define -i _optcolor=1
_d_hookdir='/etc/foo.d'
_f_config='/etc/foo.conf'
----

=== "API" variables

Also global in scope, but exist "outside" of mkinitcpio - either drawn in from
the configuration file, or "exported" to the install hooks. These are always all
upper case. When introducing new variables, extreme care must be taken to pick
names that will not conflict with the environment inherited by mkinitcpio.

== Function naming

Use all lower case with underscores where appropriate, for easy readability.
Adhere to POSIX variable naming requirements for the contents of the name,
that is: only alphanumerics, underscores, and the identifier must not start
with a number.

== Quoting

Overquoting is preferred to underquoting. Prefer single quotes to double quotes
if possible. Remember to quote, quote and quote some more.

When quoting variables, use brace expansion if the variable is part of a larger
string.

[source,bash]
----
a='/test'
b="/some/path${a}"
c="$b"
----

== Functions and block statements

Always use "top-right, lower left" for blocks of code and functions.

[source,bash]
----
do_glob() {
    local g fn="$1"; shift

    for g in "$@"; do
        "$fn" "$g"
    done
}
----

== Building

To build with meson, run `meson setup build [options...]`. This will create
`./build` and prepare mkinitcpio for installation. See `link:meson.options[]`
for a list of mkinitcpio-specific options that can be passed to meson.

To install, run `meson install -C build`.

=== Meson templating

All source files are templated by meson with the following variables:

* `VERSION`: mkinitcpio version
* `BINDIR`: the binary installation directory (for example: `/usr/bin`)
* `SYSCONFDIR`: the system configuration directory (for example: `/etc`)
* `INITCPIO_LIBDIR`: the mkinitcpio library directory (for example: `/usr/lib/initcpio`)
* `INITCPIO_SYSCONFDIR`: the mkinitcpio system configuration directory (for example: `/etc/initcpio`)
* `VCONSOLE_CONF`: the name of the `vconsole.conf` file in `SYSCONFDIR`. On some
  distributions, this may be something else, like `rc.conf`
* `UDEVD_PATH`: the absolute path to the udev daemon executable
* `TMPFILES_PATH`: the absolute path to the systemd-tmpfiles executable

Templated values can be used in source files as `@VARIABLE@`.

New templated values should be added to `conf_data` in `link:meson.build[]`.

== Testing

=== Bash Automated Testing System

mkinitcpio uses bats (Bash Automated Testing System). The tests are found in
the `link:test[]` directory. Use `meson test -C build --suite bats` to run
the test suite.

Each newly added function should also have an accompanying test.

=== ShellCheck

All shell scripts must be validated with ShellCheck. Use `meson test -C build
--suite shellcheck` and ensure it successfully passes.

== EditorConfig

A `link:.editorconfig[]` file is provided to ensure consistency
(indenting, newlines, trailing whitespace) between text editors.
