ptc-cli-bash/
├── ptc-cli.sh # Main executable script
├── README.md # Main documentation
├── config/ # Configurations
│ └── examples/ # Configuration examples
│ ├── react-app.config # For React applications
│ └── java-app.config # For Java applications
├── tests/ # Testing
│ ├── test-runner.sh # Main test runner
│ └── fixtures/ # Test data (created automatically)
└── docs/ # Documentation
└── DEVELOPMENT.md # This guide
- Argument parsing: Command line processing with support for long and short options
- Validation: Input data and environment checking
- File search: Search system with globbing and pattern support
- Processing: Main logic for working with found files
- Logging: Color output with different levels
- Fail Fast: Stop on first error
- Strict mode:
set -euo pipefail - Idempotency: Repeated runs give same result
- Transparency: Detailed logging of all operations
- Modularity: Separation into functions with clear responsibilities
# Clone project
git clone <repository-url>
cd ptc-cli-bash
# Set execution permissions
chmod +x ptc-cli.sh
chmod +x tests/test-runner.sh# Run all tests
./tests/test-runner.sh
# Test specific functionality
./ptc-cli.sh -s en -p '{lang}-copy.json' --dry-run --verboseEnable verbose mode for debugging:
./ptc-cli.sh -s en -p '{lang}/**/*.json' --verbose --dry-runFor additional bash debugging you can use:
bash -x ./ptc-cli.sh -s en -p '{lang}-copy.json' --dry-run- Add variable in "Default variables" section
- Add handling in
main()function in argument parsing section - Add validation in
validate_args()function - Update
show_help() - Add tests
Example of adding --timeout option:
# In variables section
TIMEOUT=300
# In argument parsing
-t|--timeout)
TIMEOUT="$2"
shift 2
;;
# In validation
if [[ ! "$TIMEOUT" =~ ^[0-9]+$ ]]; then
log_error "Timeout must be a number: $TIMEOUT"
return 1
fiModify find_files_by_pattern() function to support new patterns.
Main processing logic is in process_single_file() function. Add your logic there.
- Use
readonlyfor constants - Always use
localfor function variables - Quote variables:
"$variable" - Use
[[ ]]instead of[ ]for conditions - Functions should return 0 on success, non-0 on error
- Constants:
UPPER_SNAKE_CASE - Variables:
lower_snake_case - Functions:
lower_snake_case - Private functions:
_prefixed_with_underscore
Use appropriate logging functions:
log_info "General information"
log_success "Successful operation"
log_warning "Warning"
log_error "Error"
log_debug "Debug information"Tests are in tests/test-runner.sh and follow the pattern:
test_function_name() {
# Test logic
return 0 # success
return 1 # failure
}
run_test "Test description" test_function_name- Create test function in
test-runner.sh - Add
run_testcall inmain()function - If needed, add test data in
setup_fixtures()
Test files are automatically created in setup_fixtures() and removed in cleanup_fixtures().
Script supports configuration via environment variables:
PTC_SOURCE_LOCALEPTC_PATTERNSPTC_PROJECT_DIRPTC_VERBOSEPTC_DRY_RUN
0: Successful execution1: Validation error or no files found2: File processing error
In CI environments, color codes are automatically disabled when necessary.
- All user input is validated
- File paths are checked for existence
- Prevents execution of arbitrary commands
If temporary files are created, they should:
- Be created in a secure location
- Be removed in
cleanup()function - Have restricted access permissions
- Use
mapfileinstead of loops for reading command output - Minimize number of external command calls
- Cache results of repeated operations
- For very large projects (>10000 files) consider using
parallel - Add timeouts for long-running operations
- Files not found: Check patterns and paths
- Permission denied: Ensure file permissions
- Bash version: Requires Bash 3.2+ (compatible with macOS default)
# Enable bash debugging
set -x
# Check bash version
bash --version
# Check file permissions
ls -la ptc-cli.shTo extend functionality you can add plugin system:
- Create
plugins/directory - Add plugin loading mechanism
- Define plugin API
System already supports configuration files. To add new formats modify configuration loading logic.
Uses semantic versioning (semver):
MAJOR.MINOR.PATCH- Update version in
VERSIONconstant
- Update version in script
- Update CHANGELOG
- Create git tag
- Test on all supported platforms