Configuration formatting

This page documents the ferron-fmt tool, a formatter for Ferron configuration files. It formats .conf files with configurable indentation, quote style, and other styling options.

Tip

The idiomatic Ferron 3 configuration style uses bare strings without quotes (when possible), 4-space indentation, and bare boolean flags. The ferron-fmt formatter also supports raw string literals for regex patterns and defaults to this style.

What it does⁠#

ferron-fmt parses a Ferron configuration file and rewrites it with consistent formatting. It handles:

  • Indentation: configurable width and style (spaces or tabs)
  • Quote style: auto (bare when possible, quoted when necessary), always double-quoted, or always bare
  • Blank lines: normalization with a configurable maximum consecutive blank lines
  • Trailing newline: optional trailing newline
  • Directive sorting: optional alphabetical sorting of directives within blocks
  • Comment preservation: the formatter preserves inline and trailing comments
  • Quoting normalization: bare strings when possible, double-quoted when necessary (for example, values that would be ambiguous)
  • Raw string preservation: the formatter preserves r"..." syntax for strings that were originally raw
  • Line continuation preservation: the formatter preserves \ at end of line at the same position

Use this tool to make sure formatting is consistent across multiple Ferron configuration files.

Tip

The formatter is idempotent (meaning running it multiple times on the same file produces identical output).

Installation⁠#

All Ferron distributions include ferron-fmt alongside the main server binary. See Installation for details.

Usage⁠#

Format a file to stdout⁠#

ferron-fmt ferron.conf

Format a file in place⁠#

ferron-fmt -i ferron.conf

Write to a specific file⁠#

ferron-fmt -o formatted.conf ferron.conf

Read from stdin⁠#

cat ferron.conf | ferron-fmt

Check if a file is already formatted⁠#

ferron-fmt --check ferron.conf

Exits with code 0 if the file is already formatted, 1 if not. Useful for CI:

ferron-fmt --check ferron.conf && echo "Formatted" || echo "Needs formatting"

Options⁠#

OptionDefaultDescription
--indent-width <n>4Number of spaces per indentation level
--indent-style <style>spacesIndentation style: spaces or tabs
--quote-style <style>autoQuote style: auto, always-double, or always-bare
--no-normalize-quotesnonePreserve original quoting style instead of normalizing
--max-blank-lines <n>2Maximum number of consecutive blank lines to preserve
--no-trailing-newlinenoneDo not add a trailing newline at the end of the file
--sort-directivesnoneSort directives alphabetically within blocks
--checknoneCheck if input is already formatted (exit 1 if not)
-i, --in-placenoneEdit file in place
-o, --output <file>noneWrite output to file instead of stdout

Indentation⁠#

Spaces (default)⁠#

ferron-fmt --indent-style spaces --indent-width 4 ferron.conf
example.com {
    root /var/www/html
    tls {
        provider manual
        cert /etc/ssl/cert.pem
        key /etc/ssl/key.pem
    }
}

Tabs⁠#

ferron-fmt --indent-style tabs ferron.conf
example.com {
	root /var/www/html
	tls {
		provider manual
		cert /etc/ssl/cert.pem
		key /etc/ssl/key.pem
	}
}

Quote style⁠#

Auto (default)⁠#

Bare strings when possible, double-quoted when necessary (this produces idiomatic Ferron 3 configuration style):

ferron-fmt --quote-style auto ferron.conf
example.com {
    root /var/www/html
    tls {
        provider manual
        cert /etc/ssl/cert.pem
        key /etc/ssl/key.pem
    }
}

Values that require quoting (would be ambiguous):

example.com {
    root "/var/www/html"
    tls {
        provider "manual"
        cert "/etc/ssl/cert.pem"
    }
}

Always double-quoted⁠#

ferron-fmt --quote-style always-double ferron.conf
example.com {
    root "/var/www/html"
    tls {
        provider "manual"
        cert "/etc/ssl/cert.pem"
        key "/etc/ssl/key.pem"
    }
}

Always bare⁠#

ferron-fmt --quote-style always-bare ferron.conf
example.com {
    root /var/www/html
    tls {
        provider manual
        cert /etc/ssl/cert.pem
        key /etc/ssl/key.pem
    }
}
Note

always-bare produces a parse error if the formatter cannot represent a value as a bare string. For example, values containing spaces or special characters cause this error.

Preserving original quoting⁠#

By default, ferron-fmt normalizes quoting according to the configured quote style. Use --no-normalize-quotes to preserve the original quoting:

ferron-fmt --no-normalize-quotes ferron.conf

This is useful when you want consistent indentation but do not want to change the quoting style.

Trailing newline⁠#

By default, ferron-fmt adds a trailing newline at the end of the file:

ferron-fmt --no-trailing-newline ferron.conf

Sorting directives⁠#

By default, directives are output in the order they appear in the source. Use --sort-directives to sort them alphabetically:

ferron-fmt --sort-directives ferron.conf
example.com {
    root /var/www/html

    tls {
        provider manual
        cert /etc/ssl/cert.pem
        key /etc/ssl/key.pem
    }

    # Directives are sorted alphabetically:
    # compress > directory_listing > root > tls
}

Blank lines⁠#

ferron-fmt preserves blank lines between directives up to the configured maximum (default: 2):

ferron-fmt --max-blank-lines 1 ferron.conf

This collapses consecutive blank lines beyond the limit.

Raw strings⁠#

The formatter preserves raw string syntax (r"...") for strings that were originally written as raw strings in the input. Raw strings are output with no escape processing, making them ideal for regex patterns:

match api_request {
    request.uri.path ~ r"^/api/v1(?:/|$)"
}

Running the formatter on this input keeps the r"..." syntax intact. Regular quoted strings ("...") are not converted to raw strings.

Note

Raw strings do not support interpolation. The formatter does not convert interpolated strings to raw strings.

Line continuations⁠#

The formatter preserves line continuations (\ at end of line) that were present in the original input. This is useful for splitting long directives across multiple lines:

example.com {
    # This is just an example directive
    example_proxy http://localhost:3000 \
      http://localhost:3001
}

After formatting, the formatter preserves the continuation at the same position. Line continuations with trailing comments are also preserved:

example.com {
    # This is just an example directive
    example_proxy http://localhost:3000 \ # first backend
      http://localhost:3001
}
Note

Line continuations are only preserved when the formatter reads from a file or stdin. When formatting a pre-parsed AST directly (programmatic API), continuations are not available and the output uses single-line values.

See also⁠#