Skip to content

Conversation

@thoraxe
Copy link

@thoraxe thoraxe commented Dec 8, 2025

This commit enables comprehensive Windows support with both Git Bash and PowerShell shell integration, providing Windows users with the same seamless worktree management experience as macOS and Linux users.

Changes:

  • Enable Windows AMD64 builds in .goreleaser.yml with zip packaging
  • Add PowerShell (pwsh) to supported shells in shell_init.go
  • Implement PowerShell completion script patching to fix command name resolution
  • Create PowerShell cd hook with smart executable path discovery
  • Fix path separator handling in tests for cross-platform compatibility
  • Skip Unix-specific path tests on Windows with TODO comments
  • Re-enable windows-latest in GitHub Actions CI matrix
  • Add Git configuration for Windows CI to handle line endings
  • Update README with comprehensive Windows installation and setup instructions

PowerShell Integration:

  • Uses 'pwsh' identifier (urfave/cli standard for PowerShell)
  • Patches completion script to hardcode 'wtp' command name
  • Implements smart executable discovery (PATH -> current directory)
  • Prevents infinite recursion by storing executable path reference
  • Documents warning suppression for clean user experience

Git Bash Integration:

  • Works out of the box with existing Bash completion
  • Uses standard Bash hook implementation
  • No Windows-specific changes needed

Testing:

  • Fixed cross-platform path tests using filepath.Join()
  • Added runtime.GOOS checks for Windows test skipping
  • CI validates builds on windows-latest runner

🚀 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added native Windows builds and PowerShell (pwsh) integration for hooks and completion.
  • Documentation

    • Added Windows installation and setup guidance, including PowerShell usage examples.
  • Chores

    • Updated CI and release configurations to produce Windows artifacts and Windows-specific archives.
  • Bug Fixes

    • Improved cross-platform path normalization and symlink handling.
  • Tests

    • Adjusted tests to account for Windows environments and platform-specific behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

Walkthrough

Adds Windows support across CI/release, PowerShell completion/hooks and shell-init, cross-platform path handling and tests, and documentation for Windows installation and usage.

Changes

Cohort / File(s) Summary
CI / Release
​.github/workflows/ci.yml, ​.goreleaser.yml
Re-enable Windows in CI matrix; add Windows-specific Git core.autocrlf/core.eol step; restore Windows build command; add Windows as a goreleaser build target and set Windows archives to zip; add goos/arch ignore rule for unsupported combos.
PowerShell integration (CLI)
cmd/wtp/completion_config.go, cmd/wtp/hook.go, cmd/wtp/shell_init.go
Add pwsh/PowerShell handling for completion patching, hook generation, and shell-init subcommand; implement patchPowerShellCompletionScript, printPowerShellHook, and shellInitPowerShell; update help/usage text to include PowerShell.
Path handling / Worktree logic
cmd/wtp/worktree_managed.go
Normalize and clean paths before computing relativity: use filepath.Clean, filepath.Abs, and filepath.EvalSymlinks with fallback when symlink resolution fails.
Tests — cross-platform fixes & Windows guards
cmd/wtp/testhelpers_test.go, cmd/wtp/list_test.go, cmd/wtp/add_test.go, cmd/wtp/cd_test.go
Replace hard-coded "/" path expectations with filepath.Join for platform-agnostic assertions; add runtime import and GOOS == "windows" guards that skip specific tests on Windows with TODO notes.
Documentation
README.md
Add Windows installation and shell-integration guidance (PowerShell/Git Bash/From Source) and minor wording tweaks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Inspect PowerShell script patching and hook generation for correctness and edge cases.
  • Verify worktree path normalization, symlink resolution fallback, and no change to Rel-based logic.
  • Review CI and goreleaser Windows-specific steps and archive settings.
  • Check tests skipped on Windows and filepath.Join conversions.

Possibly related PRs

Suggested labels

codex

Poem

🐰 I hopped through paths both clean and sly,
PowerShell whispers, "wtp" — oh my!
CI builds on windows, little bells ring,
Cross-platform trails make my heart sing,
A tiny rabbit cheers: forward we spring! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.31% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Windows support for Git Bash and PowerShell' accurately summarizes the main objective of the PR, which is to add comprehensive Windows support for both Git Bash and PowerShell shells.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thoraxe
Copy link
Author

thoraxe commented Dec 8, 2025

"it worked on my machine"...

- Add Windows (amd64/arm64) to CI workflow and GoReleaser config
- Fix shell detection and hook scripts for Git Bash and PowerShell
- Fix path separator handling in worktree management (git returns
  forward slashes on Windows, Go uses backslashes)
- Skip tests with hardcoded Unix paths on Windows

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@thoraxe
Copy link
Author

thoraxe commented Dec 9, 2025

I just force pushed a fix for a number of things --

  1. handles some problems with powershell/windows pathing
  2. handles links (i have multiple drives with windows symlinks)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
cmd/wtp/hook.go (1)

171-227: PowerShell hook implementation is solid with minor suggestions.

The PowerShell hook correctly:

  • Stores $__wtpPath to prevent recursion
  • Checks for --generate-shell-completion flag
  • Implements cd functionality matching other shells

However, the executable discovery (lines 176-194) searches PATH then falls back to the current directory. While this works for testing, users who install wtp to a custom location outside PATH and without running from the install directory may encounter issues.

Consider documenting this discovery behavior in the PowerShell setup section of the README, or add a warning when $__wtpPath is not found:

 function wtp {
     if (-not $__wtpPath) {
-        Write-Error "wtp executable not found. Please ensure wtp is in your PATH or current directory."
+        Write-Error "wtp executable not found. Please ensure wtp is in your PATH or current directory. Run 'Get-Command wtp' to verify installation."
         return 1
     }
README.md (1)

315-322: Clarify the WarningPreference workaround.

The PowerShell setup silences warnings with $WarningPreference = 'SilentlyContinue'. While this prevents noise, it might hide legitimate warnings from the shell-init script.

Consider adding a brief explanation of why this is needed, or investigate if the underlying warnings can be fixed:

 **PowerShell:**
 
 Add to your PowerShell profile (`$PROFILE` - typically `~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1` or `~\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`):
 
 ```powershell
 # Add wtp shell integration (completion + cd functionality)
+# Note: Suppress warnings during initialization to avoid PowerShell module loading messages
 $WarningPreference = 'SilentlyContinue'
 Invoke-Expression -Command (& wtp shell-init pwsh | Out-String)
 $WarningPreference = 'Continue'

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used**: CodeRabbit UI

**Review profile**: CHILL

**Plan**: Pro

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between ffd7a2bc5e0b442da6e1dfc3e0eaddd471ad0c2c and 5c6f136f726e00df5bb01509276c35c164338fbe.

</details>

<details>
<summary>📒 Files selected for processing (11)</summary>

* `.github/workflows/ci.yml` (2 hunks)
* `.goreleaser.yml` (2 hunks)
* `README.md` (3 hunks)
* `cmd/wtp/add_test.go` (6 hunks)
* `cmd/wtp/cd_test.go` (2 hunks)
* `cmd/wtp/completion_config.go` (2 hunks)
* `cmd/wtp/hook.go` (4 hunks)
* `cmd/wtp/list_test.go` (3 hunks)
* `cmd/wtp/shell_init.go` (4 hunks)
* `cmd/wtp/testhelpers_test.go` (1 hunks)
* `cmd/wtp/worktree_managed.go` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (4)</summary>

* cmd/wtp/testhelpers_test.go
* cmd/wtp/completion_config.go
* .github/workflows/ci.yml
* .goreleaser.yml

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (2)</summary>

<details>
<summary>**/*.go</summary>


**📄 CodeRabbit inference engine (AGENTS.md)**

> `**/*.go`: Follow standard Go style with tabs and gofmt; package names must be short and lowercase
> Keep import groups tidy; use goimports for organization with local prefix following module path `github.com/satococoa/wtp/v2`
> Adhere to linting rules in `.golangci.yml` (vet, staticcheck, gosec, mnd, lll=120)
> Wrap errors with context; avoid ignoring errors in Go code
> Use snake_case for Go filenames (e.g., `remove.go`, `shell_integration.go`)
> Document exported items in Go when non-trivial; follow godoc conventions

Files:
- `cmd/wtp/worktree_managed.go`
- `cmd/wtp/shell_init.go`
- `cmd/wtp/list_test.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`
- `cmd/wtp/hook.go`

</details>
<details>
<summary>**/*_test.go</summary>


**📄 CodeRabbit inference engine (AGENTS.md)**

> `**/*_test.go`: Unit tests must be placed alongside packages as `*_test.go` files in the same directory
> Target 70% code coverage with unit tests focusing on fast feedback and mocked git interactions using table-driven test cases

Files:
- `cmd/wtp/list_test.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`

</details>

</details><details>
<summary>🧠 Learnings (14)</summary>

<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Update README and CLI help text when user-facing behavior changes


**Applied to files:**
- `README.md`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Use go run ./cmd/wtp <args> for rapid feedback during development instead of building binaries


**Applied to files:**
- `README.md`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: CLI entrypoint is located at cmd/wtp; new command implementations must integrate with the main CLI structure


**Applied to files:**
- `README.md`
- `cmd/wtp/shell_init.go`
- `cmd/wtp/list_test.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`
- `cmd/wtp/hook.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Shell integration must separate completion and hooks for clarity; wtp cd outputs absolute worktree path with no side effects


**Applied to files:**
- `README.md`
- `cmd/wtp/worktree_managed.go`
- `cmd/wtp/shell_init.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/hook.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Toggle shell integration paths with WTP_SHELL_INTEGRATION=1 when testing cd behavior


**Applied to files:**
- `README.md`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Run commands from inside a worktree to mimic real usage (e.g., go run ../cmd/wtp add feature/new-feature)


**Applied to files:**
- `README.md`
- `cmd/wtp/worktree_managed.go`
- `cmd/wtp/shell_init.go`
- `cmd/wtp/list_test.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to **/*.go : Keep import groups tidy; use goimports for organization with local prefix following module path github.com/satococoa/wtp/v2


**Applied to files:**
- `cmd/wtp/worktree_managed.go`
- `cmd/wtp/list_test.go`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to **/*_test.go : Target 70% code coverage with unit tests focusing on fast feedback and mocked git interactions using table-driven test cases


**Applied to files:**
- `cmd/wtp/list_test.go`
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: The root module is github.com/satococoa/wtp/v2 running on Go 1.24; maintain module path consistency


**Applied to files:**
- `cmd/wtp/list_test.go`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to **/*.go : Wrap errors with context; avoid ignoring errors in Go code


**Applied to files:**
- `cmd/wtp/list_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to test/e2e/**/*.go : End-to-end tests must be placed in test/e2e and exercise real git workflows using the built binary


**Applied to files:**
- `cmd/wtp/cd_test.go`
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to **/*_test.go : Unit tests must be placed alongside packages as *_test.go files in the same directory


**Applied to files:**
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Run go tool task dev before committing to ensure code is formatted, linted, and tests pass


**Applied to files:**
- `cmd/wtp/add_test.go`

</details>
<details>
<summary>📚 Learning: 2025-12-02T13:33:48.693Z</summary>

Learnt from: CR
Repo: satococoa/wtp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-02T13:33:48.693Z
Learning: Applies to .wtp.yml : Project hooks must be defined in .wtp.yml; keep commands deterministic and safe, avoiding destructive steps by default


**Applied to files:**
- `cmd/wtp/hook.go`

</details>

</details><details>
<summary>🧬 Code graph analysis (4)</summary>

<details>
<summary>cmd/wtp/worktree_managed.go (2)</summary><blockquote>

<details>
<summary>internal/git/repository_integration_test.go (1)</summary>

* `TestGetMainWorktreePath` (11-32)

</details>
<details>
<summary>internal/config/config.go (1)</summary>

* `c` (167-173)

</details>

</blockquote></details>
<details>
<summary>cmd/wtp/shell_init.go (2)</summary><blockquote>

<details>
<summary>cmd/wtp/shell_init_test.go (2)</summary>

* `TestNewShellInitCommand` (12-32)
* `TestShellInitCommand_OutputsValidScripts` (34-79)

</details>
<details>
<summary>test/e2e/shell_test.go (1)</summary>

* `TestShellEnvironment` (167-191)

</details>

</blockquote></details>
<details>
<summary>cmd/wtp/cd_test.go (1)</summary><blockquote>

<details>
<summary>internal/hooks/executor_test.go (1)</summary>

* `TestExecutePostCreateHooks_Command` (103-140)

</details>

</blockquote></details>
<details>
<summary>cmd/wtp/hook.go (1)</summary><blockquote>

<details>
<summary>internal/command/types.go (1)</summary>

* `Command` (4-8)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (6)</summary><blockquote>

<details>
<summary>cmd/wtp/cd_test.go (1)</summary><blockquote>

`20-22`: **Appropriate Windows guard for Unix-specific paths.**

The test skip is correct—this test uses hardcoded Unix paths (`/Users/dev/project/main`) that won't work on Windows.

</blockquote></details>
<details>
<summary>cmd/wtp/worktree_managed.go (1)</summary><blockquote>

`29-51`: **Robust cross-platform path normalization.**

The changes correctly handle Windows-specific path issues:
- `filepath.Clean` normalizes Git's forward slashes to OS-native separators
- `EvalSymlinks` resolves symlinks and Windows junction points with safe fallback
- The approach is backward-compatible with Unix systems

</blockquote></details>
<details>
<summary>cmd/wtp/add_test.go (1)</summary><blockquote>

`286-288`: **Consistent Windows test guards across multiple test cases.**

All five Windows guards correctly skip tests that use Unix-specific hardcoded paths. The TODO comments indicate these will be addressed in future work.



Also applies to: 335-337, 477-479, 567-569, 762-764

</blockquote></details>
<details>
<summary>README.md (1)</summary><blockquote>

`117-139`: **Comprehensive Windows installation instructions.**

The installation steps for both PowerShell and Git Bash are clear and well-structured.

</blockquote></details>
<details>
<summary>cmd/wtp/shell_init.go (1)</summary><blockquote>

`67-72`: **PowerShell shell-init follows established patterns.**

The implementation correctly mirrors bash/zsh/fish structure: outputs completion first, then the hook. Test coverage for PowerShell functionality in shell_init_test.go must be verified to confirm this implementation is fully tested.

</blockquote></details>
<details>
<summary>cmd/wtp/list_test.go (1)</summary><blockquote>

`681-683`: **Test skipping with TODO tracking is appropriate.**

The Windows guard correctly skips this test that relies on Unix-specific path conventions, allowing the test suite to maintain appropriate coverage targets while acknowledging the platform limitation. The TODO comment provides inline tracking of this limitation.

</blockquote></details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant