| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- @echo off
- REM Opencode VSCode Extension Build Script for Windows
- REM Handles the complete build process for the Opencode VSCode extension.
- REM Supports building two variants:
- REM - Standard: bundles opencode binaries (default)
- REM - GUI-only: no binaries, uses system opencode, embeds webgui-dist
- REM
- REM By default both variants are built. Use --gui-only or --standard-only to
- REM build a single variant.
- setlocal enabledelayedexpansion
- REM Resolve key directories
- set "SCRIPT_DIR=%~dp0"
- set "ROOT_DIR=%SCRIPT_DIR%..\.."
- for %%I in ("%ROOT_DIR%") do set "ROOT_DIR=%%~fI"
- set "PLUGIN_DIR=%ROOT_DIR%\hosts\vscode-plugin"
- set "WEBGUI_DIR=%ROOT_DIR%\packages\opencode\webgui"
- set "WEBGUI_DIST=%ROOT_DIR%\packages\opencode\webgui-dist"
- if not exist "%PLUGIN_DIR%\package.json" (
- echo [ERROR] package.json not found. Please run this script from the repository root.
- exit /b 1
- )
- echo Opencode VSCode Extension Build Script
- echo Plugin directory: %PLUGIN_DIR%
- echo Root directory: %ROOT_DIR%
- set "BUILD_TYPE=development"
- set "SKIP_BINARIES=false"
- set "SKIP_TESTS=false"
- set "PACKAGE_ONLY=false"
- set "BUILD_STANDARD=true"
- set "BUILD_GUI_ONLY=true"
- :parse_args
- if "%~1"=="" goto args_done
- if "%~1"=="--production" (
- set "BUILD_TYPE=production"
- shift
- goto parse_args
- )
- if "%~1"=="--skip-binaries" (
- set "SKIP_BINARIES=true"
- shift
- goto parse_args
- )
- if "%~1"=="--skip-tests" (
- set "SKIP_TESTS=true"
- shift
- goto parse_args
- )
- if "%~1"=="--package-only" (
- set "PACKAGE_ONLY=true"
- shift
- goto parse_args
- )
- if "%~1"=="--gui-only" (
- set "BUILD_STANDARD=false"
- set "BUILD_GUI_ONLY=true"
- shift
- goto parse_args
- )
- if "%~1"=="--standard-only" (
- set "BUILD_STANDARD=true"
- set "BUILD_GUI_ONLY=false"
- shift
- goto parse_args
- )
- if "%~1"=="--help" (
- echo Usage: %0 [OPTIONS]
- echo --production Build for production (default: development)
- echo --skip-binaries Skip building backend binaries
- echo --skip-tests Skip running tests
- echo --package-only Only create the .vsix package (skip compilation)
- echo --gui-only Build only the gui-only variant (no binaries)
- echo --standard-only Build only the standard variant (with binaries)
- echo --help Show this help message
- exit /b 0
- )
- echo [ERROR] Unknown option: %~1
- exit /b 1
- :args_done
- echo [INFO] Building VSCode extension in %BUILD_TYPE% mode
- if "%BUILD_STANDARD%"=="true" echo [INFO] Variant: standard (with binaries)
- if "%BUILD_GUI_ONLY%"=="true" echo [INFO] Variant: gui-only (system opencode)
- cd /d "%PLUGIN_DIR%"
- REM --- Shared preparation (compile once, package per-variant) ---
- if "%PACKAGE_ONLY%"=="false" (
- echo [INFO] Cleaning previous build artifacts...
- if not exist "node_modules" (
- echo [WARN] Dependencies not installed; skipping script clean and removing artifacts manually.
- if exist "out" rmdir /s /q "out"
- del /f /q *.vsix 2>nul
- ) else (
- call pnpm run clean 2>nul
- if errorlevel 1 (
- echo [WARN] Clean command failed, applying fallback removal...
- if exist "out" rmdir /s /q "out"
- del /f /q *.vsix 2>nul
- )
- )
- )
- if "%PACKAGE_ONLY%"=="false" (
- echo [INFO] Installing dependencies...
- where pnpm >nul 2>&1
- if not errorlevel 1 (
- call pnpm install
- ) else (
- where npm >nul 2>&1
- if errorlevel 1 (
- echo [ERROR] Neither pnpm nor npm found. Please install a package manager.
- exit /b 1
- )
- call npm install
- )
- )
- if "%SKIP_BINARIES%"=="false" (
- if "%PACKAGE_ONLY%"=="false" (
- if "%BUILD_STANDARD%"=="true" (
- echo [INFO] Building backend binaries...
- cd /d "%ROOT_DIR%"
- if exist "hosts\scripts\build_opencode.bat" (
- call hosts\scripts\build_opencode.bat
- ) else (
- echo [ERROR] Backend build script not found at hosts\scripts\build_opencode.bat
- exit /b 1
- )
- cd /d "%PLUGIN_DIR%"
- )
- )
- )
- if "%PACKAGE_ONLY%"=="false" (
- echo [INFO] Compiling TypeScript...
- if "%BUILD_TYPE%"=="production" (
- call pnpm run compile:production
- ) else (
- call pnpm run compile
- )
- )
- if "%PACKAGE_ONLY%"=="false" (
- echo [INFO] Running linter...
- call pnpm run lint
- if errorlevel 1 echo [WARN] Linting failed, continuing with build...
- )
- if "%SKIP_TESTS%"=="false" (
- if "%PACKAGE_ONLY%"=="false" (
- echo [INFO] Running tests...
- call pnpm run test
- if errorlevel 1 echo [WARN] Tests failed, continuing with build...
- )
- )
- REM --- Resolve vsce command ---
- set "VSCE_CMD=vsce"
- where vsce >nul 2>&1
- if errorlevel 1 (
- where npx >nul 2>&1
- if not errorlevel 1 (
- set "VSCE_CMD=npx -y @vscode/vsce"
- ) else (
- echo [WARN] vsce not found and npx unavailable; attempting global install via npm
- call npm install -g @vscode/vsce
- )
- )
- REM Generate timestamp
- for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (
- for /f "tokens=1-2 delims=/" %%c in ("%%a") do (
- set "MONTH=%%c"
- set "DAY=%%d"
- )
- set "YEAR=%%b"
- )
- for /f "tokens=1-2 delims=: " %%a in ('time /t') do (
- set "HOUR=%%a"
- set "MINUTE=%%b"
- )
- set "TIMESTAMP=%YEAR%%MONTH%%DAY%-%HOUR%%MINUTE%"
- REM --- Build helper: package a single variant ---
- if "%BUILD_STANDARD%"=="true" (
- call :build_variant_standard
- if errorlevel 1 exit /b 1
- )
- if "%BUILD_GUI_ONLY%"=="true" (
- call :build_variant_gui_only
- if errorlevel 1 exit /b 1
- )
- echo [INFO] Build completed successfully!
- echo [INFO] Extension packages created in: %PLUGIN_DIR%
- echo Packages created:
- for %%F in ("%PLUGIN_DIR%\*.vsix") do echo %%~nxF
- endlocal
- exit /b 0
- REM --- Build variant: standard ---
- :build_variant_standard
- echo [INFO] === Packaging STANDARD variant ===
- cd /d "%PLUGIN_DIR%"
- REM Check for required binaries
- echo [INFO] Checking for required binaries...
- set "MISSING_BINARIES=false"
- if not exist "resources\bin\windows\amd64\opencode.exe" (
- echo [WARN] Missing binary: resources\bin\windows\amd64\opencode.exe
- set "MISSING_BINARIES=true"
- )
- if not exist "resources\bin\macos\amd64\opencode" (
- echo [WARN] Missing binary: resources\bin\macos\amd64\opencode
- set "MISSING_BINARIES=true"
- )
- if not exist "resources\bin\macos\arm64\opencode" (
- echo [WARN] Missing binary: resources\bin\macos\arm64\opencode
- set "MISSING_BINARIES=true"
- )
- if not exist "resources\bin\linux\amd64\opencode" (
- echo [WARN] Missing binary: resources\bin\linux\amd64\opencode
- set "MISSING_BINARIES=true"
- )
- if not exist "resources\bin\linux\arm64\opencode" (
- echo [WARN] Missing binary: resources\bin\linux\arm64\opencode
- set "MISSING_BINARIES=true"
- )
- if "%MISSING_BINARIES%"=="true" (
- echo [WARN] Some binaries are missing. The extension may not work on all platforms.
- echo [WARN] Run 'hosts\scripts\build_opencode.bat' from the repository root to build all binaries.
- )
- REM Package with original package.json and .vscodeignore
- if "%BUILD_TYPE%"=="production" (
- call %VSCE_CMD% package --no-dependencies --out "opencode-vscode-%TIMESTAMP%.vsix"
- ) else (
- call %VSCE_CMD% package --pre-release --no-dependencies --out "opencode-vscode-dev-%TIMESTAMP%.vsix"
- )
- if errorlevel 1 exit /b 1
- echo [INFO] Standard variant packaged successfully
- exit /b 0
- REM --- Build variant: gui-only ---
- :build_variant_gui_only
- echo [INFO] === Packaging GUI-ONLY variant ===
- cd /d "%PLUGIN_DIR%"
- REM Always rebuild webgui to pick up source changes
- REM The monorepo uses bun workspaces a deps are already installed at root level
- echo [INFO] Building webgui...
- cd /d "%WEBGUI_DIR%"
- where bun >nul 2>&1
- if not errorlevel 1 (
- call bun run build
- ) else (
- call npm run build
- )
- cd /d "%PLUGIN_DIR%"
- if not exist "%WEBGUI_DIST%" (
- echo [ERROR] webgui-dist not found at %WEBGUI_DIST% after build
- exit /b 1
- )
- REM Copy webgui-dist into plugin resources for embedding
- echo [INFO] Embedding webgui-dist into plugin resources...
- if exist "resources\webgui-app" rmdir /s /q "resources\webgui-app"
- xcopy /s /e /i "%WEBGUI_DIST%" "resources\webgui-app\" >nul
- REM Move binaries completely outside the plugin tree so vsce cannot bundle them
- set "BIN_STASH=%TEMP%\opencode_bin_stash_%RANDOM%"
- if exist "resources\bin" (
- mkdir "%BIN_STASH%"
- move "resources\bin" "%BIN_STASH%\bin" >nul
- )
- REM Temporarily swap package.json with gui-only overrides and .vscodeignore
- copy "%PLUGIN_DIR%\package.json" "%PLUGIN_DIR%\package.json.bak" >nul
- copy "%PLUGIN_DIR%\.vscodeignore" "%PLUGIN_DIR%\.vscodeignore.bak" >nul
- REM Deep-merge gui-only overrides into package.json using PowerShell's built-in JSON support
- powershell -NoProfile -Command "$b=Get-Content 'package.json'|ConvertFrom-Json;$o=Get-Content 'package.gui-only.json'|ConvertFrom-Json;function m($t,$s){foreach($p in $s.PSObject.Properties){$v=$p.Value;if($v-is[array]-and$t.($p.Name)-is[array]){$a=$t.($p.Name);for($i=0;$i-lt$v.Count;$i++){if($i-lt$a.Count-and$v[$i]-is[pscustomobject]){m $a[$i] $v[$i]}else{$a[$i]=$v[$i]}}}elseif($v-is[pscustomobject]-and$t.($p.Name)-is[pscustomobject]){m $t.($p.Name) $v}else{$t|Add-Member -MemberType NoteProperty -Name $p.Name -Value $v -Force}}};m $b $o;$b|ConvertTo-Json -Depth 100|Set-Content 'package.json'"
- if errorlevel 1 (
- echo [ERROR] Failed to merge gui-only package.json overrides
- call :gui_only_cleanup
- exit /b 1
- )
- REM Swap .vscodeignore
- copy "%PLUGIN_DIR%\.vscodeignore.gui-only" "%PLUGIN_DIR%\.vscodeignore" >nul
- REM Package gui-only variant
- if "%BUILD_TYPE%"=="production" (
- call %VSCE_CMD% package --no-dependencies --out "opencode-vscode-gui-only-%TIMESTAMP%.vsix"
- ) else (
- call %VSCE_CMD% package --pre-release --no-dependencies --out "opencode-vscode-gui-only-dev-%TIMESTAMP%.vsix"
- )
- set "PACKAGE_RESULT=%ERRORLEVEL%"
- REM Restore originals
- call :gui_only_cleanup
- if "%PACKAGE_RESULT%"=="1" exit /b 1
- echo [INFO] GUI-only variant packaged successfully
- exit /b 0
- REM --- Cleanup helper for gui-only ---
- :gui_only_cleanup
- cd /d "%PLUGIN_DIR%"
- if exist "package.json.bak" (
- move /y "package.json.bak" "package.json" >nul
- )
- if exist ".vscodeignore.bak" (
- move /y ".vscodeignore.bak" ".vscodeignore" >nul
- )
- if exist "%BIN_STASH%\bin" (
- if exist "resources\bin" rmdir /s /q "resources\bin"
- move "%BIN_STASH%\bin" "resources\bin" >nul
- )
- if exist "%BIN_STASH%" rmdir /s /q "%BIN_STASH%"
- if exist "resources\webgui-app" rmdir /s /q "resources\webgui-app"
- exit /b 0
|