diff --git a/config/pkg/target/go-win.yml b/config/pkg/target/go-win.yml new file mode 100644 index 00000000..46c13f5f --- /dev/null +++ b/config/pkg/target/go-win.yml @@ -0,0 +1,10 @@ +go-win: + type: target + artifact: + binary: custom + env: + GOROOT: '{pkg_root_path}/go-win' + GOBIN: '{pkg_root_path}/go-win/bin' + GOPATH: '{pkg_root_path}/go-win/go' + path@windows: + - '{pkg_root_path}/go-win/bin' diff --git a/src/Package/Artifact/go_win.php b/src/Package/Artifact/go_win.php new file mode 100644 index 00000000..44cf61b9 --- /dev/null +++ b/src/Package/Artifact/go_win.php @@ -0,0 +1,85 @@ +executeCurl('https://go.dev/VERSION?m=text') ?: ''); + if ($version === '') { + throw new DownloaderException('Failed to get latest Go version from https://go.dev/VERSION?m=text'); + } + + // find SHA256 hash from download page + $page = default_shell()->executeCurl('https://go.dev/dl/'); + if ($page === '' || $page === false) { + throw new DownloaderException('Failed to get Go download page from https://go.dev/dl/'); + } + + $version_regex = str_replace('.', '\.', $version); + $pattern = "/class=\"download\" href=\"\\/dl\\/{$version_regex}\\.windows-amd64\\.zip\">.*?([a-f0-9]{64})<\\/tt>/s"; + if (preg_match($pattern, $page, $matches)) { + $hash = $matches[1]; + } else { + throw new DownloaderException("Failed to find download hash for Go {$version} windows-amd64"); + } + + $url = "https://go.dev/dl/{$version}.windows-amd64.zip"; + $path = DOWNLOAD_PATH . DIRECTORY_SEPARATOR . "{$version}.windows-amd64.zip"; + default_shell()->executeCurlDownload($url, $path, retries: $downloader->getRetry()); + + // verify hash + $file_hash = hash_file('sha256', $path); + if ($file_hash !== $hash) { + throw new DownloaderException("Hash mismatch for downloaded go-win binary. Expected {$hash}, got {$file_hash}"); + } + + return DownloadResult::archive(basename($path), ['url' => $url, 'version' => $version], extract: "{$pkgroot}/go-win", verified: true, version: $version); + } + + #[CustomBinaryCheckUpdate('go-win', ['windows-x86_64'])] + public function checkUpdateBinary(?string $old_version): CheckUpdateResult + { + [$version] = explode("\n", default_shell()->executeCurl('https://go.dev/VERSION?m=text') ?: ''); + if ($version === '') { + throw new DownloaderException('Failed to get latest Go version from https://go.dev/VERSION?m=text'); + } + return new CheckUpdateResult( + old: $old_version, + new: $version, + needUpdate: $old_version === null || $version !== $old_version, + ); + } + + #[AfterBinaryExtract('go-win', ['windows-x86_64'])] + public function afterExtract(string $target_path): void + { + if (!file_exists("{$target_path}\\bin\\go.exe")) { + throw new DownloaderException("Go installation appears incomplete: go.exe not found at {$target_path}\\bin\\go.exe"); + } + + GlobalEnvManager::putenv("GOROOT={$target_path}"); + GlobalEnvManager::putenv("GOPATH={$target_path}\\gopath"); + GlobalEnvManager::putenv("GOCACHE={$target_path}\\gocache"); + GlobalEnvManager::putenv("GOMODCACHE={$target_path}\\gopath\\pkg\\mod"); + GlobalEnvManager::addPathIfNotExists("{$target_path}\\bin"); + } +}