You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含工作区的Cargo Git依赖打补丁以实现离线托管

离线托管Cargo工作区Git依赖的正确姿势

问题场景

我最近在搭建Cargo包的离线安装方案,已经搞定了crates.io源的情况——只要在.cargo/config.toml里配置replace-with = "vendored-sources"就行。单包的Git依赖也没问题,比如pubgrub这类,步骤就是:

  • 把仓库下载成tar.gz包,解压到/vendor目录
  • 生成仅包含"package"校验和的.cargo-checksum.json文件
  • 在config里添加patch配置:
    [patch."https://github.com/astral-sh/pubgrub"]
    pubgrub = { path = "/vendor/pubgrub" }
    

但碰到多包工作区的Git依赖就卡壳了,比如reqwest-middleware仓库,里面包含reqwest-middleware、reqwest-retry等多个子包:

  • 直接patch工作区根目录,会报虚拟清单错误:

    found a virtual manifest at /vendor/reqwest-middleware/Cargo.toml instead of a package manifest

  • 把path指向子包目录,离线模式下又会触发Git拉取报错:

    Unable to update https://github.com/astral-sh/reqwest-middleware?rev=21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe#21ceec9a
    Caused by:
    can't checkout from 'https://github.com/astral-sh/reqwest-middleware': you are in the offline mode (--offline)

我自己试出了一种方法,但太啰嗦,还不能和crates.io的vendored源放在同一目录,否则会报虚拟包和源更新失败的错误:

[source.reqwest-middleware]
directory = "/vendor/reqwest-middleware"

[source.doesntmatter]
git = "https://github.com/astral-sh/reqwest-middleware"
rev = "21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe"
replace-with = "reqwest-middleware"

首选解决方案

对付这种工作区Git依赖,最靠谱的方法是给工作区里每个子包单独配置patch路径,同时保证工作区根目录有正确的.cargo-checksum.json文件。

具体步骤:

  1. 把整个工作区仓库下载解压到/vendor/reqwest-middleware目录
  2. 在工作区根目录生成.cargo-checksum.json——这个文件需要包含所有子包的校验和,最简单的方式是在线环境执行cargo vendor自动生成,也可以手动计算每个子包的校验和填入
  3. 在.cargo/config.toml中为每个子包添加patch配置:
    [patch."https://github.com/astral-sh/reqwest-middleware"]
    reqwest-middleware = { path = "/vendor/reqwest-middleware/reqwest-middleware" }
    reqwest-retry = { path = "/vendor/reqwest-middleware/reqwest-retry" }
    # 有其他子包就继续添加对应配置
    

为什么这个方案可行?

  • 每个子包单独指定路径,直接避开了虚拟清单的问题
  • 工作区根目录的校验和文件会告知Cargo该Git仓库的内容合法,离线模式下不会再尝试拉取远程仓库

简化替代方案

如果子包太多不想逐个配置,也可以用自定义源+replace-with的方式,但需要把工作区依赖和crates.io的vendored源分开存放:

  1. 单独创建目录存放工作区依赖,比如/vendor/git-repos/reqwest-middleware,crates.io的vendored源放在/vendor/crates-io
  2. 在.cargo/config.toml中配置:
    # crates.io的vendored源配置
    [source.crates-io]
    replace-with = "vendored-crates"
    
    [source.vendored-crates]
    directory = "/vendor/crates-io"
    
    # 工作区依赖的自定义源
    [source.reqwest-middleware-workspace]
    directory = "/vendor/git-repos/reqwest-middleware"
    
    [source.reqwest-middleware-git]
    git = "https://github.com/astral-sh/reqwest-middleware"
    rev = "21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe"
    replace-with = "reqwest-middleware-workspace"
    

这种方法不用逐个编写子包配置,但需要维护独立的目录结构,避免和crates.io源冲突。

内容的提问来源于stack exchange,提问作者Flamefire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:09:58