fix: windows (#1056)
* fix windows * fix: address code review feedback - unused imports and async function - Remove unused imports in TypeScript files: - platform.test.ts: remove unused beforeEach, afterAll, test, os, fs, ShellType; add missing afterEach, it - cli-tool-manager.ts: remove unused getPathDelimiter - paths.ts: remove unused homeDir variable - Remove unused imports in Python files: - client.py: remove unused get_claude_detection_paths import - test_platform.py: remove unused pytest, MagicMock, find_executable, get_comspec_path - Fix findExecutable in platform/index.ts: change from async to sync (function uses synchronous existsSync, should not be async) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: correct Windows path construction and Python type annotations Fixes: 1. Windows path construction - path.join('C:', ...) produces 'C:foo' (relative to C: drive), not 'C:\foo'. Changed to 'C:\Program Files' as the first segment to get proper absolute paths. 2. getCurrentOS() now handles unknown platforms (e.g., FreeBSD) by defaulting to Linux for Unix-like systems. 3. getPlatformDescription() now has a fallback when OS mapping fails. 4. Shell config test now accepts cmd.exe fallback (when PowerShell paths don't exist in test environments). 5. Python ruff fixes - sorted imports and modernized type annotations (list instead of List, dict instead of Dict, X | None instead of Optional[X]). Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix comment (sentry) and tests * try and fix lint and tests * fix tests * fix remaining * we need to add more tests, i have a PR for this but it has been ignored * fix(tests): normalize path separators in fs.existsSync mock for Windows path.join() uses backslashes on Windows, so the mock now normalizes paths to forward slashes before comparison to ensure tests pass cross-platform. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * fix(platform): address code review findings for cross-platform safety - Fix argument quoting vulnerability in build_windows_command using subprocess.list2cmdline() - Remove duplicate Claude detection paths from client.py by using platform module - Add empty string check in withExecutableExtension (TypeScript) - Add empty string check in isSecurePath (TypeScript) for cross-platform consistency - Add Homebrew paths for macOS in getClaudeExecutablePath (TypeScript) - Fix misleading CI step name (was "Setup Node.js and Python", now "Setup Python") - Fix expandWindowsEnvVars to provide sensible defaults for unset env vars Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(platform): condense path construction and expand Python glob patterns - Condense multi-line path construction in get_claude_detection_paths_structured() to single-line expressions for cleaner ruff formatting - Fix getPythonPaths() to expand glob patterns (Python3*) using readdirSync instead of returning literal glob strings that existsSync can't handle - Add expandDirPattern helper function for safe directory pattern matching Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(platform): return Python commands as argument sequences Change get_python_commands() / getPythonCommands() to return command arguments as sequences (list of lists) instead of space-separated strings. Before: ["py -3", "python"] - broken with subprocess/shutil.which After: [["py", "-3"], ["python"]] - works correctly This allows callers to: - Pass cmd directly to subprocess.run(cmd) - Use cmd[0] with shutil.which() for executable lookup Updated both Python and TypeScript implementations for consistency. Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]> Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Andy <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.5
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Andy
parent
30638c2f16
commit
d6234f52b1
@@ -40,9 +40,21 @@ Follow conventional commits: `<type>: <subject>`
|
||||
- [ ] I've followed the code principles (SOLID, DRY, KISS)
|
||||
- [ ] My PR is small and focused (< 400 lines ideally)
|
||||
|
||||
## Platform Testing Checklist
|
||||
|
||||
**CRITICAL:** This project supports Windows, macOS, and Linux. Platform-specific bugs are a common source of breakage.
|
||||
|
||||
- [ ] **Windows tested** (either on Windows or via CI)
|
||||
- [ ] **macOS tested** (either on macOS or via CI)
|
||||
- [ ] **Linux tested** (CI covers this)
|
||||
- [ ] Used centralized `platform/` module instead of direct `process.platform` checks
|
||||
- [ ] No hardcoded paths (used `findExecutable()` or platform abstractions)
|
||||
|
||||
**If you only have access to one OS:** CI now tests on all platforms. Ensure all checks pass before submitting.
|
||||
|
||||
## CI/Testing Requirements
|
||||
|
||||
- [ ] All CI checks pass
|
||||
- [ ] All CI checks pass on **all platforms** (Windows, macOS, Linux)
|
||||
- [ ] All existing tests pass
|
||||
- [ ] New features include test coverage
|
||||
- [ ] Bug fixes include regression tests
|
||||
|
||||
+103
-17
@@ -1,3 +1,11 @@
|
||||
# Cross-Platform CI Pipeline
|
||||
#
|
||||
# Tests on all target platforms (Linux, Windows, macOS) to catch
|
||||
# platform-specific bugs before they merge. ALL platforms must pass.
|
||||
#
|
||||
# Why this matters: Platform-specific code often breaks when developers
|
||||
# commit from one OS without testing on others. This CI prevents that.
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
@@ -15,15 +23,21 @@ permissions:
|
||||
actions: read
|
||||
|
||||
jobs:
|
||||
# Python tests
|
||||
# --------------------------------------------------------------------------
|
||||
# Python Backend Tests - All Platforms
|
||||
# --------------------------------------------------------------------------
|
||||
test-python:
|
||||
runs-on: ubuntu-latest
|
||||
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false # Don't cancel all jobs if one platform fails
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.12', '3.13']
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
@@ -31,13 +45,14 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install uv
|
||||
- name: Install uv package manager
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: "latest"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: apps/backend
|
||||
shell: bash
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install -r requirements.txt
|
||||
@@ -45,22 +60,32 @@ jobs:
|
||||
|
||||
- name: Run tests
|
||||
working-directory: apps/backend
|
||||
shell: bash
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}/apps/backend
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
source .venv/Scripts/activate
|
||||
else
|
||||
source .venv/bin/activate
|
||||
fi
|
||||
pytest ../../tests/ -v --tb=short -x
|
||||
|
||||
- name: Run tests with coverage
|
||||
- name: Run coverage (Python 3.12 only)
|
||||
if: matrix.python-version == '3.12'
|
||||
working-directory: apps/backend
|
||||
shell: bash
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}/apps/backend
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
pytest ../../tests/ -v --cov=. --cov-report=xml --cov-report=term-missing --cov-fail-under=20
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
source .venv/Scripts/activate
|
||||
else
|
||||
source .venv/bin/activate
|
||||
fi
|
||||
pytest ../../tests/ -v --cov=. --cov-report=xml --cov-report=term-missing --cov-fail-under=10
|
||||
|
||||
- name: Upload coverage reports
|
||||
- name: Upload coverage to Codecov
|
||||
if: matrix.python-version == '3.12'
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
@@ -69,11 +94,20 @@ jobs:
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
# Frontend lint, typecheck, test, and build
|
||||
# --------------------------------------------------------------------------
|
||||
# Frontend Tests - All Platforms
|
||||
# --------------------------------------------------------------------------
|
||||
test-frontend:
|
||||
runs-on: ubuntu-latest
|
||||
name: Frontend on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
@@ -83,9 +117,11 @@ jobs:
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
shell: bash
|
||||
run: echo "dir=$(npm config get cache)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
@@ -95,18 +131,68 @@ jobs:
|
||||
working-directory: apps/frontend
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: Lint
|
||||
- name: Run linter
|
||||
working-directory: apps/frontend
|
||||
run: npm run lint
|
||||
|
||||
- name: Type check
|
||||
- name: Run TypeScript type check
|
||||
working-directory: apps/frontend
|
||||
run: npm run typecheck
|
||||
|
||||
- name: Run tests
|
||||
- name: Run unit tests
|
||||
working-directory: apps/frontend
|
||||
run: npm run test
|
||||
|
||||
- name: Build
|
||||
- name: Build application
|
||||
working-directory: apps/frontend
|
||||
run: npm run build
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Platform-Specific Integration Tests
|
||||
# --------------------------------------------------------------------------
|
||||
test-platform-integration:
|
||||
name: Platform Integration Tests on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
# Only run integration tests after basic tests pass
|
||||
needs: [test-python, test-frontend]
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: "latest"
|
||||
|
||||
- name: Install backend dependencies
|
||||
working-directory: apps/backend
|
||||
shell: bash
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install -r requirements.txt
|
||||
uv pip install -r ../../tests/requirements-test.txt
|
||||
|
||||
- name: Run platform-specific tests
|
||||
working-directory: apps/backend
|
||||
shell: bash
|
||||
env:
|
||||
PYTHONPATH: ${{ github.workspace }}/apps/backend
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
source .venv/Scripts/activate
|
||||
else
|
||||
source .venv/bin/activate
|
||||
fi
|
||||
pytest ../../tests/test_platform.py -v --tb=short
|
||||
|
||||
Reference in New Issue
Block a user