
開發(fā)工具CLI配置管理【免費(fèi)下載鏈接】chezmoiManage your dotfiles across multiple diverse machines, securely.項(xiàng)目地址https://gitcode.com/gh_mirrors/ch/chezmoi點(diǎn)擊查看免費(fèi)下載導(dǎo)讀在真實(shí)的 dotfiles 管理場景中我們經(jīng)常需要把并不屬于自己源碼狀態(tài)的第三方內(nèi)容納入管理——例如 Oh My Zsh 及其插件、vim 插件、plug.vim這類單文件工具乃至某個(gè)二進(jìn)制發(fā)行包。由于這些內(nèi)容不是 chezmoi 的源碼狀態(tài)格式git submodule 無法直接勝任。本篇指南以 chezmoi 的.chezmoiexternal.$FORMAT機(jī)制為核心完整講解file、archive、archive-file、git-repo四種外部類型的使用方法、緩存與刷新機(jī)制、過濾與校驗(yàn)字段并結(jié)合倉庫源碼說明底層實(shí)現(xiàn)幫助你安全、高效地把外部內(nèi)容納入統(tǒng)一管理。一、認(rèn)識(shí).chezmoiexternal.$FORMATchezmoi 的外部引入入口只要在源碼狀態(tài)默認(rèn)~/.local/share/chezmoi或由.chezmoiroot指定的目錄中的任何位置放置一個(gè)名為.chezmoiexternal.$FORMAT的文件$FORMAT為 chezmoi 支持的配置格式之一如toml、yaml、json詳見 配置格式說明它就會(huì)被解釋為一組外部文件和歸檔的清單chezmoi 會(huì)把它們當(dāng)作源碼狀態(tài)的一部分來包含參考.chezmoiexternal.$FORMAT參考手冊。幾個(gè)關(guān)鍵特性支持模板.chezmoiexternal.$FORMAT無論是否有.tmpl后綴都會(huì)作為模板解釋因此可以在不同機(jī)器上引入不同的外部內(nèi)容。受忽略規(guī)則約束如果該文件位于.chezmoiignore列出的忽略目錄中則其中所有條目都會(huì)被忽略。按目標(biāo)名索引條目以相對于該文件所在目錄的目標(biāo)路徑為鍵必須包含type字段以及url和/或urls字段若條目的父目錄在源碼狀態(tài)中不存在chezmoi 會(huì)自動(dòng)創(chuàng)建為普通目錄。從源碼結(jié)構(gòu)看chezmoi 在 internal/chezmoi/sourcestate.go 中定義了External結(jié)構(gòu)體type的取值集合定義在 internal/chezmoi/sourcestate.goconst ( ExternalTypeArchive ExternalType archive ExternalTypeArchiveFile ExternalType archive-file ExternalTypeFile ExternalType file ExternalTypeGitRepo ExternalType git-repo )條目字段一覽字段類型默認(rèn)值說明typestring無外部類型file、archive、archive-file、git-repodecompressstring無文件解壓方式encryptedboolfalse外部內(nèi)容是否加密exactboolfalse為歸檔中的目錄添加exact_屬性exclude[]string無從歸檔中排除的模式列表executableboolfalse為文件添加executable_屬性privateboolfalse為文件或目錄添加private_屬性readonlyboolfalse為文件添加readonly_屬性formatstring自動(dòng)探測歸檔格式pathstring無歸檔中要提取的文件路徑include[]string無從歸檔中包含的模式列表refreshPeriodduration0刷新周期0 表示永不刷新stripComponentsint0從歸檔成員路徑中剝離的前導(dǎo)目錄組件數(shù)urlstring無下載 URLurls[]string無按順序嘗試的備用 URL 列表checksum.sha256string無期望的數(shù)據(jù) SHA256 校驗(yàn)和checksum.sha384string無期望的數(shù)據(jù) SHA384 校驗(yàn)和checksum.sha512string無期望的數(shù)據(jù) SHA512 校驗(yàn)和checksum.sizeint無期望的數(shù)據(jù)大小clone.args[]string無git clone的額外參數(shù)filter.commandstring無內(nèi)容過濾命令filter.args[]string無過濾命令的額外參數(shù)pull.args[]string無git pull的額外參數(shù)archive.extractAppleDoubleboolfalse為true時(shí)提取 AppleDouble 文件targetPathstring無目標(biāo)路徑覆蓋條目鍵url必須是https://、http://或file://協(xié)議若指定了urls則按順序嘗試使用第一個(gè)成功的 URL。若設(shè)置了任意校驗(yàn)和字段chezmoi 會(huì)校驗(yàn)下載數(shù)據(jù)。二、從 URL 包含子目錄以 Oh My Zsh 為例git submodule 之所以行不通是因?yàn)?chezmoi 的源碼狀態(tài)有自己的格式而 Oh My Zsh 等第三方項(xiàng)目并非這種格式。.chezmoiexternal.$FORMAT正是為這種從外部源導(dǎo)入的場景設(shè)計(jì)的。例如要把 Oh My Zsh、zsh-syntax-highlighting 插件和 powerlevel10k 主題一并納入管理在~/.local/share/chezmoi/.chezmoiexternal.toml中寫入[.oh-my-zsh] type archive url https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz exact true stripComponents 1 refreshPeriod 168h [.oh-my-zsh/custom/plugins/zsh-syntax-highlighting] type archive url https://github.com/zsh-users/zsh-syntax-highlighting/archive/master.tar.gz exact true stripComponents 1 refreshPeriod 168h [.oh-my-zsh/custom/themes/powerlevel10k] type archive url https://github.com/romkatv/powerlevel10k/archive/v1.15.0.tar.gz exact true stripComponents 1然后應(yīng)用變更c(diǎn)hezmoi apply關(guān)鍵字段解讀type archive目標(biāo)是一個(gè)目錄其內(nèi)容來自u(píng)rl指向的歸檔。exact true目錄及其所有子目錄被當(dāng)作精確目錄處理chezmoi apply時(shí)會(huì)刪除歸檔中不存在的條目保證目標(biāo)目錄與歸檔嚴(yán)格一致。stripComponents 1剝離歸檔成員路徑的第一個(gè)前導(dǎo)組件。Oh My Zsh 的 master 歸檔解壓后頂層是ohmyzsh-master/剝離后內(nèi)容正好落到.oh-my-zsh/下。refreshPeriod 168h一周刷新一次。為什么給前兩項(xiàng)設(shè)置刷新周期因?yàn)樗鼈冎赶騧aster分支的 tarball內(nèi)容會(huì)隨時(shí)間變化而 powerlevel10k 指向v1.15.0這種打標(biāo)簽版本不會(huì)變化所以不設(shè)置刷新周期。要升級(jí) powerlevel10k只需修改 URL 中的版本號(hào)即可。強(qiáng)制刷新--refresh-externals/-RrefreshPeriod控制的是多久最多重新下載一次默認(rèn)值0表示永不重新下載除非強(qiáng)制。強(qiáng)制刷新使用--refresh-externals標(biāo)志可簡寫為-Rchezmoi --refresh-externals apply # 等價(jià)寫法 chezmoi -R apply從源碼看-R標(biāo)志的值類型定義在 internal/chezmoi/refreshexternals.go支持always、auto、never三個(gè)取值也兼容布爾值標(biāo)志在 internal/cmd/config.go 中注冊為持久標(biāo)志。緩存機(jī)制與refreshPeriod的源碼實(shí)現(xiàn)chezmoi 會(huì)在本地緩存下載的歸檔避免每次運(yùn)行命令都重新下載。對應(yīng)實(shí)現(xiàn)是 internal/chezmoi/sourcestate.go 中的getExternalDataRaw以URL 的 SHA256 摘要作為緩存鍵cacheKey : hex.EncodeToString(urlSHA256[:])緩存文件存放在緩存目錄的external/子目錄下RefreshExternalsAuto默認(rèn)下若緩存文件存在且修改時(shí)間 refreshPeriod晚于當(dāng)前時(shí)間則直接使用緩存refreshPeriod 0時(shí)只要緩存存在就永遠(yuǎn)復(fù)用RefreshExternalsAlways時(shí)完全不使用緩存RefreshExternalsNever時(shí)永遠(yuǎn)使用緩存無視刷新周期file://URL 則始終直接讀取磁盤文件不走緩存。實(shí)戰(zhàn)注意緩存文件導(dǎo)致的漂移如果外部依賴的目標(biāo)目錄在正常使用中會(huì)產(chǎn)生緩存文件chezmoi apply會(huì)報(bào)出文件已變化。解決辦法是把緩存目錄加入.chezmoiignore。例如 Oh My Zsh 會(huì)把補(bǔ)全緩存寫入.oh-my-zsh/cache/completions/應(yīng)將其加入.chezmoiignore。性能警告不要用 externals 管理大文件或大歸檔。chezmoi 每次執(zhí)行chezmoi diff、chezmoi apply或chezmoi verify時(shí)都會(huì)校驗(yàn)外部內(nèi)容的精確內(nèi)容。對于大型外部內(nèi)容應(yīng)改用run_onchange_腳本一次性解包。三、用include過濾器只選取歸檔中的部分文件include接受一組模式只從歸檔 URL 中引入匹配的成員。比如上面 zsh-syntax-highlighting 的示例如果只想引入其必要的源文件而不是整個(gè)歸檔[.oh-my-zsh/custom/plugins/zsh-syntax-highlighting] type archive url https://github.com/zsh-users/zsh-syntax-highlighting/archive/master.tar.gz exact true stripComponents 1 refreshPeriod 168h include [*/*.zsh, */.version, */.revision-hash, */highlighters/**]匹配算法include/exclude的模式匹配的是歸檔內(nèi)的路徑不是目標(biāo)狀態(tài)路徑。參考手冊給出的判定算法如下成員名命中任意exclude模式 → 排除若該成員是目錄其下所有文件與子目錄也遞歸排除否則成員名命中任意include模式 → 包含否則若只指定了include模式 → 排除否則若只指定了exclude模式 → 包含否則兩種都沒指定→ 包含。被排除的成員不會(huì)生成源碼狀態(tài)條目若是目錄其全部子內(nèi)容也一并排除。對應(yīng)實(shí)現(xiàn)位于 internal/chezmoi/sourcestate.gochezmoi 用PatternSet收集 include/exclude 模式并在WalkArchive遍歷歸檔時(shí)按剝離組件之前的原始路徑進(jìn)行匹配否則無法區(qū)分同一層級(jí)下的同名文件命中排除模式且為目錄時(shí)返回fs.SkipDir以實(shí)現(xiàn)遞歸排除。四、從 URL 包含單個(gè)文件file類型包含單個(gè)文件與包含子目錄使用同一套機(jī)制只是外部類型從archive換成file。例如把 vim-plug 的plug.vim放入~/.vim/autoload/plug.vim[.vim/autoload/plug.vim] type file url https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim refreshPeriod 168htype file表示目標(biāo)是一個(gè)內(nèi)容來自u(píng)rl的普通文件。可選布爾字段executable可讓目標(biāo)文件帶上可執(zhí)行權(quán)限見參考手冊。五、從歸檔中提取單個(gè)文件archive-file類型archive-file類型用于從歸檔中提取單個(gè)成員到目標(biāo)路徑特別適合把預(yù)編譯二進(jìn)制下載并落盤到~/.local/bin。下面的例子從 age 的發(fā)布?xì)w檔中提取age/age可執(zhí)行文件URL 通過模板根據(jù)當(dāng)前操作系統(tǒng)與架構(gòu)計(jì)算 TOML{{ $ageVersion : 1.1.1 -}} [.local/bin/age] type archive-file url https://github.com/FiloSottile/age/releases/download/v{{ $ageVersion }}/age-v{{ $ageVersion }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz path age/age YAML{{ $ageVersion : 1.1.1 -}} .local/bin/age: type: archive-file url: https://github.com/FiloSottile/age/releases/download/v{{ $ageVersion }}/age-v{{ $ageVersion }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz path: age/age JSON{{ $ageVersion : 1.1.1 -}} { .local/bin/age: { type: archive-file, url: https://github.com/FiloSottile/age/releases/download/v{{ $ageVersion }}/age-v{{ $ageVersion }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz, path: age/age } }這會(huì)從給定 URL按當(dāng)前 OS 和架構(gòu)計(jì)算得出提取歸檔成員age/age寫入目標(biāo)./local/bin/age。注意archive-file的幾點(diǎn)細(xì)節(jié)path要寫對path對應(yīng)歸檔內(nèi)的成員路徑stripComponents會(huì)先剝離前導(dǎo)組件再與path比較。用tar tzf之類的工具先確認(rèn)路徑且path通常不需要前導(dǎo)./參考手冊給出的例子中path zellij而不帶./。executable true即使歸檔內(nèi)未設(shè)置可執(zhí)行位也能強(qiáng)制給目標(biāo)文件加上執(zhí)行權(quán)限——這對下載預(yù)編譯二進(jìn)制非常有用。.rar與.zip是歸檔要從這類格式中提取單個(gè)文件必須使用archive-file類型。六、把整個(gè)歸檔導(dǎo)入源碼狀態(tài)chezmoi import有時(shí)需要把整個(gè)第三方配置歸檔一次性導(dǎo)入源碼狀態(tài)而不是持續(xù)跟蹤外部 URL。import命令就是為此設(shè)計(jì)的。例如把最新版 Oh My Zsh 導(dǎo)入~/.oh-my-zshcurl -s -L -o ${TMPDIR}/oh-my-zsh-master.tar.gz https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz mkdir -p $(chezmoi source-path)/dot_oh-my-zsh chezmoi import --strip-components 1 --destination ~/.oh-my-zsh ${TMPDIR}/oh-my-zsh-master.tar.gzimport命令的完整參數(shù)見 internal/cmd/importcmd.go包括-d/--destination目標(biāo)前綴--exact為導(dǎo)入的目錄設(shè)置exact_屬性-x/--exclude與-i/--include按條目類型過濾-r/--remove-destination導(dǎo)入前刪除目標(biāo)--strip-components剝離前導(dǎo)路徑組件。注意這只更新源碼狀態(tài)之后仍需運(yùn)行chezmoi apply來更新目標(biāo)目錄。七、處理不支持壓縮格式的 tar 歸檔filter.command與filter.argschezmoi 原生理解 tar 歸檔支持未壓縮以及 bzip2、gzip、xz、zstd 壓縮格式。如果遇到不支持的壓縮格式可以用過濾器先把數(shù)據(jù)解壓。例如在 chezmoi 原生支持 zstd 之前處理.tar.zst外部歸檔的方式[.Software/anki/2.1.54-qt6] type archive url https://github.com/ankitects/anki/releases/download/2.1.54/anki-2.1.54-linux-qt6.tar.zst filter.command zstd filter.args [-d] format tarfilter.command與filter.args組合起來告訴 chezmoi把下載的數(shù)據(jù)通過管道送入zstd -dformat tar則聲明過濾器的輸出是未壓縮的 tar 歸檔。從參考手冊看指定filter.command/filter.args后文件或歸檔會(huì)通過寫入命令標(biāo)準(zhǔn)輸入、讀取命令標(biāo)準(zhǔn)輸出的方式完成過濾。format字段支持的歸檔格式有tar、tar.gz、tgz、tar.bz2、tbz2、xz、.tar.zst與zip。若未指定formatchezmoi 會(huì)先依據(jù) URL 路徑、再依據(jù)內(nèi)容猜測格式實(shí)現(xiàn)見 internal/chezmoi/sourcestate.go使用GuessArchiveFormat。八、保持 git 倉庫子目錄最新git-repo類型如果你希望某個(gè)子目錄始終跟隨一個(gè) git 倉庫的最新狀態(tài)可以用git-repo外部類型[.vim/pack/alker0/chezmoi.vim] type git-repo url https://github.com/alker0/chezmoi.vim.git refreshPeriod 168h行為規(guī)則目錄不存在 → 執(zhí)行g(shù)it clone目錄存在 → 執(zhí)行g(shù)it pull拉取最新變更但不早于每個(gè)refreshPeriod一次默認(rèn)refreshPeriod為0即禁用刷新可通過給chezmoi apply傳--refresh-externals/-R強(qiáng)制刷新即強(qiáng)制git pull。自定義 clone / pull 參數(shù)通過$DIR.clone.args與$DIR.pull.args變量可以定制git clone與git pull的參數(shù)例如強(qiáng)制 fast-forward[.vim/pack/alker0/chezmoi.vim] type git-repo url https://github.com/alker0/chezmoi.vim.git refreshPeriod 168h [.vim/pack/alker0/chezmoi.vim.pull] args [--ff-only]源碼級(jí)實(shí)現(xiàn)從源碼看git-repo外部被生成為SourceStateCommandinternal/chezmoi/sourcestate.go目錄不存在時(shí)執(zhí)行g(shù)it clone [clone.args] URL dest工作目錄為進(jìn)程當(dāng)前目錄目錄存在時(shí)在目標(biāo)目錄內(nèi)執(zhí)行g(shù)it pull [pull.args]命令通過sync.OnceValue延遲構(gòu)造以避免過早解析$PATHforceRefresh由--refresh-externalsalways觸發(fā)。倉庫中的 externalgitrepo.txtar 測試驗(yàn)證了chezmoi apply --refresh-externals會(huì)執(zhí)行g(shù)it pull。限制與替代方案依賴git二進(jìn)制$PATH中必須有g(shù)it。目錄管理權(quán)交給 gitchezmoi 無法管理該目錄中的其他文件。不參與差異比較git-repo外部的內(nèi)容不會(huì)體現(xiàn)在chezmoi diff或chezmoi dump中并會(huì)被chezmoi unmanaged列出。需要管理額外文件時(shí)改用archive外部類型URL 指向該 git 倉庫master/main分支的歸檔即可。九、在源碼目錄中使用 git submoduleexternal_屬性除了.chezmoiexternal.$FORMAT還可以用 git submodule 把外部 git 倉庫引入源碼目錄。chezmoi init與chezmoi update默認(rèn)會(huì)用--recurse-submodules標(biāo)志處理 submodule實(shí)現(xiàn)見 internal/cmd/initcmd.go 與 internal/cmd/updatecmd.go。為什么必須設(shè)置external_屬性chezmoi 假定源碼狀態(tài)中的所有文件與目錄都是 chezmoi 格式即文件名包含private_、run_等屬性前綴。絕大多數(shù) submodule 并不符合這一格式——例如 submodule 中的run_test.sh會(huì)被 chezmoi 誤解為run_腳本。因此如果使用 git submodule必須對包含 submodule 的子目錄設(shè)置external_屬性。設(shè)置external_屬性后chezmoi 會(huì)跳過該目錄中的條目不再按 chezmoi 格式解析從源碼看internal/chezmoi/sourcestate.go 會(huì)跳過external_目錄中的條目并可通過.chezmoiexternals/目錄機(jī)制處理參見 special-directories 文檔。如果不想讓 chezmoi 處理 submodule可以傳--recurse-submodulesfalse標(biāo)志或?qū)⑴渲米兞縰pdate.recurseSubmodules設(shè)為false。十、進(jìn)階字段與最佳實(shí)踐匯總校驗(yàn)下載內(nèi)容checksum設(shè)置checksum.sha256、checksum.sha384或checksum.sha512后chezmoi 會(huì)校驗(yàn)下載數(shù)據(jù)是否匹配給定校驗(yàn)和checksum.size校驗(yàn)數(shù)據(jù)大小。這為file/archive外部提供了供應(yīng)鏈級(jí)別的完整性保障。對應(yīng)數(shù)據(jù)結(jié)構(gòu)在 internal/chezmoi/sourcestate.go 中定義源碼中還額外支持md5、ripemd160、sha1字段。多外部合并到一個(gè)目錄targetPathtargetPath用于指定外部內(nèi)容的目標(biāo)路徑以覆蓋條目鍵從而在一個(gè).chezmoiexternal文件中把多個(gè)外部合并進(jìn)同一個(gè)目標(biāo)目錄。例如把多個(gè)字體歸檔都落到Library/Fonts[p10k_fonts] type archive url https://github.com/romkatv/powerlevel10k-media/archive/master.tar.gz exact false stripComponents 1 refreshPeriod 168h include [*/*.ttf] targetPath Library/Fonts [source_code_pro] type archive url https://github.com/adobe-fonts/source-code-pro/archive/master.tar.gz exact false stripComponents 2 refreshPeriod 168h include [**/*.ttf] targetPath Library/Fonts私有 git 倉庫外部外部可以指向私有 git 倉庫但必須使用 SSH URLSSH 密鑰應(yīng)在before_腳本中配置好。為了避免密鑰未就緒時(shí)報(bào)錯(cuò)可用模板函數(shù)stat判斷密鑰文件是否存在再?zèng)Q定是否引入條目{{ if stat (joinPath .chezmoi.homeDir .ssh id_rsa) }} [.path/to/private/repo] type git-repo url gitprivate.com:org/repo.git {{ end }}加密與解壓encrypted true表示文件或歸檔已加密chezmoi 會(huì)按加密配置處理decompress指定文件的解壓方式支持bzip2、gzip、xz、zstd。合理選擇refreshPeriod參考手冊建議的合適刷新周期一天24h、一周168h、四周672h。判斷原則很簡單——URL 指向會(huì)變化的master/main分支時(shí)設(shè)置刷新周期指向固定標(biāo)簽版本時(shí)保持默認(rèn)0永不刷新需要更新時(shí)手動(dòng)-R強(qiáng)制刷新或直接改 URL。常見問題速查問題解法外部目錄運(yùn)行時(shí)產(chǎn)生緩存文件導(dǎo)致 apply 報(bào)變化把緩存目錄加入.chezmoiignore如.oh-my-zsh/cache/completions/大文件/大歸檔性能差改用run_onchange_腳本一次性解包需要git-repo目錄中再管理其他文件換用archive外部 分支歸檔 URL第三方 submodule 文件名被誤解析對子目錄設(shè)置external_屬性想要一次性固化第三方內(nèi)容用chezmoi import導(dǎo)入源碼狀態(tài)下載內(nèi)容需要完整性校驗(yàn)設(shè)置checksum.sha256等字段至此你已經(jīng)掌握了從單文件到整個(gè) git 倉庫的全部外部引入方式。這套.chezmoiexternal.$FORMAT機(jī)制讓 chezmoi 既能保持源碼狀態(tài)的自洽性又能把分散在各處的第三方 dotfiles 統(tǒng)一納入chezmoi apply的掌控之下。贊分享開發(fā)工具CLI配置管理【免費(fèi)下載鏈接】chezmoiManage your dotfiles across multiple diverse machines, securely.項(xiàng)目地址https://gitcode.com/gh_mirrors/ch/chezmoi點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Scrcpy終極指南在電腦上完美控制Android設(shè)備的完整方案Scrcpy終極指南在電腦上完美控制Android設(shè)備的完整方案 Scrcpy是一款免費(fèi)開源的Android屏幕鏡像和控制工具讓您能夠在電腦上實(shí)時(shí)顯示并操作音視頻chezmoi 與其他 dotfiles 管理工具對比特性矩陣、核心差異與選型指南chezmoi 與其他 dotfiles 管理工具對比特性矩陣、核心差異與選型指南 本文基于倉庫中的官方對比文檔 assets/chezmoi.io/docs開發(fā)工具CLI配置管理chezmoi性能調(diào)優(yōu)大規(guī)模dotfiles倉庫的管理和優(yōu)化策略chezmoi性能調(diào)優(yōu)大規(guī)模dotfiles倉庫的管理和優(yōu)化策略 chezmoi是一個(gè)強(qiáng)大的跨平臺(tái)dotfiles管理工具專門設(shè)計(jì)用于在多臺(tái)不同機(jī)器上安全地開發(fā)工具CLI配置管理上一篇KeyMapper 3.0版本發(fā)布移動(dòng)設(shè)備按鍵映射工具的重大升級(jí)下一篇Fabrication-Toolkit項(xiàng)目5.1.0版本發(fā)布KiCad插件功能升級(jí)解析創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考