Recipes
1. Simple Command-Line Tool
A basic tool with flags and one required option.
class GREP_TOOL
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("mygrep", "Search for patterns in files", "1.0.0")
-- Flags
cli.add_flag ("i|ignore-case", "Case-insensitive matching")
cli.add_flag ("n|line-number", "Print line numbers")
cli.add_flag ("c|count", "Only print match count")
cli.add_flag ("r|recursive", "Search directories recursively")
cli.parse
if cli.help_requested then
cli.print_help
elseif cli.has_errors then
cli.print_errors
elseif cli.arguments.count < 2 then
print ("Usage: mygrep [OPTIONS] PATTERN FILE...%N")
else
search (cli)
end
end
search (cli: SIMPLE_CLI)
local
pattern: STRING
ignore_case: BOOLEAN
show_line_nums: BOOLEAN
do
if attached cli.command as p then
pattern := p
end
ignore_case := cli.has_flag ("ignore-case")
show_line_nums := cli.has_flag ("line-number")
-- Search each file argument
across cli.arguments_after_command as file_path loop
search_file (pattern, file_path, ignore_case, show_line_nums)
end
end
search_file (pattern, file_path: STRING; ignore_case, show_line_nums: BOOLEAN)
do
-- Implementation...
end
end
Usage
# Basic search
mygrep "error" log.txt
# Case-insensitive with line numbers
mygrep -in "warning" src/*.e
# Recursive search
mygrep -r "TODO" src/
2. Git-Style Subcommands
Tool with multiple subcommands like git (init, add, commit).
class PACKAGE_MANAGER
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("pkg", "Simple package manager", "1.0.0")
-- Global options
cli.add_flag ("v|verbose", "Verbose output")
cli.add_flag ("q|quiet", "Suppress output")
cli.parse
if cli.help_requested then
print_main_help
elseif attached cli.command as cmd then
dispatch_command (cmd, cli)
else
print_main_help
end
end
feature {NONE} -- Commands
dispatch_command (cmd: STRING; cli: SIMPLE_CLI)
do
if cmd.same_string ("install") then
cmd_install (cli)
elseif cmd.same_string ("remove") then
cmd_remove (cli)
elseif cmd.same_string ("update") then
cmd_update (cli)
elseif cmd.same_string ("list") then
cmd_list (cli)
else
print ("Unknown command: " + cmd + "%N")
end
end
cmd_install (cli: SIMPLE_CLI)
do
across cli.arguments_after_command as pkg loop
if cli.has_flag ("verbose") then
print ("Installing " + pkg + "...%N")
end
-- Install package...
end
end
cmd_remove (cli: SIMPLE_CLI)
do
-- Remove packages...
end
cmd_update (cli: SIMPLE_CLI)
do
print ("Updating package index...%N")
end
cmd_list (cli: SIMPLE_CLI)
do
print ("Installed packages:%N")
-- List packages...
end
print_main_help
do
print ("pkg - Simple package manager%N")
print ("%NCommands:%N")
print (" install PKG... Install packages%N")
print (" remove PKG... Remove packages%N")
print (" update Update package index%N")
print (" list List installed packages%N")
print ("%NOptions:%N")
print (" -v, --verbose Verbose output%N")
print (" -q, --quiet Suppress output%N")
print (" -h, --help Show help%N")
end
end
Usage
pkg install simple_json simple_file
pkg -v remove old_package
pkg update
pkg list
3. File Processor
Process files with input/output options.
class FILE_PROCESSOR
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("process", "Transform files", "1.0.0")
-- Required input
cli.add_required_option ("i|input", "Input file", "FILE")
-- Optional output (defaults to stdout)
cli.add_option ("o|output", "Output file (default: stdout)", "FILE")
-- Format options
cli.add_option_with_default ("f|format", "Output format", "FMT", "json")
-- Processing flags
cli.add_flag ("p|pretty", "Pretty print output")
cli.add_flag ("m|minify", "Minify output")
cli.parse
if cli.help_requested then
cli.print_help
elseif cli.has_errors then
cli.print_errors
else
process (cli)
end
end
process (cli: SIMPLE_CLI)
local
input_path, output_path: STRING
format: STRING
pretty: BOOLEAN
do
-- Required option always has value
if attached cli.option_value ("input") as i then
input_path := i
end
-- Optional with inline default
output_path := cli.option_value_or_default ("output", "")
-- Format has configured default
if attached cli.option_value ("format") as f then
format := f
end
pretty := cli.has_flag ("pretty")
-- Process file...
print ("Processing " + input_path + " as " + format + "%N")
end
end
Usage
# Convert to JSON (default format)
process -i data.xml -o data.json
# Convert to YAML, pretty printed
process -i data.json -f yaml -p
# Output to stdout
process -i data.xml
4. Build Tool
Compile/build tool with targets and options.
class BUILD_TOOL
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("build", "Build Eiffel projects", "2.0.0")
-- Build options
cli.add_option ("c|config", "ECF configuration file", "FILE")
cli.add_option ("t|target", "Build target", "TARGET")
cli.add_option_with_default ("j|jobs", "Parallel jobs", "NUM", "4")
-- Build modes
cli.add_flag ("r|release", "Release build (optimized)")
cli.add_flag ("d|debug", "Debug build (assertions)")
cli.add_flag ("clean", "Clean before build")
cli.add_flag ("finalize", "Finalized build")
cli.parse
if cli.help_requested then
cli.print_help
elseif cli.has_errors then
cli.print_errors
else
run_build (cli)
end
end
run_build (cli: SIMPLE_CLI)
local
config_file: STRING
jobs: INTEGER
do
config_file := cli.option_value_or_default ("config", "project.ecf")
jobs := cli.integer_option_or_default ("jobs", 4)
if cli.has_flag ("clean") then
print ("Cleaning...%N")
end
print ("Building " + config_file + " with " + jobs.out + " jobs%N")
if cli.has_flag ("release") then
print ("Mode: Release%N")
elseif cli.has_flag ("debug") then
print ("Mode: Debug%N")
end
end
end
5. Server Application
Web server with host/port configuration.
class WEB_SERVER
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("server", "Simple web server", "1.0.0")
-- Network options
cli.add_option_with_default ("H|host", "Bind address", "ADDR", "127.0.0.1")
cli.add_option_with_default ("p|port", "Port number", "PORT", "8080")
-- Path options
cli.add_option_with_default ("d|docroot", "Document root", "DIR", "./public")
-- Runtime options
cli.add_flag ("daemon", "Run as daemon")
cli.add_flag ("a|access-log", "Enable access logging")
cli.add_option ("l|log-file", "Log file path", "FILE")
cli.parse
if cli.help_requested then
cli.print_help
elseif cli.has_errors then
cli.print_errors
else
start_server (cli)
end
end
start_server (cli: SIMPLE_CLI)
local
host: STRING
port: INTEGER
docroot: STRING
do
host := cli.option_value_or_default ("host", "127.0.0.1")
port := cli.integer_option_or_default ("port", 8080)
docroot := cli.option_value_or_default ("docroot", "./public")
print ("Starting server on " + host + ":" + port.out + "%N")
print ("Document root: " + docroot + "%N")
if cli.has_flag ("access-log") then
print ("Access logging enabled%N")
end
-- Start server...
end
end
Usage
# Start on default port
server
# Custom port and document root
server -p 3000 -d ./dist
# Production settings
server --host=0.0.0.0 --port=80 --daemon --access-log
6. Data Converter
Convert between data formats.
class DATA_CONVERTER
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("convert", "Convert between data formats", "1.0.0")
-- Format options
cli.add_required_option ("f|from", "Input format", "FORMAT")
cli.add_required_option ("t|to", "Output format", "FORMAT")
-- I/O
cli.add_option ("i|input", "Input file (stdin if omitted)", "FILE")
cli.add_option ("o|output", "Output file (stdout if omitted)", "FILE")
-- Options
cli.add_flag ("p|pretty", "Pretty print")
cli.add_option ("indent", "Indentation spaces", "NUM")
cli.parse
if cli.help_requested then
print_help
elseif cli.has_errors then
cli.print_errors
else
convert (cli)
end
end
print_help
do
print ("convert - Data format converter%N")
print ("%NSupported formats: json, yaml, xml, csv, toml%N")
print ("%NExamples:%N")
print (" convert -f json -t yaml -i data.json -o data.yaml%N")
print (" convert --from=csv --to=json < data.csv%N")
end
convert (cli: SIMPLE_CLI)
local
from_fmt, to_fmt: STRING
indent: INTEGER
do
if attached cli.option_value ("from") as f then
from_fmt := f
end
if attached cli.option_value ("to") as t then
to_fmt := t
end
indent := cli.integer_option_or_default ("indent", 2)
print ("Converting from " + from_fmt + " to " + to_fmt + "%N")
-- Conversion logic...
end
end
7. Test Runner
Run tests with filtering and output options.
class TEST_RUNNER
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("test", "Eiffel test runner", "1.0.0")
-- Test selection
cli.add_option ("f|filter", "Run tests matching pattern", "PATTERN")
cli.add_option ("t|tag", "Run tests with tag", "TAG")
-- Output
cli.add_flag ("v|verbose", "Verbose output")
cli.add_flag ("q|quiet", "Only show failures")
cli.add_option_with_default ("format", "Output format", "FMT", "text")
-- Execution
cli.add_flag ("fail-fast", "Stop on first failure")
cli.add_option_with_default ("timeout", "Test timeout (seconds)", "SEC", "30")
cli.parse
if cli.help_requested then
cli.print_help
elseif cli.has_errors then
cli.print_errors
else
run_tests (cli)
end
end
run_tests (cli: SIMPLE_CLI)
local
timeout: INTEGER
filter: detachable STRING
do
timeout := cli.integer_option_or_default ("timeout", 30)
filter := cli.option_value ("filter")
if attached filter then
print ("Running tests matching: " + filter + "%N")
else
print ("Running all tests%N")
end
print ("Timeout: " + timeout.out + "s%N")
if cli.has_flag ("fail-fast") then
print ("Stopping on first failure%N")
end
end
end
Usage
# Run all tests
test
# Run specific tests
test --filter="*json*"
test --tag=unit
# CI mode
test --format=junit --quiet --fail-fast
8. Deployment Tool
Deploy applications with environment selection.
class DEPLOY_TOOL
create
make
feature
make
local
cli: SIMPLE_CLI
do
create cli.make
cli.set_app_info ("deploy", "Deployment tool", "1.0.0")
-- Environment
cli.add_required_option ("e|env", "Target environment", "ENV")
-- Options
cli.add_option ("b|branch", "Git branch", "BRANCH")
cli.add_option ("tag", "Deploy specific tag", "TAG")
-- Flags
cli.add_flag ("n|dry-run", "Show what would be done")
cli.add_flag ("f|force", "Force deployment")
cli.add_flag ("skip-tests", "Skip test suite")
cli.add_flag ("y|yes", "Skip confirmation")
cli.parse
if cli.help_requested then
print_help
elseif cli.has_errors then
cli.print_errors
else
deploy (cli)
end
end
print_help
do
print ("deploy - Deployment tool%N")
print ("%NEnvironments: staging, production%N")
print ("%NExamples:%N")
print (" deploy -e staging Deploy to staging%N")
print (" deploy -e production -y Deploy to production (no prompt)%N")
print (" deploy -e staging -n Dry run%N")
end
deploy (cli: SIMPLE_CLI)
local
env, branch: STRING
do
if attached cli.option_value ("env") as e then
env := e
end
branch := cli.option_value_or_default ("branch", "main")
if cli.has_flag ("dry-run") then
print ("[DRY RUN] ")
end
print ("Deploying " + branch + " to " + env + "%N")
if env.same_string ("production") and not cli.has_flag ("yes") then
print ("Are you sure? Use -y to skip confirmation%N")
return
end
-- Deployment logic...
end
end