cargo-offline命令
cargo-offline是標(biāo)準(zhǔn)cargo命令的包裝器。其被用來,根據(jù)·距離cargo-offline命令執(zhí)行目錄最近的Cargo.toml文件是否被修改過,來給被包裝的cargo命令條件地增補(bǔ)--offline命令行參數(shù)(即,離線編譯)。形象地講,就是將cargo check條件地變形為cargo check --offline。
-
項(xiàng)目鏈接:https://github.com/stuartZhang/cargo-offline
-
包倉庫鏈接:https://crates.io/crates/cargo-offline
-
代碼也精彩,真不是簡單的代碼堆疊,而是有套路,和講套路的。
-
先點(diǎn)個(gè)
star -
再直接導(dǎo)航至:https://github1s.com/stuartZhang/cargo-offline
-
動機(jī)
最近一段時(shí)間,github.com訪問的穩(wěn)定性實(shí)在很差。但,執(zhí)行cargo命令總是要求
-
首先,同步crates.io-index索引清單。
-
然后,執(zhí)行目標(biāo)任務(wù)
于是,日常開發(fā)/編譯工作流就時(shí)常被阻塞于
warning: spurious network error (1 tries remaining): [35] SSL connect error (schannel: failed to receive handshake, SSL/TLS connection failed); class=Net (12) Caused by: Unable to update registry `crates-io` Caused by: failed to fetch `https://github.com/rust-lang/crates.io-index` Caused by: [35] SSL connect error (schannel: failed to receive handshake, SSL/TLS connection failed); class=Net (12)
的網(wǎng)絡(luò)錯誤上。這實(shí)在令人感覺挫敗!
另一方面,雖然“搬梯子”能夠緩解問題,但面對頻繁的cargo check/run指令執(zhí)行(特別是,莫名其妙出現(xiàn)的“全量索引同步”現(xiàn)象),其“按流量·計(jì)費(fèi)”的經(jīng)濟(jì)成本著實(shí)令人肉疼。
所以,我下定決心在業(yè)余時(shí)間搞一個(gè)【條件·離線·編譯】的命令行工具,來拯救自己于迷茫。
最理想的使用模型
-
僅首次編譯·或·在依賴項(xiàng)變更時(shí),
cargo命令才【連線】編譯與同步本地的crates.io-index索引清單 —— 有限且可控的“搬梯子”還是可以經(jīng)濟(jì)承受的。 -
在所有其它時(shí)候,
cargo命令皆【離線】編譯 —— 沒事少連線github.com。
工作原理
cargo-offline命令會
-
透傳所有命令行參數(shù)給底層的
cargo指令 -
尋找距離
cargo-offline執(zhí)行目錄最近的Cargo.toml文件,無論該配置文件-
是【工作區(qū)
workspace】配置文件 -
還是【工作區(qū)·成員
workspace.member】配置文件。
-
-
比較被找到的
Cargo.toml文件·是否·被修改過 —— 就是對比該文件的【最后·修改時(shí)間】屬性值是否發(fā)生了變化。 -
若
Cargo.toml文件的·最后修改時(shí)間·變化了,就給被透傳的參數(shù)列表額外添加--offline參數(shù)項(xiàng)。 -
于是,
cargo命令就會進(jìn)入【離線模式】編譯了。
Cargo.toml文件修改時(shí)間的保存位置
判斷Cargo.toml文件·是否·被修改過,關(guān)鍵需要:
-
緩存·在上一次編譯時(shí)·讀取的
Cargo.toml文件【修改時(shí)間】屬性值 -
再,使用【緩存·時(shí)間值】與當(dāng)前【文件修改時(shí)間】比大小
就將Cargo.toml文件【修改時(shí)間】保存于何處,cargo-offline程序提供了兩套備選方案:
-
直接保存到
Cargo.toml文件自身里,和作為***.metadata配置塊內(nèi)一個(gè)鍵值對。-
被
toml crate編輯過的Cargo.toml文件,它內(nèi)部 -
程序·會額外地依賴
cargo_toml crate。所以,編譯輸出的二進(jìn)制文件會更大那么一點(diǎn)點(diǎn)兒。 -
編譯指令·會額外地開啟【不穩(wěn)定
feature】file_set_times -
“配置塊”會被重新排序
-
“雙引號”會被替換為“單引號”。
-
不會在工程目錄下引入新文件了。
-
也不用修改
.gitignore文件添加例外規(guī)則了。 -
就【工作區(qū)】而言,保存配置塊是
[workspace.metadata] -
就【工作區(qū)·成員】和【普通工程】而言,保存配置塊是
[package.metadata] -
優(yōu)點(diǎn):
-
缺點(diǎn):
-
-
保存于獨(dú)立的
*.toml配置文件內(nèi)。-
需手工地向
.gitignore文件添加cargo-offline-config.toml文件名。 -
Cargo.toml文件可保持“無損”。 -
少一個(gè)程序依賴項(xiàng)
-
避免開啟【不穩(wěn)定
feature】 -
即,與
Cargo.toml文件同目錄的cargo-offline-config.toml文件。目前,此文件名是在代碼內(nèi)被硬編碼的。 -
優(yōu)點(diǎn):
-
缺點(diǎn):
-
值得一提的是,**Cargo.toml文件【修改時(shí)間】保存位置的選擇是【編譯時(shí)·決策】,而不是【運(yùn)行時(shí)·決策】。**即,
-
以
Cargo features作為編譯條件 -
根據(jù)不同的決策選擇
-
編譯輸出不一樣的二進(jìn)制行可執(zhí)行文件作為結(jié)果。
安裝
此命令行工具crate已經(jīng)被發(fā)布至crates.io包倉庫。所以,我就未對各主流平臺與架構(gòu)準(zhǔn)備·預(yù)編譯包(感謝偉大的包管理器!)。
-
選擇緩存
Cargo.toml文件【修改時(shí)間】至Cargo.toml [metadata]的同學(xué),執(zhí)行這條安裝指令:cargo install cargo-offline --features=cargo-metadata
-
選擇緩存
Cargo.toml文件【修改時(shí)間】至cargo-offline-config.toml獨(dú)立文件的同學(xué),執(zhí)行這條安裝指令:cargo install cargo-offline --features=toml-config
因?yàn)槲覜]有給Cargo Package設(shè)置default features,所以完全忽略--features=命令行參數(shù)會導(dǎo)致源碼編譯錯誤。惡作劇地,同時(shí)指定--features=cargo-metadata與--features=toml-config也會導(dǎo)致編譯失敗。
一旦被安裝成功之后,cargo-offline.exe可執(zhí)行文件就會
-
出現(xiàn)在
%CARGO_HOME%in目錄下 -
從
PATH環(huán)境變量劃定的搜索范圍,可見 -
可從命令行直接運(yùn)行
使用
cargo-offline命令的執(zhí)行也有兩種方式可供選擇:
-
作為獨(dú)立命令,執(zhí)行
cargo-offline。后隨和標(biāo)準(zhǔn)cargo命令相同的命令行參數(shù)(這些參數(shù)會被透傳給cargo指令的)。比如,cargo-offline check
-
作為
cargo指令的子命令,執(zhí)行cargo offline。比如,cargo offline check
cargo-offline的命令行參數(shù)與cargo完全相同,因?yàn)?code style="background:rgb(251,241,199);font-family:'Source Code Pro', 'Fira Code', Menlo, Monaco, Consolas, 'DejaVu Sans Mono', Inconsolata, 'Courier New', monospace;">cargo-offline僅只做了透傳處理。
源碼也精彩,歡迎來品鑒
不是語句的堆疊,而是講究了“套路”。被涉及到的【設(shè)計(jì)模式】包括但不限于:
-
【條件編譯】
plus【策略·設(shè)計(jì)模式】 —— 解決Cargo.toml文件【修改時(shí)間】保存位置的選擇問題。-
【策略·模式】大約對等于
OOP里的【控制反轉(zhuǎn)IoC】plus【依賴注入DI】的組合。在我的代碼,從IoC容器到DI注入項(xiàng)都是自寫的。 -
欲深入了解【策略·模式】的細(xì)節(jié)理論,我推薦文章淺聊Rust【策略·設(shè)計(jì)模式】Strategy / Policy design pattern —— 歡迎點(diǎn)贊、發(fā)評論與轉(zhuǎn)發(fā)分享。
-
-
Builder設(shè)計(jì)模式 —— 解決struct局部初始化的問題。-
其大約對等于
OOP里【工廠模式】。 -
但,親手給每個(gè)
struct編寫Builder,那不是傻嗎!多大的工作量呀!我的選擇是derive_builder。
-
-
Option / Result枚舉類的“拆/裝箱”配合器【Combinator模式】 —— 避免丑陋且有panic風(fēng)險(xiǎn)的.unwrap()“拆箱”操作。-
有那么一點(diǎn)兒
ramda鏈?zhǔn)胶瘮?shù)調(diào)用的感覺了。餒餒的【函數(shù)編程·范式】。
-
-
規(guī)則宏
macro-by-example—— 避免代碼重復(fù)。-
這是【結(jié)構(gòu)相同·但·類型不同】代碼塊復(fù)用的利器呀!
-
以【宏】的思維來復(fù)用代碼,得花費(fèi)一段時(shí)間來適應(yīng)。
-
關(guān)于·編譯
重要,十分重要:因?yàn)椤静环€(wěn)定feature】file_set_times在程序中被條件地開啟,所以該Cargo Package工程依賴的rustup工具鏈被鮮明地鎖定于nightly版本。若你git clone此工程至本地,請先安裝nightly版的rustc再編譯執(zhí)行之。否則,會報(bào)錯的。
另外,推薦使用VSCode編輯與編譯cargo-offline工程,因?yàn)槲乙呀?jīng)配置好了:
-
Ctrl + Shift + B直接·編譯+執(zhí)行。 -
在安裝了
CodeLLDB插件之后,F5就先編譯,再進(jìn)入斷點(diǎn)調(diào)試模式。
無論采用上面哪種方式編譯程序,VSCode都會彈出【下拉·選擇器】,要求選擇輸入【自定義cargo feature】。所以,請注意使用【上下箭頭】與【回車】鍵,響應(yīng)VSCode的選擇要求。
后續(xù)路圖
若今后給該·命令行工具·添加更多功能與配置選項(xiàng),我計(jì)劃上【GUI圖形界面】,考慮到我的win32與Gnome.GTK3編程經(jīng)歷與背景。
-
代碼
+關(guān)注
關(guān)注
30文章
4927瀏覽量
72501 -
編譯
+關(guān)注
關(guān)注
0文章
682瀏覽量
34869 -
Win32
+關(guān)注
關(guān)注
0文章
11瀏覽量
8318
原文標(biāo)題:命令
文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄

cargo-offline命令解讀
評論