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, bare boolean flags, and raw string literals for regex patterns. The ferron-fmt formatter 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 — inline and trailing comments are preserved
  • Quoting normalization — bare strings when possible, double-quoted when necessary (e.g., for values that would be ambiguous)
  • Raw string preservationr"..." syntax is preserved for strings that were originally raw
  • Line continuation preservation\ at end of line is preserved at the same position

This tool can be used to ensure consistent formatting across multiple Ferron configuration files.

Tip

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

Installation

ferron-fmt is included in all Ferron distributions 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-quotesPreserve original quoting style instead of normalizing
--max-blank-lines <n>2Maximum number of consecutive blank lines to preserve
--no-trailing-newlineDon’t add a trailing newline at the end of the file
--sort-directivesSort directives alphabetically within blocks
--checkCheck if input is already formatted (exit 1 if not)
-i, --in-placeEdit file in place
-o, --output <file>Write 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 will produce a parse error if any value cannot be represented as a bare string (e.g., values containing spaces or special characters).

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 don’t 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 will 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 continuation is preserved 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