Configuration file support
Why it matters
Without a config file, users must pass --api-key, --format, --output-dir, and --region on every single invocation. That friction drives them toward shell aliases that are fragile, .env files that aren't portable, and wrapper scripts that become undocumented infrastructure. ISO 25010:2011 usability.operability scores CLIs on whether persistent preferences can be set once and forgotten. A CLI that requires 6 flags per invocation is not operationally usable in real workflows — teams will script around it rather than into it, breaking the tool's intended composability.
Severity rationale
Medium because the absence of config file support imposes per-invocation repetition that degrades usability in team workflows without causing data loss or security failures.
Remediation
Add config file discovery using cosmiconfig (Node.js) or a standard ~/.config location (Python/Go). CLI flags must always override config file values:
import { cosmiconfig } from 'cosmiconfig'
const explorer = cosmiconfig('mytool')
const result = await explorer.search() // finds .mytoolrc, mytool.config.js, etc.
const fileConfig = result?.config ?? {}
// CLI flags override config — spread order matters
const config = { ...fileConfig, ...cliFlags }
import tomllib
from pathlib import Path
def load_config() -> dict:
for loc in [Path('mytool.toml'), Path.home() / '.config' / 'mytool' / 'config.toml']:
if loc.exists():
with open(loc, 'rb') as f:
return tomllib.load(f)
return {} # no config file is not an error
Document which config file locations are checked in --help output or a mytool config --locations subcommand.
Detection
-
ID:
config-file -
Severity:
medium -
What to look for: Enumerate all configuration sources (config files, environment variables, CLI flags). For each, check for config file support: cosmiconfig, rc, configparser, viper, config crate. Look for config file loading from standard locations:
.mytoolrc,.mytoolrc.json,mytool.config.js,~/.config/mytool/config.json, orpyproject.toml[tool.mytool]section. Check that command-line flags override config file values. Check that a missing config file doesn't cause an error (defaults should be used). -
Pass criteria: The CLI supports a configuration file for persistent options. Config file values are overridable by command-line flags. Missing config file is handled gracefully (defaults used, no error). Config file locations follow platform conventions (XDG on Linux,
~/Library/Preferenceson macOS, or project-local dotfiles) — at least 1 configuration file format supported (JSON, YAML, TOML, or RC file). Report: "X configuration sources found." -
Fail criteria: No config file support — all options must be passed as flags every time, or config file is required (crashes if missing), or config file values cannot be overridden by flags.
-
Skip (N/A) when: The CLI has 2 or fewer options total — config file overhead is not warranted. All checks skip when no CLI entry point is detected.
-
Detail on fail:
"No configuration file support found — users must pass --api-key and --format on every invocation"or"Config file is loaded from hardcoded path '/etc/mytool.conf' — non-standard and requires root to edit" -
Remediation: Config files save users from repetitive flag typing:
// Node.js — cosmiconfig for standard config file discovery import { cosmiconfig } from 'cosmiconfig' const explorer = cosmiconfig('mytool') const configResult = await explorer.search() const fileConfig = configResult?.config ?? {} // CLI flags override config file values const config = { ...fileConfig, ...cliFlags, // spread CLI flags last to override }# Python — standard config locations from pathlib import Path import tomllib def load_config(): locations = [ Path('mytool.toml'), Path.home() / '.config' / 'mytool' / 'config.toml', ] for loc in locations: if loc.exists(): with open(loc, 'rb') as f: return tomllib.load(f) return {} # defaults, no error
External references
- iso-25010:2011 · usability.operability — Usability — Operability
Taxons
History
- 2026-04-18·v1.0.0·Initial import from cli-quality·automated