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
-
代碼也精彩,真不是簡(jiǎn)單的代碼堆疊,而是有套路,和講套路的。
-
先點(diǎn)個(gè)
star
-
再直接導(dǎo)航至:https://github1s.com/stuartZhang/cargo-offline
-
動(dòng)機(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ò)錯(cuò)誤上。這實(shí)在令人感覺挫??!
另一方面,雖然“搬梯子”能夠緩解問題,但面對(duì)頻繁的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
命令會(huì)
-
透?jìng)魉忻钚袇?shù)給底層的
cargo
指令 -
尋找距離
cargo-offline
執(zhí)行目錄最近的Cargo.toml
文件,無論該配置文件-
是【工作區(qū)
workspace
】配置文件 -
還是【工作區(qū)·成員
workspace.member
】配置文件。
-
-
比較被找到的
Cargo.toml
文件·是否·被修改過 —— 就是對(duì)比該文件的【最后·修改時(shí)間】屬性值是否發(fā)生了變化。 -
若
Cargo.toml
文件的·最后修改時(shí)間·變化了,就給被透?jìng)鞯膮?shù)列表額外添加--offline
參數(shù)項(xiàng)。 -
于是,
cargo
命令就會(huì)進(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è)鍵值對(duì)。-
被
toml crate
編輯過的Cargo.toml
文件,它內(nèi)部 -
程序·會(huì)額外地依賴
cargo_toml crate
。所以,編譯輸出的二進(jìn)制文件會(huì)更大那么一點(diǎn)點(diǎn)兒。 -
編譯指令·會(huì)額外地開啟【不穩(wěn)定
feature
】file_set_times
-
“配置塊”會(huì)被重新排序
-
“雙引號(hào)”會(huì)被替換為“單引號(hào)”。
-
不會(huì)在工程目錄下引入新文件了。
-
也不用修改
.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包倉庫。所以,我就未對(duì)各主流平臺(tái)與架構(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ù)會(huì)導(dǎo)致源碼編譯錯(cuò)誤。惡作劇地,同時(shí)指定--features=cargo-metadata
與--features=toml-config
也會(huì)導(dǎo)致編譯失敗。
一旦被安裝成功之后,cargo-offline.exe
可執(zhí)行文件就會(huì)
-
出現(xiàn)在
%CARGO_HOME%in
目錄下 -
從
PATH
環(huán)境變量劃定的搜索范圍,可見 -
可從命令行直接運(yùn)行
使用
cargo-offline
命令的執(zhí)行也有兩種方式可供選擇:
-
作為獨(dú)立命令,執(zhí)行
cargo-offline
。后隨和標(biāo)準(zhǔn)cargo
命令相同的命令行參數(shù)(這些參數(shù)會(huì)被透?jìng)鹘ocargo
指令的)。比如,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僅只做了透?jìng)魈幚怼?/p>
源碼也精彩,歡迎來品鑒
不是語句的堆疊,而是講究了“套路”。被涉及到的【設(shè)計(jì)模式】包括但不限于:
-
【條件編譯】
plus
【策略·設(shè)計(jì)模式】 —— 解決Cargo.toml
文件【修改時(shí)間】保存位置的選擇問題。-
【策略·模式】大約對(duì)等于
OOP
里的【控制反轉(zhuǎn)IoC
】plus
【依賴注入DI
】的組合。在我的代碼,從IoC
容器到DI
注入項(xiàng)都是自寫的。 -
欲深入了解【策略·模式】的細(xì)節(jié)理論,我推薦文章淺聊Rust【策略·設(shè)計(jì)模式】Strategy / Policy design pattern —— 歡迎點(diǎn)贊、發(fā)評(píng)論與轉(zhuǎn)發(fā)分享。
-
-
Builder
設(shè)計(jì)模式 —— 解決struct
局部初始化的問題。-
其大約對(duì)等于
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
此工程至本地,請(qǐng)先安裝nightly
版的rustc
再編譯執(zhí)行之。否則,會(huì)報(bào)錯(cuò)的。
另外,推薦使用VSCode
編輯與編譯cargo-offline
工程,因?yàn)槲乙呀?jīng)配置好了:
-
Ctrl + Shift + B
直接·編譯+
執(zhí)行。 -
在安裝了
CodeLLDB
插件之后,F5
就先編譯,再進(jìn)入斷點(diǎn)調(diào)試模式。
無論采用上面哪種方式編譯程序,VSCode
都會(huì)彈出【下拉·選擇器】,要求選擇輸入【自定義cargo feature
】。所以,請(qǐng)注意使用【上下箭頭】與【回車】鍵,響應(yīng)VSCode
的選擇要求。
后續(xù)路圖
若今后給該·命令行工具·添加更多功能與配置選項(xiàng),我計(jì)劃上【GUI
圖形界面】,考慮到我的win32
與Gnome.GTK3
編程經(jīng)歷與背景。
-
代碼
+關(guān)注
關(guān)注
30文章
4723瀏覽量
68237 -
編譯
+關(guān)注
關(guān)注
0文章
649瀏覽量
32775 -
Win32
+關(guān)注
關(guān)注
0文章
11瀏覽量
8105
原文標(biāo)題:命令
文章出處:【微信號(hào):Rust語言中文社區(qū),微信公眾號(hào):Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論