This guide will help you set up your development environment for contributing to phpvm.
- macOS or Linux
- Git
- Bash 4.0+ (or compatible shell)
- Basic understanding of shell scripting
# Clone the repository
git clone https://github.com/Thavarshan/phpvm.git
cd phpvm
# Install development dependencies
make install
# Install git hooks
make install-hooks
# Run all checks to verify setup
make check# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install development tools
brew install shellcheck shfmt bats-coresudo apt-get update
sudo apt-get install -y shellcheck bats
# shfmt (manual installation)
wget -O shfmt https://github.com/mvdan/sh/releases/download/v3.12.0/shfmt_v3.12.0_linux_amd64
chmod +x shfmt
sudo mv shfmt /usr/local/bin/sudo dnf install -y ShellCheck
# Install BATS and shfmt manually (see Ubuntu instructions)Install pre-commit hooks to automatically run quality checks:
make install-hooksThis will:
- Check code formatting before each commit
- Run linter (ShellCheck) before each commit
- Prevent commits if checks fail
To bypass hooks (use sparingly):
git commit --no-verifyInstall recommended extensions:
code --install-extension timonwong.shellcheck
code --install-extension foxundermoon.shell-format
code --install-extension rogalmic.bash-debugThe project includes .vscode/settings.json with:
- ShellCheck integration
- Shell script formatting settings
- File associations
- Testing support
Add to your .vimrc or init.vim:
" Enable syntax checking with ShellCheck
let g:syntastic_sh_checkers = ['shellcheck']
let g:syntastic_sh_shellcheck_args = '-x'
" Set indentation for shell scripts
autocmd FileType sh setlocal shiftwidth=4 tabstop=4 expandtabgit checkout -b feature/your-feature-nameEdit phpvm.sh or other files as needed.
# Quick check (fast feedback)
make lint
# Format code
make format
# Run tests
make test
# Run all checks
make checkAdd tests for new features:
BATS tests - Add to appropriate file in tests/:
@test "your feature works correctly" {
run your_function arg1 arg2
[ "$status" -eq 0 ]
[[ "$output" =~ "expected" ]]
}git add .
git commit -m "feat: add new feature"Pre-commit hooks will run automatically.
git push origin feature/your-feature-nameThen create a pull request on GitHub.
make help # Show all available commands
make install # Install development dependencies
make install-hooks # Install git pre-commit hooks
make lint # Run ShellCheck linter
make format # Format code with shfmt
make format-check # Check formatting (CI mode)
make test # Run built-in tests
make test-bats # Run BATS test suite
make test-all # Run all tests
make check # Run all quality checks
make clean # Remove temporary files
make release # Prepare for release# Run phpvm tests
# Run BATS tests
bats tests/
# Run ShellCheck
shellcheck phpvm.sh install.sh
# Format with shfmt
shfmt -w -i 4 -sr phpvm.sh install.shtests/
βββ test_helper.bash # Setup and helper functions
βββ 01_core.bats # Core functionality
βββ 02_features.bats # Features and placeholders
βββ 03_error_handling.bats # Error handling
# All tests
make test-all
# Built-in tests only
make test
# BATS tests only
make test-bats
# Specific BATS file
bats tests/01_core.bats
# With verbose output
bats -t tests/See TESTING.md and tests/README.md for detailed information.
- Indentation: 4 spaces (no tabs)
- Line length: 120 characters max
- Function naming:
snake_case - Variable naming:
UPPER_CASEfor globals,lower_casefor locals - Comments: Use
#for single-line comments - Error handling: Always check return codes
# Good function example
phpvm_example_function() {
local input="$1"
local result
# Validate input
if [ -z "$input" ]; then
phpvm_err "Input required"
return $PHPVM_EXIT_INVALID_ARG
fi
# Process input
result=$(process_input "$input")
# Return result
echo "$result"
return 0
}Follow conventional commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Test additions or changeschore: Build process or auxiliary tool changes
Examples:
feat(alias): add alias management system
fix(install): handle missing repository gracefully
docs(testing): update testing guide
test(core): add tests for version resolutionRead the warning message and fix accordingly. Common issues:
SC2086: Quote variables to prevent word splittingSC2155: Declare and assign separatelySC2034: Variable appears unused
Disable specific warnings if intentional:
# shellcheck disable=SC2086
some_command $unquoted_var- Ensure you're using bash, not sh
- Check your package manager setup
- Verify environment variables
- Review test isolation
# Bypass hooks temporarily
git commit --no-verify
# Remove hooks
rm .git/hooks/pre-commit
# Reinstall hooks
make install-hooks- quality.yml - Runs linting, formatting, and all tests
- test.yml - Main test suite across platforms
- security-test.yml - Security analysis
- release.yml - Release automation
# Run same checks as CI
make check- TESTING.md - Comprehensive testing guide
- IMPLEMENTATION_GUIDE.md - Feature implementation guide
- NVM_FEATURE_GAPS.md - Feature roadmap
- BATS Documentation
- ShellCheck Wiki
- Google Shell Style Guide
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Check the docs directory
- Explore the codebase - Read
phpvm.shto understand structure - Run tests - Get familiar with the test suite
- Pick an issue - Look for "good first issue" labels
- Implement Phase 1 features - See IMPLEMENTATION_GUIDE.md
- Ask questions - Don't hesitate to open discussions
Happy coding! π
Last Updated: January 15, 2026 For Contributors: Thank you for contributing to phpvm!