A personal CLI tool for Mac/Linux terminal tasks written in Rust.
Tech Stack: Rust 2024 Edition (1.94.0+)
git clone https://github.com/seokjin0414/stool.git
cd stool
cp config.yaml.example config.yaml
vim config.yaml
./install.sh # Or: ./install.sh /path/to/config.yaml
stool --help- Interactive server selection menu
- Manual IP input option
- Cancel option (silent exit)
- Multiple authentication methods:
- PEM key authentication
- Password authentication (with expect)
- Auto-accepts host key fingerprint
- Auto-enters password
- Password prompt (if not in config)
- Masked password input
- Optional: leave empty for default SSH authentication
- Default SSH key (ssh-agent, ~/.ssh/config)
- Server configuration embedded at build time
- External config file support
- Update Homebrew packages
- Update Rust toolchain
- Selective or batch updates
- Find files by pattern (exact, glob, or partial match)
- Count files and directories
- SCP-based file transfer
- Upload/Download support
- Server selection from config or manual IP input
- Cancel option (silent exit)
- Same authentication methods as SSH (including password prompt)
- Default paths: Upload(
/), Download(/Downloads/) - External config file support
- Tab completion for local file paths
- Empty input support for default paths
- Masked password input when not in config
- Build: Build Docker images with standardized options
- Platform:
linux/arm64 - Options:
--provenance=false --sbom=false - Tag:
{image}:latest - Image selection from config or manual input
- Platform:
- Push: Build, tag, and push to AWS ECR
- Auto SSO/ECR login: checks SSO session, logs in if expired, then ECR login
- Automatic version management with ECR integration
- Version types: major, middle, minor (minor default)
- Initial version:
0.1.0 - Always pushes both
latestand version tags - Auto-increments version based on current ECR tags
- Interactive AWS credential configuration
- Wraps
aws configurecommand - Command aliases:
configure,conf - ECR login with interactive registry selection
- Supports YAML config and manual input
- Automatic
aws ecr get-login-password+docker loginpipeline - SSO Support:
sso: Configure AWS SSO with hybrid auto/manual inputlogin: SSO login/token refresh with profile selection- ECR login with SSO: auto-checks session, logs in if expired
- Auto-completion for Zsh, Bash, Fish, PowerShell
- Automatically installed with install.sh
- Rust toolchain (automatically installed by install.sh)
- macOS or Linux
# 1. Clone repository
git clone https://github.com/seokjin0414/stool.git
cd stool
# 2. Create config.yaml
cp config.yaml.example config.yaml
vim config.yaml # Edit with your server information
# 3. Run installation script
./install.shThe script will:
- Check/install Rust
- Build release binary with embedded config.yaml
- Install to
~/Library/Stool/stool - Create symlink at
/usr/local/bin/stool - Auto-detect and install zsh completion (if writable)
Alternative: Specify config path
./install.sh /path/to/my-config.yamlNote: If zsh completion installation fails due to permissions, install manually:
stool completion zsh | sudo tee /opt/homebrew/share/zsh/site-functions/_stool
source ~/.zshrc# 1. Create config.yaml (required)
cp config.yaml.example config.yaml
vim config.yaml
# 2. Build release
cargo build --release
# 3. Install binary
mkdir -p ~/Library/Stool
cp target/release/stool ~/Library/Stool/
# 4. Create symlink
sudo ln -sf ~/Library/Stool/stool /usr/local/bin/stool
# 5. Install shell completion (optional)
stool completion zsh | sudo tee /usr/local/share/zsh/site-functions/_stool
source ~/.zshrcstool --help # Show all commands
stool --version # Show version
# Detailed help for each command
stool -s --help # SSH connection help
stool -u --help # System update help
stool -f --help # Filesystem operations help
stool -t --help # File transfer help
stool -d --help # Docker operations help
stool -a --help # AWS CLI help
# Subcommand help
stool -d build --help # Docker build detailed help
stool -d push --help # Docker push detailed helpNote: All commands provide detailed help messages with features, options, and workflow descriptions.
stool ssh # Use embedded config.yaml
stool -s # Short flag
stool ssh --config servers.yaml # Use external config filestool update # Update both brew and rustup
stool -u # Short flag
stool -u --brew # Update Homebrew only
stool -u --rustup # Update Rust toolchain onlystool -f find "*.rs" # Find with glob pattern
stool -f find "main.rs" # Find exact filename
stool -f find "main" # Find with partial match
stool -f find "*.toml" -p ./src # Find with custom path
stool -f count # Count in current directory
stool -f count ./src # Count in specific pathstool transfer # Use embedded config.yaml
stool -t # Short flag
stool transfer --config servers.yaml # Use external config fileFeatures:
- Upload:
- Local file path supports tab completion (required)
- Remote path accepts empty input for default (~/)
- Download:
- Remote file path is required
- Local destination path supports tab completion, empty input for default (~/Downloads/)
stool docker build # Build Docker image only
stool -d build # Short flag
stool -d build -c config.yaml # Use external config file
stool docker push # Build + tag + push to ECR
stool -d push # Short flag
stool -d push -c config.yaml # Use external config fileWorkflow:
- Select ECR registry from config
- (For push) Auto SSO/ECR login (checks session, logs in if needed)
- Select or input Docker image name
- (For push) Build image with
--platform linux/arm64 --provenance=false --sbom=false - (For push) Select version type:
- major: 0.1.0 → 1.0.0
- middle: 0.1.0 → 0.2.0
- minor: 0.1.0 → 0.1.1 (default)
- (For push) Tag and push both
latestand version tags
stool aws configure # Configure AWS credentials
stool -a configure # Short flag
stool -a conf # Alias
stool aws ecr # ECR login (embedded config.yaml)
stool -a ecr # Short flag
stool -a ecr -c servers.yaml # ECR login (external config file)
stool -a sso # Configure AWS SSO (hybrid auto/manual)
stool -a login # SSO login/token refreshSSO Configure Workflow:
- Select SSO config from YAML or manual input
- Write profile directly to
~/.aws/config(bypasses interactive UI) - Auto run
aws sso loginfor browser authentication
stool completion zsh # Generate zsh completion
stool completion bash # Generate bash completion
stool completion fish # Generate fish completion
stool completion powershell # Generate powershell completionservers:
- name: "Production Server"
ip: "192.168.1.100"
user: "admin"
password: "your-password" # Optional: password authentication
- name: "Development Server"
ip: "192.168.1.101"
user: "dev"
key_path: "~/.ssh/id_rsa" # Optional: PEM key authentication
- name: "Staging Server"
ip: "10.0.0.50"
user: "deploy"
# No password or key_path - uses default SSH authentication
ecr_registries:
- name: "Production ECR"
account_id: "123456789012" # 12-digit AWS account ID
region: "ap-northeast-2" # AWS region
sso_profile: "my-profile" # Optional: use SSO authentication
images: # Optional: Docker image names
- "my-app"
- "my-service"
- name: "Dev ECR"
account_id: "987654321098"
region: "us-east-1"
# No sso_profile - uses default aws configure credentials
images:
- "dev-app"
sso_configs:
- profile_name: "my-profile" # AWS CLI profile name
sso_session_name: "my-sso" # SSO session name
start_url: "https://company.awsapps.com/start"
region: "ap-northeast-2"
sso_account_id: "123456789012" # AWS account ID
sso_role_name: "MyRole" # IAM role name
output_format: "json" # Optional: default is jsonkey_path- PEM key authenticationpassword- Password with expect script- If neither exists - Password prompt with masked input
- Enter password: Uses expect script for authentication
- Leave empty: Uses default SSH authentication (ssh-agent, ~/.ssh/config)
# Edit config and rebuild
vim config.yaml
cargo build --release
cp target/release/stool ~/Library/Stool/
# Or use external config without rebuild
stool ssh --config /path/to/other-config.yaml# Automatically installed by install.sh (if writable)
# Or manually install to Homebrew path:
stool completion zsh | sudo tee /opt/homebrew/share/zsh/site-functions/_stool
source ~/.zshrc
# Or system path:
stool completion zsh | sudo tee /usr/local/share/zsh/site-functions/_stool
source ~/.zshrcstool completion bash | sudo tee /etc/bash_completion.d/stool
source ~/.bashrcstool completion fish > ~/.config/fish/completions/stool.fishstool/
├── stool-cli/ # Binary crate (CLI interface)
├── stool-core/ # Core types, config, and error handling
│ ├── config.rs # YAML config loading (Server, EcrRegistry)
│ └── error.rs # Unified error types and Result alias
├── stool-modules/ # Feature modules (ssh, update, filesystem, transfer, docker, aws)
│ ├── ssh.rs # SSH connection with server selection
│ ├── update.rs # System updates (brew, rustup)
│ ├── filesystem.rs # File search and count operations
│ ├── transfer.rs # SCP file transfer (upload/download)
│ ├── docker.rs # Docker operations (build, ECR push with version management)
│ └── aws.rs # AWS CLI wrapper (configure, ECR login)
└── stool-utils/ # Shared utilities
├── interactive.rs # Server selection, text/password/path input (masked, tab completion)
└── command.rs # SSH/SCP/command execution with expect -c
Architecture Highlights:
- Modular workspace structure with clear separation of concerns
- Unified error handling across all modules (24 error types)
- Shared utilities eliminate code duplication (91 lines reduced)
- Optimized for binary size and performance (LTO, strip, single codegen)
- Comprehensive documentation (25 public functions documented)
- Named constants throughout (no magic strings)
config.yamlis embedded into the binary at build time- Binary contains server information and credentials
config.yamlis gitignored by default- Keep built binaries secure
- Use external config files for sensitive environments
- Password Security:
- expect script method: Uses
expect -cto pass scripts as command-line arguments- Standard and stable approach for expect automation
- Passwords embedded in script string but cleared after process termination
- Alternative stdin method causes conflicts with interactive mode
- Interactive password prompt: Masked input using dialoguer::Password
- ECR passwords: Passed via stdin to docker login (--password-stdin)
- expect script method: Uses
Error Handling:
- All errors use unified
StoolErrorTypeenum (24 variants) - All error messages in English for consistency
unwrap()is completely prohibited; use?operator ormap_err()- Error messages include contextual information (user@ip, paths, etc.)
- Error chaining with
with_message()andwith_source() - Explicit handling of recoverable errors (e.g., directory read failures)
Code Organization:
- Common logic extracted to utility functions
- No code duplication (91 lines eliminated via helpers)
- Named constants for all hardcoded values
- Single responsibility per function
Documentation:
- Module-level docs (
//!) on every module file - Doc comments (
///) on all public functions - Arguments, Returns, and Errors sections included
- 25 public functions fully documented
Message Formatting:
- Success: "Action completed successfully" pattern
- Progress: No ellipsis, clear statements
- Errors: Detailed context with relevant information
Performance:
- LTO (Link Time Optimization) enabled
- Single codegen unit compilation
- Symbol stripping for smaller binaries
- Panic abort mode
cargo check && cargo fmt && cargo clippy -- -D warningscargo build --release# Test help
./target/release/stool --help
# Test filesystem operations
./target/release/stool -f find "*.toml"
./target/release/stool -f count .MIT License
Copyright (c) 2024 seokjin0414
seokjin0414 sars21@hanmail.net