diff --git a/README.md b/README.md index f850eb9..355b805 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ [![Maven](https://img.shields.io/badge/Maven-C71A36?logo=apachemaven&logoColor=white)](#maven-包管理加速) [![Gradle](https://img.shields.io/badge/Gradle-02303A?logo=gradle&logoColor=white)](#gradle-包管理加速) [![RubyGems](https://img.shields.io/badge/RubyGems-CC342D?logo=rubygems&logoColor=white)](#ruby-包管理加速) +[![CRAN](https://img.shields.io/badge/CRAN-276DC3?logo=r&logoColor=white)](#r-包管理加速) [![Go](https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white)](#go-模块加速) [![NuGet](https://img.shields.io/badge/NuGet-004880?logo=nuget&logoColor=white)](#nuget-包管理加速) [![Rust](https://img.shields.io/badge/Rust-000000?logo=rust&logoColor=white)](#rust-包管理加速) @@ -129,6 +130,7 @@ | Maven | `maven` | `https://repo1.maven.org/...` | `https://xget.xi-xu.me/maven/...` | | Gradle | `gradle` | `https://plugins.gradle.org/...` | `https://xget.xi-xu.me/gradle/...` | | RubyGems | `rubygems` | `https://rubygems.org/...` | `https://xget.xi-xu.me/rubygems/...` | +| CRAN | `cran` | `https://cran.r-project.org/...` | `https://xget.xi-xu.me/cran/...` | | Go 模块 | `golang` | `https://proxy.golang.org/...` | `https://xget.xi-xu.me/golang/...` | | NuGet | `nuget` | `https://api.nuget.org/...` | `https://xget.xi-xu.me/nuget/...` | | Rust Crates | `crates` | `https://crates.io/...` | `https://xget.xi-xu.me/crates/...` | @@ -305,6 +307,22 @@ https://rubygems.org/api/v1/gems/nokogiri.json https://xget.xi-xu.me/rubygems/api/v1/gems/nokogiri.json ``` +#### CRAN + +```url +# CRAN 包文件原始链接 +https://cran.r-project.org/src/contrib/ggplot2_3.4.4.tar.gz + +# 转换后(添加 cran 前缀) +https://xget.xi-xu.me/cran/src/contrib/ggplot2_3.4.4.tar.gz + +# CRAN 包元数据原始链接 +https://cran.r-project.org/web/packages/dplyr/DESCRIPTION + +# 转换后(添加 cran 前缀) +https://xget.xi-xu.me/cran/web/packages/dplyr/DESCRIPTION +``` + #### Go 模块 ```url @@ -880,6 +898,62 @@ bundle config mirror.https://rubygems.org https://xget.xi-xu.me/rubygems/ bundle install ``` +### R 包管理加速 + +#### 配置 R 使用 Xget CRAN 镜像 + +```r +# 在 R 中临时使用 Xget CRAN 镜像 +install.packages("ggplot2", repos = "https://xget.xi-xu.me/cran/") + +# 全局配置 CRAN 镜像 +options(repos = c(CRAN = "https://xget.xi-xu.me/cran/")) + +# 验证配置 +getOption("repos") +``` + +#### 在 .Rprofile 中配置 + +```r +# 在用户主目录的 .Rprofile 文件中配置全局镜像 +options(repos = c( + CRAN = "https://xget.xi-xu.me/cran/", + BioCsoft = "https://bioconductor.org/packages/release/bioc", + BioCann = "https://bioconductor.org/packages/release/data/annotation", + BioCexp = "https://bioconductor.org/packages/release/data/experiment" +)) + +# 设置下载方法 +options(download.file.method = "libcurl") +``` + +#### 在项目中使用 + +```r +# 在项目的 renv.lock 或脚本中指定镜像 +renv::init() +renv::settings$repos.override(c(CRAN = "https://xget.xi-xu.me/cran/")) + +# 安装包 +install.packages(c("dplyr", "ggplot2", "tidyr")) + +# 或使用 pak 包管理器 +pak::pkg_install("tidyverse", repos = "https://xget.xi-xu.me/cran/") +``` + +```bash +# 在命令行中使用 R 脚本安装包 +Rscript -e "options(repos = c(CRAN = 'https://xget.xi-xu.me/cran/')); install.packages('ggplot2')" + +# 批量安装包 +Rscript -e " +options(repos = c(CRAN = 'https://xget.xi-xu.me/cran/')) +packages <- c('dplyr', 'ggplot2', 'tidyr', 'readr') +install.packages(packages) +" +``` + ### Go 模块加速 #### 配置 Go 使用 Xget 代理 diff --git a/src/config/platforms.js b/src/config/platforms.js index d1073da..5978310 100644 --- a/src/config/platforms.js +++ b/src/config/platforms.js @@ -17,8 +17,10 @@ export const PLATFORMS = { maven: 'https://repo1.maven.org', gradle: 'https://plugins.gradle.org', rubygems: 'https://rubygems.org', + cran: 'https://cran.r-project.org', golang: 'https://proxy.golang.org', nuget: 'https://api.nuget.org', + crates: 'https://crates.io', packagist: 'https://repo.packagist.org', debian: 'https://deb.debian.org', ubuntu: 'https://archive.ubuntu.com', @@ -26,7 +28,6 @@ export const PLATFORMS = { rocky: 'https://download.rockylinux.org', arch: 'https://geo.mirror.pkgbuild.com', arxiv: 'https://arxiv.org', - crates: 'https://crates.io', // Container Registries 'cr-quay': 'https://quay.io', diff --git a/test/cran.test.js b/test/cran.test.js new file mode 100644 index 0000000..b2e3b1a --- /dev/null +++ b/test/cran.test.js @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; +import { PLATFORMS, transformPath } from '../src/config/platforms.js'; + +describe('CRAN Platform Configuration', () => { + it('should have CRAN platform configured', () => { + expect(PLATFORMS.cran).toBe('https://cran.r-project.org'); + }); + + it('should transform CRAN paths correctly', () => { + const testCases = [ + { + input: '/cran/src/contrib/ggplot2_3.4.4.tar.gz', + expected: '/src/contrib/ggplot2_3.4.4.tar.gz', + description: 'package source file' + }, + { + input: '/cran/web/packages/dplyr/DESCRIPTION', + expected: '/web/packages/dplyr/DESCRIPTION', + description: 'package description file' + }, + { + input: '/cran/bin/windows/contrib/4.3/ggplot2_3.4.4.zip', + expected: '/bin/windows/contrib/4.3/ggplot2_3.4.4.zip', + description: 'Windows binary package' + }, + { + input: '/cran/bin/macosx/big-sur-arm64/contrib/4.3/ggplot2_3.4.4.tgz', + expected: '/bin/macosx/big-sur-arm64/contrib/4.3/ggplot2_3.4.4.tgz', + description: 'macOS binary package' + }, + { + input: '/cran/web/packages/packages.rds', + expected: '/web/packages/packages.rds', + description: 'package index file' + } + ]; + + testCases.forEach(({ input, expected, description }) => { + const result = transformPath(input, 'cran'); + expect(result).toBe(expected, `Failed for ${description}: ${input}`); + }); + }); + + it('should handle root path correctly', () => { + const result = transformPath('/cran/', 'cran'); + expect(result).toBe('/'); + }); + + it('should handle paths without platform prefix', () => { + const result = transformPath('/src/contrib/ggplot2_3.4.4.tar.gz', 'cran'); + expect(result).toBe('/src/contrib/ggplot2_3.4.4.tar.gz'); + }); +});