Command Reference
Complete reference for all fyaml commands, flags, and options.
Global Flags
These flags apply to all commands:
-v, --verbose
Show debug output. All verbose output is written to stderr, so it doesn't interfere with piped stdout.
Usage:
Default: false (disabled)
Behavior:
- When enabled, shows
[DEBUG] Processing: <filepath>for each YAML/JSON file processed - Warnings (e.g., empty directory) are always shown with
[WARN]prefix, regardless of verbose flag - All output goes to stderr, so stdout remains clean for piping
- Useful for debugging which files are being processed
Output Example:
$ fyaml -v pack config/
[DEBUG] Processing: /path/to/config/entities/item1.yml
[DEBUG] Processing: /path/to/config/entities/item2.yml
entities:
item1:
entity:
id: example1
attributes:
name: sample name
item2:
entity:
id: example2
attributes:
name: another name
Commands
fyaml [DIR]
Compile a directory of YAML/JSON files into a single document. This is the primary command.
Synopsis:
Arguments:
DIR- Directory to pack (default: current directory)
Flags:
-c, --check- Compare generated output to--outputfile or stdin (if--outputomitted or set to-), exit non-zero if different--chroot string- Security/confinement boundary for includes (default: same as DIR)--convert-booleans- Convert unquoted YAML 1.1 booleans totrue/false--dir string- Explicitly specify directory to pack (avoids subcommand conflicts)--enable-anchors- Enable anchor references across different files (extension)--enable-includes- Process file includes (!include,!include-text,<<include()>>) (extension)-f, --format string- Output format:yamlorjson(default:yaml)--indent int- Number of spaces for indentation (default:2)--merge string- Merge strategy:shallow(last wins) ordeep(recursive) (default:shallow)-m, --mode string- Output mode:canonical(sorted keys, no comments) orpreserve(authored order and comments) (default:canonical)-o, --output string- Write output to file, or-for stdin when used with--check(default: stdout)-V, --version- Print version information and exit
Examples:
# Pack current directory to stdout
fyaml
# Pack specific directory
fyaml config/
# Write to file
fyaml -o output.yml
# Output as JSON
fyaml config/ --format json -o output.json
# Preserve authored order and comments
fyaml config/ --mode preserve -o output.yml
# Verify output matches file
fyaml -o output.yml --check
# Verify output matches stdin
fyaml --check < expected.yml
# Verify output matches stdin (explicit)
fyaml --check --output - < expected.yml
# Pack directory with conflicting name (e.g., directory named "pack")
fyaml --dir pack
# With verbose output
fyaml -v config/
# Show version
fyaml --version
Exit Codes:
0- Success1- Pack or IO error2---checkmismatch (output differs from file)
fyaml pack [DIR] (Alias)
An alias for fyaml [DIR] that works identically. Maintained for backward compatibility.
Synopsis:
All flags and behavior are identical to the main fyaml [DIR] command.
Examples:
# These are equivalent:
fyaml config/
fyaml config/
# Both work with all flags:
fyaml config/ --enable-includes
fyaml config/ --enable-includes
fyaml version
Print version information. Both fyaml version (subcommand) and fyaml --version or fyaml -V (flag) work identically.
Synopsis:
Output:
Exit Codes:
0- Success
Flags Reference
-c, --check
Compare the generated output with an existing file specified by --output. Exits with code 2 if they differ.
Usage:
Behavior:
- Requires
--outputto be specified - Reads the existing file (if it exists)
- Compares byte-by-byte with generated output
- Prints "output mismatch" to stderr if different (no output if same)
- Exits with code 2 if different, exits with code 0 if same
- Useful in CI/CD to verify configuration hasn't changed
Exit Codes:
0- Output matches the file2- Output differs from the file1- Error (file read error, etc.)
Examples:
# Verify in CI
fyaml -o config.yml --check
# Check exit code to distinguish between errors and mismatches
fyaml -o config.yml --check
exit_code=$?
if [ $exit_code -eq 2 ]; then
echo "Configuration is out of date!"
exit 1
elif [ $exit_code -ne 0 ]; then
echo "Error occurred during packing"
exit $exit_code
fi
--convert-booleans
Convert on/off and yes/no values to true/false booleans.
Usage:
Default: false (disabled)
When to use:
If your YAML files use on/off or yes/no for boolean values, they'll be treated as strings by default. Use this flag to convert them to actual boolean values.
Behavior:
- Unquoted values (
on,off,yes,no,y,n, etc.) are converted totrue/false - Quoted strings (
"on",'yes') are preserved as strings - Non-boolean strings are unchanged
Conversions:
| Input | Output |
|---|---|
on, On, ON |
true |
off, Off, OFF |
false |
yes, Yes, YES |
true |
no, No, NO |
false |
y, Y |
true |
n, N |
false |
Examples:
# Convert on/off to true/false
fyaml --convert-booleans
# Combine with other flags
fyaml --convert-booleans --enable-includes
fyaml --convert-booleans --enable-anchors
fyaml --convert-booleans -o output.yml
# Pack specific directory with conversion
fyaml config/ --convert-booleans
Example transformation:
Input (config/settings.yml):
Output with --convert-booleans:
Note: fyaml always outputs YAML 1.2 format where only true and false are booleans.
See also: Usage Guide - Converting YAML 1.1 Booleans for more details and examples.
--dir
Explicitly specify the directory to pack. This flag takes precedence over positional arguments and is useful for avoiding conflicts when a directory has the same name as a subcommand (e.g., pack or version).
Usage:
Behavior:
- Takes precedence over positional arguments
- If both
--dirand a positional argument are provided,--diris used - Useful for packing directories named
packorversionwithout ambiguity
Examples:
# Pack directory named "pack" (avoids subcommand conflict)
fyaml --dir pack
# Pack directory named "version"
fyaml --dir version
# --dir takes precedence over positional argument
fyaml --dir config/ other/ # Uses config/, ignores other/
See also: Usage Guide - Subcommand and Directory Name Conflicts for more details.
--enable-anchors
Enable cross-file YAML anchor resolution. Allows anchors defined in one file to be referenced as aliases in another file.
Usage:
fyaml config/ --enable-anchors
fyaml config/ --enable-anchors --mode preserve
fyaml config/ --enable-anchors -o output.yml
Default: false (disabled)
Behavior:
- Collects anchors from all files and makes them available for cross-file references
- Resolves cross-file alias references during parsing
- Works with both alias references (
*alias) and merge keys (<<: *alias) - Files that fail to parse won't contribute anchors to other files
Mode Differences:
- Canonical mode: Aliases are expanded into their full content
- Preserve mode: Alias references are preserved as
*alias_nameto maintain the original structure
Example:
Using @ files to ensure anchors appear before aliases:
# @anchors.yml (processed first alphabetically)
common_template: &common_template
timeout: 30
retries: 3
enabled: true
# entities/item1.yml
entity:
id: example1
config: *common_template
attributes:
name: sample name
Output (canonical mode):
common_template:
enabled: true
retries: 3
timeout: 30
entities:
item1:
entity:
attributes:
name: sample name
config:
enabled: true
retries: 3
timeout: 30
id: example1
Output (preserve mode):
common_template: &common_template
timeout: 30
retries: 3
enabled: true
entities:
item1:
entity:
id: example1
config: *common_template
attributes:
name: sample name
Preserve Mode Validation:
When using --mode preserve with --enable-anchors and --format yaml, fyaml validates that the output YAML is valid. If the output contains aliases that appear before their anchor definitions, fyaml will return an error. Use the --verbose flag to see the invalid YAML content in the error output.
To ensure valid YAML in preserve mode:
- Use
@files for anchor definitions (processed first alphabetically) - Organize files so anchor definitions come before files that use them
- Use
--mode canonicalto expand aliases and avoid ordering issues
Limitations:
- Files that fail to parse (due to invalid YAML or unresolvable aliases) won't have their anchors available to other files
- Circular anchor dependencies are supported but may require multiple processing passes
- The common pattern (anchors in shared/definition files, aliases in entity/config files) works well, but in preserve mode you may need to reorganize files or use
@files to ensure valid YAML - Requires
--enable-anchorsflag - In preserve mode with YAML output, invalid YAML (aliases before anchors) will cause an error
See also: YAML Anchors and Aliases in the Usage Guide for detailed information.
--enable-includes
Enable processing of file includes. This is an extension to the FYAML specification.
Usage:
Default: false (disabled)
Include Mechanisms:
When enabled, fyaml processes three include mechanisms:
| Syntax | Purpose | Example |
|---|---|---|
!include |
Include parsed YAML structures | config: !include defaults.yml |
!include-text |
Include raw text content | command: !include-text script.sh |
<<include()>> |
Alias for !include-text (CircleCI style) |
command: <<include(script.sh)>> |
Processing Order:
!includetags are processed first (YAML structures merged)!include-texttags are processed (text content replaced)<<include()>>directives are processed (backward compatibility)
Behavior:
- Chroot boundary: All includes must resolve to paths within the chroot boundary (defaults to pack directory)
- Relative paths: File paths are resolved relative to the file containing the include
- For nested includes, paths in included files are resolved relative to the included file's location, not the original file
- Absolute paths: Allowed but must be within the chroot boundary
- Nested includes:
!includesupports nested includes — included YAML files can contain their own!include,!include-text, or<<include()>>directives!include-textand<<include()>>are single-level only — the included text content is not processed for further includes- JSON file support:
<<include()>>works in JSON files (standard JSON)!includeand!include-texttags work in JSON files (non-standard JSON, but supported by fyaml)- YAML files can include JSON files using
!include
Examples:
# Process includes
fyaml config/ --enable-includes
# Combine with other flags
fyaml config/ --enable-includes -o output.yml
fyaml config/ --enable-includes --format json
Example: Including YAML Structures
# entities/item1.yml
entity:
id: example1
config: !include ../shared/defaults.yml
attributes:
name: sample name
Example: Including Text Content
# entities/item1.yml
entity:
id: example1
attributes:
name: sample name
steps:
- run:
command: !include-text scripts/hello.sh
Example: CircleCI Style
Error Cases:
!includeon non-scalar — "must be used on a scalar value"echo <<include(f)>>— "entire string must be include statement"<<include(a)>> <<include(b)>>— "multiple include statements"- Missing file — "could not open path/to/file for inclusion"
- Path escapes chroot boundary — "include path escapes chroot boundary"
- Invalid YAML/JSON in included file — "failed to parse YAML/JSON in path"
Note: Without this flag, include directives and tags are passed through unchanged. This preserves backward compatibility and keeps the default behavior spec-compliant.
See also: Usage Guide - File Includes for complete usage documentation and examples.
--chroot
Set the security/confinement boundary for includes. This allows includes from outside the pack directory but within the specified chroot boundary.
Usage:
fyaml config1 --chroot . --enable-includes
fyaml config1 --chroot /path/to/project-root --enable-includes
Default: Same as DIR (pack directory)
Behavior:
- If not set: Includes must be within the pack directory (DIR) - default behavior
- If set: Includes can come from outside DIR but must be within the chroot boundary
- Does NOT affect what gets packed - DIR still controls which files appear in output
- Does NOT affect path resolution - relative paths in
!includetags remain relative to the file containing the tag
Use Case: Shared Includes
The primary use case for --chroot is sharing include files across multiple configuration directories:
project-root/
shared-includes/
common.yaml
config1/
app.yaml # !include ../shared-includes/common.yaml
config2/
app.yaml # !include ../shared-includes/common.yaml
# From project-root/
fyaml config1 --chroot . --enable-includes
fyaml config2 --chroot . --enable-includes
Both configs can reference the same shared-includes/ directory.
Security:
- The chroot boundary is a security/confinement boundary (like Unix
chroot) - It prevents includes from accessing files outside the specified boundary
- Only affects where includes can come from, not what gets packed
Examples:
# Default behavior (chroot = DIR)
fyaml config/ --enable-includes
# Allow includes from project root
fyaml config/ --chroot . --enable-includes
# Allow includes from specific directory
fyaml config/ --chroot /path/to/project --enable-includes
-f, --format
Specify the output format. Valid values: yaml or json.
Usage:
Default: yaml
Behavior:
yaml- Outputs YAML format (default)json- Outputs JSON format with 2-space indentation- Empty output behavior differs by format (see below)
Examples:
# YAML output (default)
fyaml
# JSON output
fyaml --format json
# JSON to file
fyaml -f json -o config.json
# Pack specific directory as JSON
fyaml config/ --format json
Empty Output:
- YAML format: Returns empty output (0 bytes) when no files found
- JSON format: Returns
nullwhen no files found
See also: Usage Guide - Output Format for more details on YAML and JSON output behavior.
--indent
Specify the number of spaces used for indentation in both YAML and JSON output.
Usage:
Default: 2
Behavior:
- Applies to both YAML and JSON output formats
- Must be a positive integer (error message: "must be positive")
- YAML output uses the specified indent spacing
- JSON output uses the specified indent spacing
Examples:
# Default 2-space indent (YAML)
fyaml
# 4-space indent (YAML)
fyaml --indent 4
# 2-space indent (JSON)
fyaml --format json --indent 2
# 4-space indent (JSON)
fyaml --format json --indent 4
Note: The default indent of 2 spaces is the widely accepted convention for YAML and JSON. You can override this if your project uses a different indentation style.
See also: Usage Guide - Output Format for more details on YAML and JSON formatting.
--merge
Control how maps are merged when multiple files contribute to the same key.
Usage:
fyaml --merge shallow # Default: later files completely replace earlier ones
fyaml --merge deep # Recursively merge nested maps
Default: shallow
Valid Values:
shallow: Later file's value completely replaces earlier one (default, backward compatible)deep: Nested maps are merged recursively, only replacing values at the leaf level
When to use:
- Shallow merge (default): Use when you want later files to completely override earlier ones. This is the default behavior and maintains backward compatibility.
- Deep merge: Use when you want to combine configuration from multiple files, preserving values from earlier files that aren't overridden.
Behavior:
- Shallow merge: If two files define the same key, the entire value from the later file replaces the earlier one, even for nested maps.
- Deep merge: If both sides are maps, they are merged recursively. Non-map values or type mismatches use shallow behavior (replace).
Important Notes:
- Arrays always use "replace" behavior (last wins) even in deep merge mode
- Deep merge only affects nested maps - scalar values and arrays are always replaced
- Applies to all merging scenarios: root-level files,
@files, and@directories
Examples:
# Use shallow merge (default)
fyaml config/
# Use deep merge to combine nested configurations
fyaml config/ --merge deep
# Combine with other flags
fyaml config/ --merge deep --mode preserve
fyaml config/ --merge deep --format json
Example transformation:
Input files:
@base.yml:
@override.yml:
Output with --merge shallow (default):
Output with --merge deep:
See also: Usage Guide - Merge Behavior for more details and examples.
-m, --mode
Select the output mode that controls key ordering and comment preservation.
Usage:
fyaml --mode canonical # Default: sorted keys, no comments
fyaml -m preserve # Preserve order and comments
Default: canonical
Valid Values:
canonical(default) - Keys are sorted alphabetically, comments are removedpreserve- Maintains authored key order and preserves comments
Behavior:
Canonical Mode (Default):
- All map keys are sorted alphabetically
- Comments are removed from output
- Deterministic output
- Ideal for tools that don't care about key ordering or comments, and when sorted keys make diffs more readable
Preserve Mode:
- Keys maintain the order they appear in source files
- Comments are preserved in YAML output
- Deterministic output (same input always produces same output)
- YAML syntax may be normalized (e.g., merge keys may be emitted with explicit
!!mergetags) - Ideal for maintaining documentation in comments and preserving the authored structure from source files
Interaction with JSON Output:
- Key order: JSON output always sorts keys alphabetically regardless of mode (Go's JSON encoder behavior)
- Comments: JSON doesn't support comments, so comments are lost regardless of mode
- Both modes produce deterministic JSON output
Examples:
# Canonical mode (default)
fyaml
fyaml --mode canonical
# Preserve mode
fyaml --mode preserve
fyaml -m preserve
# Preserve mode with JSON output (key order preserved, comments lost)
fyaml --mode preserve --format json -o output.json
# Combine with other flags
fyaml config/ --mode preserve --enable-includes -o output.yml
fyaml -m preserve --convert-booleans
When to Use Each Mode:
- Use canonical mode when:
- You need sorted keys (makes diffs more readable)
- The target tool doesn't care about key ordering or comments
-
You prefer a consistent, predictable key order
-
Use preserve mode when:
- You want to maintain documentation in comments
- You want to preserve the authored key order from source files
- The target tool or your workflow benefits from maintaining source structure
Note: Both modes are deterministic and suitable for version control and CI/CD. The difference is in key ordering (sorted vs. authored) and comment preservation.
See also: Usage Guide - Output Modes for detailed documentation and examples.
-o, --output
Specify the output file path. If not provided, output is written to stdout.
Usage:
Behavior:
- File is written atomically (creates temp file, then renames)
- File permissions are set to
0644 - If the file exists, it's overwritten
- Parent directories are not created automatically (must exist)
Examples:
# Write to current directory
fyaml -o config.yml
# Write to specific path
fyaml -o /tmp/output.yml
# Write to subdirectory (must exist)
fyaml -o build/config.yml
# Pack specific directory to file
fyaml config/ -o output.yml
Exit Codes
fyaml uses the following exit codes:
| Code | Meaning | When It Occurs |
|---|---|---|
0 |
Success | Packing succeeded, or --check found no differences |
1 |
Error | Pack error, IO error, invalid format, etc. |
2 |
Mismatch | --check found differences between output and file |
Examples:
# Success
fyaml # exits 0
# Error - invalid directory
fyaml /nonexistent # exits 1
# Mismatch - config out of date
fyaml -o config.yml --check # exits 2 if different
Default Behavior
Default Directory
If no directory is specified, fyaml packs the current working directory:
Default Output
If no output file is specified, output goes to stdout:
# Output to stdout
fyaml
# Output to file
fyaml -o output.yml
# Pack specific directory to stdout
fyaml config/
Default Format
Default output format is YAML:
# YAML output (default)
fyaml
# JSON output
fyaml --format json
# Pack specific directory as JSON
fyaml config/ --format json
Error Messages
Common Errors
"pack error: failed to build filetree: ..."
- Directory doesn't exist
- Permission denied
- Invalid path
- Error message includes the underlying error details
"pack error: failed to marshal tree: ..."
- Invalid YAML/JSON in files
- File contains non-map top-level value
- Error message includes the underlying error details (often includes file path and line/column information)
"expected a map, got a <type> which is not supported at this time for \"
- File has top-level scalar or array instead of map
<type>is the Go type (e.g.,string,[]interface{})<filepath>is the full path to the problematic file- See Usage Guide - File Content Requirements for details
"invalid format:
- Invalid
--formatvalue - Use
yamlorjsononly
"--check requires --output to be specified"
--checkflag used without--output- Must specify output file when using
--check
"failed to read output file: ..."
- Error reading file for
--checkcomparison - File may be unreadable (permission issue)
"warning: no YAML/JSON files found in directory:
- Directory contains no
.yml,.yaml, or.jsonfiles - Not an error, but output will be empty/null
Performance Considerations
- Files are processed in memory
- Suitable for typical configuration files (KB to low MB)
- Very large files (hundreds of MB) may consume significant memory
- Processing is single-threaded
Troubleshooting
Subcommand and Directory Name Conflicts
If you have a directory named pack or version, use the --dir flag to explicitly specify the directory:
The --dir flag takes precedence over positional arguments and avoids any ambiguity. See Usage Guide - Subcommand and Directory Name Conflicts for more details.
See Also
- Usage Guide - Common usage patterns and limitations
- Examples - Detailed examples