diff --git a/config/pkg/target/rust.yml b/config/pkg/target/rust.yml new file mode 100644 index 00000000..f2e10738 --- /dev/null +++ b/config/pkg/target/rust.yml @@ -0,0 +1,6 @@ +rust: + type: target + artifact: + binary: custom + path: + - '{pkg_root_path}/rust/bin' diff --git a/src/Package/Artifact/rust.php b/src/Package/Artifact/rust.php new file mode 100644 index 00000000..e5c9f525 --- /dev/null +++ b/src/Package/Artifact/rust.php @@ -0,0 +1,85 @@ +executeCurl('https://static.rust-lang.org/dist/channel-rust-stable.toml', retries: $downloader->getRetry()); + // parse toml by regex since we want to avoid adding a toml parser dependency just for this + $cnt = preg_match_all('/^version = "([^"]+)"$/m', $toml_config ?: '', $matches); + if (!$cnt) { + throw new DownloaderException('Failed to parse Rust version from channel config'); + } + $versions = $matches[1]; + // strip version num \d.\d.\d (some version number is like "x.x.x (abcdefg 1970-01-01)" + $versions = array_filter(array_map(fn ($v) => preg_match('/^(\d+\.\d+\.\d+)/', $v, $m) ? $m[1] : null, $versions)); + usort($versions, 'version_compare'); + $latest_version = end($versions); + if (!$latest_version) { + throw new DownloaderException('Could not determine latest Rust version'); + } + + // merge download link + $download_url = "https://static.rust-lang.org/dist/rust-{$latest_version}-{$arch}-unknown-linux-{$distro}.tar.xz"; + $path = DOWNLOAD_PATH . DIRECTORY_SEPARATOR . basename($download_url); + default_shell()->executeCurlDownload($download_url, $path, retries: $downloader->getRetry()); + return DownloadResult::archive(basename($path), ['url' => $download_url, 'version' => $latest_version], extract: PKG_ROOT_PATH . '/rust-install', verified: false, version: $latest_version); + } + + #[CustomBinaryCheckUpdate('rust', [ + 'linux-x86_64', + 'linux-aarch64', + ])] + public function checkUpdateBinary(?string $old_version, ArtifactDownloader $downloader): CheckUpdateResult + { + $toml_config = default_shell()->executeCurl('https://static.rust-lang.org/dist/channel-rust-stable.toml', retries: $downloader->getRetry()); + $cnt = preg_match_all('/^version = "([^"]+)"$/m', $toml_config ?: '', $matches); + if (!$cnt) { + throw new DownloaderException('Failed to parse Rust version from channel config'); + } + $versions = array_filter(array_map(fn ($v) => preg_match('/^(\d+\.\d+\.\d+)/', $v, $m) ? $m[1] : null, $matches[1])); + usort($versions, 'version_compare'); + $latest_version = end($versions); + if (!$latest_version) { + throw new DownloaderException('Could not determine latest Rust version'); + } + return new CheckUpdateResult( + old: $old_version, + new: $latest_version, + needUpdate: $old_version === null || $latest_version !== $old_version, + ); + } + + #[AfterBinaryExtract('rust', [ + 'linux-x86_64', + 'linux-aarch64', + ])] + public function postExtractRust(string $target_path): void + { + $prefix = PKG_ROOT_PATH . '/rust'; + shell()->exec("cd {$target_path} && ./install.sh --prefix={$prefix}"); + } +}