|
| 1 | +# GitHub Copilot Instructions for goenv |
| 2 | + |
| 3 | +## Branch Structure |
| 4 | + |
| 5 | +### Active Branches |
| 6 | +- **`main`** - Active development for v3.x (Go rewrite) - **USE THIS FOR ALL PRS** |
| 7 | +- **`master`** - Legacy v2.x maintenance only (bash-based) |
| 8 | + |
| 9 | +### PR Guidelines |
| 10 | +✅ Target `main` for: features, bug fixes, docs, improvements |
| 11 | +❌ Target `master` only for: critical v2.x security patches |
| 12 | + |
| 13 | +### Branch Naming |
| 14 | +- `fix/issue/NNN` - Bug fixes |
| 15 | +- `feature/description` - New features |
| 16 | +- `docs/description` - Documentation |
| 17 | +- `refactor/description` - Code refactoring |
| 18 | + |
| 19 | +## Project Architecture |
| 20 | + |
| 21 | +### Tech Stack |
| 22 | +- Language: Go (100% rewritten from bash in v3.x) |
| 23 | +- CLI Framework: Cobra |
| 24 | +- Testing: Go testing + some legacy BATS |
| 25 | + |
| 26 | +### Directory Structure |
| 27 | +``` |
| 28 | +cmd/ # CLI commands (Cobra-based) |
| 29 | +├── core/ # Version management (install, use, list, info) |
| 30 | +├── shims/ # Shim system (exec, rehash, which, whence) |
| 31 | +├── tools/ # Tool management (install, sync, outdated) |
| 32 | +├── shell/ # Shell integration (init, setup, prompt) |
| 33 | +├── diagnostics/ # Health checks (doctor, status) |
| 34 | +├── meta/ # Utilities (help, update, commands) |
| 35 | +├── integrations/# IDE integration (vscode) |
| 36 | +└── aliases/ # Version aliases |
| 37 | +
|
| 38 | +internal/ # Internal packages |
| 39 | +├── shims/ # Shim generation logic ⚠️ WINDOWS SENSITIVE |
| 40 | +├── manager/ # Version management |
| 41 | +├── resolver/ # Binary/version resolution |
| 42 | +├── install/ # Version installation |
| 43 | +└── utils/ # Shared utilities |
| 44 | +
|
| 45 | +docs/ # User documentation |
| 46 | +testing/ # Test utilities |
| 47 | +``` |
| 48 | + |
| 49 | +## Platform-Specific Code |
| 50 | + |
| 51 | +### Windows Development ⚠️ CRITICAL |
| 52 | + |
| 53 | +**Location**: `internal/shims/manager.go` |
| 54 | + |
| 55 | +Windows uses `.bat` files instead of bash scripts for shims. |
| 56 | + |
| 57 | +**Batch File Constraints** (Reference: Issue #555): |
| 58 | + |
| 59 | +❌ **NEVER DO**: |
| 60 | +```bat |
| 61 | +# BAD - Breaks CMD parsing! |
| 62 | +if "%var%"=="value" ( |
| 63 | + goto :label |
| 64 | +) |
| 65 | +:label |
| 66 | +
|
| 67 | +# BAD - Raw expansion in nested loop |
| 68 | +for %%a in (%*) do (...) |
| 69 | +``` |
| 70 | + |
| 71 | +✅ **ALWAYS DO**: |
| 72 | +```bat |
| 73 | +# GOOD - Use subroutines |
| 74 | +if "%var%"=="value" call :subroutine |
| 75 | +exit /b 0 |
| 76 | +
|
| 77 | +:subroutine |
| 78 | +# Logic here |
| 79 | +exit /b 0 |
| 80 | +``` |
| 81 | + |
| 82 | +**Key Rules**: |
| 83 | +1. NO goto/labels inside parenthesized `if (...)` blocks |
| 84 | +2. NO raw `%*` expansion in `for` loops |
| 85 | +3. Use single-line conditionals when possible: `if "%DEBUG%"=="1" echo on` |
| 86 | +4. Always propagate exit codes: `exit /b %ERRORLEVEL%` |
| 87 | +5. Use subroutines with `call :label` for complex logic |
| 88 | + |
| 89 | +**Testing on macOS/Linux**: |
| 90 | +- Go tests validate template logic ✅ |
| 91 | +- Cannot execute `.bat` files on Unix |
| 92 | +- CI runs Windows tests automatically |
| 93 | + |
| 94 | +## Key Implementation Patterns |
| 95 | + |
| 96 | +### Shim System Flow |
| 97 | +1. User runs `go version` |
| 98 | +2. Hits shim at `~/.goenv/shims/go` (or `go.bat` on Windows) |
| 99 | +3. Shim executes `goenv exec go version` |
| 100 | +4. `goenv exec` resolves current version from: |
| 101 | + - `GOENV_VERSION` env var (highest priority) |
| 102 | + - `.go-version` file (walks up tree) |
| 103 | + - `go.mod` toolchain directive |
| 104 | + - `~/.goenv/version` (global default) |
| 105 | + - `system` (fallback) |
| 106 | +5. Executes actual Go binary from resolved version |
| 107 | + |
| 108 | +### Shim Generation |
| 109 | +- Triggered by `goenv rehash` |
| 110 | +- Auto-rehashes after `goenv install` and `go install` |
| 111 | +- Scans all versions for binaries |
| 112 | +- Creates platform-specific wrapper (bash or .bat) |
| 113 | + |
| 114 | +### Version Resolution |
| 115 | +- `internal/resolver/resolver.go` - Core logic |
| 116 | +- Smart precedence handling |
| 117 | +- Walks directory tree for `.go-version` |
| 118 | +- Parses `go.mod` for toolchain directives |
| 119 | + |
| 120 | +## Testing Guidelines |
| 121 | + |
| 122 | +```bash |
| 123 | +# Run all tests |
| 124 | +make test |
| 125 | + |
| 126 | +# Test specific area |
| 127 | +go test -v ./cmd/shims/... |
| 128 | +go test -v ./internal/shims/... |
| 129 | + |
| 130 | +# Integration tests (require installed Go versions) |
| 131 | +go test -v ./cmd/shims/exec_integration_test.go |
| 132 | + |
| 133 | +# Build & test locally |
| 134 | +make build |
| 135 | +./goenv <command> |
| 136 | +``` |
| 137 | + |
| 138 | +## Common Development Tasks |
| 139 | + |
| 140 | +### Adding a New Command |
| 141 | +1. Create in appropriate `cmd/<category>/` directory |
| 142 | +2. Use Cobra framework pattern |
| 143 | +3. Add to parent command's `init()` |
| 144 | +4. Write tests in `<name>_test.go` |
| 145 | +5. Update documentation |
| 146 | + |
| 147 | +### Modifying Shim Templates |
| 148 | +1. Edit `internal/shims/manager.go` |
| 149 | +2. Update `createUnixShim()` OR `createWindowsShim()` |
| 150 | +3. ⚠️ Windows changes require extra care - see constraints above |
| 151 | +4. Test: `go test ./internal/shims/... ./cmd/shims/...` |
| 152 | +5. Consider Windows batch file gotchas |
| 153 | + |
| 154 | +### Adding Platform Support |
| 155 | +1. Update `internal/utils/` for OS detection |
| 156 | +2. Add platform-specific shim generator |
| 157 | +3. Update install scripts |
| 158 | +4. Test on target platform |
| 159 | + |
| 160 | +## Code Style |
| 161 | + |
| 162 | +### Conventional Commits |
| 163 | +``` |
| 164 | +feat(area): description |
| 165 | +fix(area): description |
| 166 | +docs(area): description |
| 167 | +refactor(area): description |
| 168 | +test(area): description |
| 169 | +``` |
| 170 | + |
| 171 | +### Error Handling |
| 172 | +- Use `internal/errors` package |
| 173 | +- Provide context: `errors.FailedTo("action", err)` |
| 174 | +- User-friendly messages |
| 175 | + |
| 176 | +### Configuration |
| 177 | +- Respect environment variables (`GOENV_*`) |
| 178 | +- Use `internal/config` for paths |
| 179 | +- Support `GOENV_ROOT` customization |
| 180 | + |
| 181 | +## Environment Variables |
| 182 | + |
| 183 | +- `GOENV_ROOT` - Installation directory (default: `~/.goenv`) |
| 184 | +- `GOENV_VERSION` - Override current version |
| 185 | +- `GOENV_DEBUG` - Enable debug logging |
| 186 | +- `GOENV_NO_AUTO_REHASH` - Disable auto-rehash (for CI/CD) |
| 187 | + |
| 188 | +## Build & Release |
| 189 | + |
| 190 | +```bash |
| 191 | +make build # Current platform |
| 192 | +make test # Run tests |
| 193 | +make cross-build # All platforms |
| 194 | +make install # Install to GOENV_ROOT |
| 195 | +``` |
| 196 | + |
| 197 | +GitHub Actions builds release binaries for all platforms. |
| 198 | + |
| 199 | +## Key Files to Know |
| 200 | + |
| 201 | +- `internal/shims/manager.go` - Shim generation (Windows-sensitive!) |
| 202 | +- `internal/resolver/resolver.go` - Version resolution |
| 203 | +- `internal/manager/manager.go` - Version management |
| 204 | +- `cmd/root.go` - Root command & global flags |
| 205 | +- `main.go` - Entry point |
| 206 | + |
| 207 | +## Documentation |
| 208 | + |
| 209 | +- User docs: `docs/` |
| 210 | +- Contributing: `CONTRIBUTING.md` |
| 211 | +- Quick reference: `docs/QUICK_REFERENCE.md` |
| 212 | +- Code should be self-documenting with clear comments |
| 213 | + |
| 214 | +## Issue Resolution Checklist |
| 215 | + |
| 216 | +When fixing issues: |
| 217 | +1. ✅ Read issue thoroughly including comments |
| 218 | +2. ✅ Identify affected files/components |
| 219 | +3. ✅ Check for similar issues in issue tracker |
| 220 | +4. ✅ Write failing test first (TDD) |
| 221 | +5. ✅ Implement fix |
| 222 | +6. ✅ Verify all tests pass |
| 223 | +7. ✅ Update documentation if needed |
| 224 | +8. ✅ Create PR against `main` branch |
| 225 | +9. ✅ Reference issue number in commit: `Fixes #NNN` |
| 226 | + |
| 227 | +## Windows-Specific Issue Patterns |
| 228 | + |
| 229 | +Common Windows issues to watch for: |
| 230 | +- Batch file syntax errors (goto/label problems) |
| 231 | +- Path separators (use `filepath.Join`) |
| 232 | +- Line endings (CRLF vs LF - see `.gitattributes`) |
| 233 | +- Executable detection (file extensions) |
| 234 | +- Permission model differences |
| 235 | + |
| 236 | +## Need Help? |
| 237 | + |
| 238 | +- Check existing tests for patterns |
| 239 | +- Review similar commands for consistency |
| 240 | +- Ask in PR for architectural guidance |
| 241 | +- See `CONTRIBUTING.md` for full guidelines |
0 commit comments