Skip to content

Commit 4231327

Browse files
committed
chore: add bash script standards and automatic directory-based switching instructions
1 parent 2f04b3b commit 4231327

2 files changed

Lines changed: 99 additions & 29 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
applyTo: "**/*.{sh,bats,bash}"
3+
description: "Use when writing or editing bash scripts, BATS tests, or shell helpers. Covers phpvm bash coding standards, variable naming, safe patterns, and testing conventions."
4+
---
5+
# Bash Script Standards for phpvm
6+
7+
## Variable Naming
8+
- Prefix ALL global/exported variables with `PHPVM_` (e.g., `PHPVM_DIR`, `PHPVM_EXIT_ERROR`)
9+
- Use lowercase `snake_case` for local variables (`local resolved`, `local package_name`)
10+
- Define exit codes as named constants: `PHPVM_EXIT_SUCCESS=0`, `PHPVM_EXIT_ERROR=1`, etc.
11+
12+
## External Commands
13+
- Always use the `command` prefix for external utilities: `command grep`, `command awk`, `command sort`, `command cut`
14+
- Use the `command_exists` helper instead of inline `command -v X > /dev/null 2>&1`
15+
16+
## Output & Strings
17+
- Use `printf '%s\n'` instead of `echo` when outputting variable content (avoids `-n`/`-e` interpretation)
18+
- Use `$()` for command substitution, never backticks
19+
- Double-quote all variable expansions: `"$var"`, `"${arr[@]}"`
20+
- Single-quote strings with no expansions: regex patterns, format strings
21+
22+
## Control Flow
23+
- Use `if/then/fi` instead of `[ test ] && cmd` for functions that must return 0 on success
24+
- Use `|| { ... }` blocks for inline error bailouts:
25+
```bash
26+
mkdir -p "$dir" || {
27+
phpvm_err "Failed to create directory $dir"
28+
return 1
29+
}
30+
```
31+
- Use `case/esac` for command routing (not chained elif)
32+
33+
## Loops & Input Processing
34+
- Use `while IFS= read -r line` loops instead of `for x in $(...)` to avoid word-splitting
35+
- Use process substitution `< <(cmd)` when feeding loops from commands
36+
37+
## Functions
38+
- Declare as `func_name() { ... }` (no `function` keyword, no space before parens)
39+
- Document with `# Purpose:`, `# Usage:`, `# Returns:` comment blocks
40+
- Always `return` explicit exit codes (0 success, 1+ failure)
41+
42+
## Logging
43+
- Use the project helpers: `phpvm_echo` (info), `phpvm_err` (error→stderr), `phpvm_warn` (warning→stderr), `phpvm_debug` (debug-only)
44+
- Never use raw `echo` for user-facing messages
45+
46+
## ShellCheck
47+
- Code must pass ShellCheck without warnings
48+
- Suppress only with inline comments and justification: `# shellcheck disable=SC2155 # combined declare+assign is intentional`
49+
50+
## BATS Tests
51+
- Place tests in `tests/` named `NN_topic.bats` (zero-padded number prefix)
52+
- Use `test_helper.bash` for shared setup/teardown (creates `TEST_DIR`, sets `PHPVM_TEST_MODE=true`)
53+
- Assert with `[ "$status" -eq 0 ]` and `[[ "$output" =~ "pattern" ]]`
54+
- Each test must be self-contained—never depend on state from a previous test

README.md

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ PHP 8.1.13
3939
- Install and manage multiple PHP versions.
4040
- Seamlessly switch between installed PHP versions.
4141
- Auto-switch PHP versions based on project `.phpvmrc` (configurable depth via `PHPVM_PHPVMRC_MAX_DEPTH`).
42+
- Automatic directory-based switching via built-in cd hook (`PROMPT_COMMAND` for bash, `chpwd` for zsh).
4243
- Alias management for versions (`phpvm alias`, `phpvm unalias`).
4344
- Built-in version shortcuts: `latest`, `stable`, and user-defined aliases.
4445
- Cache directory inspection (`phpvm cache dir`).
@@ -94,24 +95,24 @@ If the installation was successful, it should output the path to `phpvm`.
9495

9596
### Available Commands
9697

97-
| Command | Description |
98-
| ---------------------------- | ------------------------------------------ |
99-
| `phpvm install <version>` | Install a specific PHP version |
100-
| `phpvm use <version>` | Switch to a specific PHP version |
101-
| `phpvm uninstall <version>` | Remove a specific PHP version |
102-
| `phpvm current` | Display the currently active PHP version |
103-
| `phpvm which [version]` | Show the path to PHP binary for a version |
104-
| `phpvm deactivate` | Temporarily disable phpvm and restore PATH |
105-
| `phpvm system` | Switch to system/Homebrew default PHP |
106-
| `phpvm auto` | Auto-switch based on `.phpvmrc` file |
107-
| `phpvm list` or `phpvm ls` | List all installed PHP versions |
108-
| `phpvm alias [name] [ver]` | Create, update, or list version aliases |
109-
| `phpvm unalias <name>` | Remove version alias |
110-
| `phpvm cache dir` | Show phpvm cache directory |
111-
| `phpvm info` | Show system information for debugging |
112-
| `phpvm version` | Show version information |
113-
| `phpvm --version` / `-v` | Show version information (aliases) |
114-
| `phpvm help` | Show help message |
98+
| Command | Description |
99+
| --------------------------- | ------------------------------------------ |
100+
| `phpvm install [version]` | Install a PHP version (reads `.phpvmrc` if no version given) |
101+
| `phpvm use [version]` | Switch PHP version (reads `.phpvmrc` → default alias if no version given) |
102+
| `phpvm uninstall <version>` | Remove a specific PHP version |
103+
| `phpvm current` | Display the currently active PHP version |
104+
| `phpvm which [version]` | Show the path to PHP binary for a version |
105+
| `phpvm deactivate` | Temporarily disable phpvm and restore PATH |
106+
| `phpvm system` | Switch to system/Homebrew default PHP |
107+
| `phpvm auto` | Auto-switch based on `.phpvmrc` file |
108+
| `phpvm list` or `phpvm ls` | List all installed PHP versions |
109+
| `phpvm alias [name] [ver]` | Create, update, or list version aliases |
110+
| `phpvm unalias <name>` | Remove version alias |
111+
| `phpvm cache dir` | Show phpvm cache directory |
112+
| `phpvm info` | Show system information for debugging |
113+
| `phpvm version` | Show version information |
114+
| `phpvm --version` / `-v` | Show version information (aliases) |
115+
| `phpvm help` | Show help message |
115116

116117
### Installing PHP Versions
117118

@@ -197,13 +198,28 @@ Create a `.phpvmrc` file in your project directory to specify the desired PHP ve
197198
echo "8.1" > .phpvmrc
198199
```
199200

200-
When you navigate to that project directory and run:
201+
**Automatic switching on `cd`**: When phpvm is sourced into your shell, it registers a cd hook that detects `.phpvmrc` files and switches PHP versions automatically as you navigate between directories. No manual command needed — just `cd` into a project.
202+
203+
- **Bash**: Uses `PROMPT_COMMAND`
204+
- **Zsh**: Uses `chpwd_functions`
205+
- Gated behind `PHPVM_AUTO_USE=true` (the default)
206+
- Skips switching if already on the correct version
207+
208+
**Using `use` and `install` without a version**: When no version argument is given, these commands read `.phpvmrc` automatically:
201209

202210
```sh
203-
phpvm auto
211+
# Reads version from .phpvmrc in current or parent directories
212+
phpvm use
213+
phpvm install
204214
```
205215

206-
phpvm will automatically detect and switch to the version specified in the `.phpvmrc` file.
216+
`phpvm use` follows this fallback chain: `.phpvmrc``default` alias → error.
217+
218+
**Manual switching**: You can also trigger auto-switching explicitly:
219+
220+
```sh
221+
phpvm auto
222+
```
207223

208224
Aliases can also be used in `.phpvmrc`:
209225

@@ -320,14 +336,14 @@ fi
320336

321337
## Environment Variables
322338

323-
| Variable | Default | Description |
324-
| --- | --- | --- |
325-
| `PHPVM_DIR` | `~/.phpvm` | Installation directory |
326-
| `PHPVM_AUTO_USE` | `true` | Enable automatic `.phpvmrc` detection when sourced |
327-
| `PHPVM_PHPVMRC_MAX_DEPTH` | `25` | Max parent directories to traverse when searching for `.phpvmrc` |
328-
| `DEBUG` | `false` | Enable debug logging with timestamps |
329-
| `NO_COLOR` | _(unset)_ | Disable color output ([no-color.org](https://no-color.org/)) |
330-
| `PHPVM_LOG_TIMESTAMPS` | `false` | Always show timestamps in log output |
339+
| Variable | Default | Description |
340+
| ------------------------- | ---------- | ---------------------------------------------------------------- |
341+
| `PHPVM_DIR` | `~/.phpvm` | Installation directory |
342+
| `PHPVM_AUTO_USE` | `true` | Enable automatic `.phpvmrc` detection when sourced |
343+
| `PHPVM_PHPVMRC_MAX_DEPTH` | `25` | Max parent directories to traverse when searching for `.phpvmrc` |
344+
| `DEBUG` | `false` | Enable debug logging with timestamps |
345+
| `NO_COLOR` | _(unset)_ | Disable color output ([no-color.org](https://no-color.org/)) |
346+
| `PHPVM_LOG_TIMESTAMPS` | `false` | Always show timestamps in log output |
331347

332348
## Uninstallation
333349

0 commit comments

Comments
 (0)