Auto-Discovery Tutorial#
This tutorial explains how scafctl automatically discovers solution files, making the -f flag optional for most commands.
Prerequisites#
- scafctl installed and available in your PATH
- Basic familiarity with YAML syntax and solution files
- Completion of the Getting Started tutorial
Table of Contents#
- Overview
- How Auto-Discovery Works
- Search Order
- Supported Commands
- Examples
- Interaction with
--cwd - When Auto-Discovery Fails
- Best Practices
Overview#
Many scafctl commands accept a -f / --file flag to specify the solution file path. When this flag is omitted, scafctl searches the current directory (or the --cwd target) for a solution file using a well-defined search order.
This means you can simply cd into a project directory and run commands without specifying the file:
# Instead of:
scafctl run solution -f solution.yaml
# Just run:
scafctl run solution# Instead of:
scafctl run solution -f solution.yaml
# Just run:
scafctl run solutionHow Auto-Discovery Works#
When no -f flag is provided, scafctl calls FindSolution(), which iterates over a set of folder prefixes and file names in order, returning the first match.
Search Order#
The search combines these folder prefixes with these file names:
Folder prefixes (checked in order):
scafctl/— conventional project subfolder.scafctl/— hidden project subfolder- (current directory) — no subfolder prefix
File names (checked in order for each folder):
solution.yamlsolution.ymlscafctl.yamlscafctl.ymlsolution.jsonscafctl.json
This produces 18 candidate paths checked in this exact order:
| Priority | Path |
|---|---|
| 1 | scafctl/solution.yaml |
| 2 | scafctl/solution.yml |
| 3 | scafctl/scafctl.yaml |
| 4 | scafctl/scafctl.yml |
| 5 | scafctl/solution.json |
| 6 | scafctl/scafctl.json |
| 7 | .scafctl/solution.yaml |
| 8 | .scafctl/solution.yml |
| 9 | .scafctl/scafctl.yaml |
| 10 | .scafctl/scafctl.yml |
| 11 | .scafctl/solution.json |
| 12 | .scafctl/scafctl.json |
| 13 | solution.yaml |
| 14 | solution.yml |
| 15 | scafctl.yaml |
| 16 | scafctl.yml |
| 17 | solution.json |
| 18 | scafctl.json |
The first file that exists on disk is used.
Supported Commands#
Auto-discovery works with every command that accepts -f:
| Command | Auto-Discovery | Notes |
|---|---|---|
scafctl run solution | ✅ | Also supports catalog bare names and URLs |
scafctl run resolver | ✅ | Falls back to auto-discovery when -f is omitted |
scafctl lint | ✅ | Discovers and lints the local solution |
scafctl render solution | ✅ | Discovers solution for rendering |
scafctl test functional | ✅ | Discovers solution to run functional tests |
scafctl test list | ✅ | Discovers solution to list test cases |
scafctl test init | ✅ | Discovers solution to generate test scaffold |
scafctl plugins install | ✅ | Discovers solution to install referenced plugins |
Examples#
Basic Usage — Run in Project Directory#
# Given this project structure:
# my-project/
# ├── solution.yaml
# └── templates/
# └── config.yaml.tpl
cd my-project
scafctl run solution # discovers ./solution.yaml
scafctl lint # discovers ./solution.yaml
scafctl test functional # discovers ./solution.yaml# Given this project structure:
# my-project/
# ├── solution.yaml
# └── templates/
# └── config.yaml.tpl
cd my-project
scafctl run solution # discovers ./solution.yaml
scafctl lint # discovers ./solution.yaml
scafctl test functional # discovers ./solution.yamlConventional Subfolder#
# Given this project structure:
# my-project/
# ├── scafctl/
# │ └── solution.yaml
# └── src/
# └── main.go
cd my-project
scafctl run solution # discovers ./scafctl/solution.yaml# Given this project structure:
# my-project/
# ├── scafctl/
# │ └── solution.yaml
# └── src/
# └── main.go
cd my-project
scafctl run solution # discovers ./scafctl/solution.yamlHidden Subfolder#
# Given this project structure:
# my-project/
# ├── .scafctl/
# │ └── solution.yaml
# └── README.md
cd my-project
scafctl lint # discovers ./.scafctl/solution.yaml# Given this project structure:
# my-project/
# ├── .scafctl/
# │ └── solution.yaml
# └── README.md
cd my-project
scafctl lint # discovers ./.scafctl/solution.yamlExplicit -f Overrides Discovery#
When you specify -f, auto-discovery is skipped entirely:
# Use a specific file regardless of what's in the current directory
scafctl run solution -f path/to/other-solution.yaml
# Use stdin
cat solution.yaml | scafctl lint -f -
# Use a URL
scafctl run solution -f https://example.com/solution.yaml
# Use a catalog name
scafctl run solution -f my-solution@1.0.0# Use a specific file regardless of what's in the current directory
scafctl run solution -f path/to/other-solution.yaml
# Use stdin
cat solution.yaml | scafctl lint -f -
# Use a URL
scafctl run solution -f https://example.com/solution.yaml
# Use a catalog name
scafctl run solution -f my-solution@1.0.0Interaction with --cwd#
When --cwd is set, auto-discovery searches relative to the specified directory instead of the process working directory:
# Discover solution inside another directory
scafctl run solution --cwd /path/to/project
# This is equivalent to:
cd /path/to/project && scafctl run solution# Discover solution inside another directory
scafctl run solution --cwd /path/to/project
# This is equivalent to:
cd /path/to/project; scafctl run solutionAll 18 candidate paths are resolved against the --cwd target.
When Auto-Discovery Fails#
If no solution file is found, scafctl returns a clear error:
Error: no solution path provided and no solution file found in default locationsCommon causes:
- You’re not in the correct directory
- The solution file has a non-standard name (use
-fto specify it) - The
--cwdflag points to the wrong directory
You can see the candidate paths scafctl checks with:
scafctl config pathsscafctl config pathsBest Practices#
Use
solution.yamlat the project root — this is the most common convention and is discovered without any subfolder prefix.Use
scafctl/subfolder for multi-tool repos — keeps scafctl configuration separate from other tools.Use
.scafctl/for hidden configuration — useful when the solution is infrastructure that shouldn’t be front-and-center.Always use
-fin CI/CD — explicit paths prevent surprises when the working directory changes.Combine with
--cwdfor monorepos — target a specific project without changing directories.