1. 程式人生 > >【20180410】python--repo:主體main.py學習

【20180410】python--repo:主體main.py學習

1.概述:

main.py是repo命令執行的第二站,在入口指令碼repo檔案完成檢驗和初始化執行環境後,即將repo命令引數傳遞給main.py進行詳細的引數解析和repo command對應物件呼叫執行。即是說main.py起到總排程的作用,根據repo命令引數判斷需要呼叫哪個command物件並完成物件建立和屬性賦值,最後執行command物件的execute方法執行repo command。

2.資料結構:

main.py中用到了三種較複雜且重要的資料結構,分別為_Repo類、all_commands物件陣列、XmlManifest類;其中_Repo類是在main.py內部宣告,後兩者是import的外部包內容;另外還繼續用到之前的關鍵變數 repodir(.repo)。

本文中主要分析_Repo類的使用,all_commands和XmlManifest在後續的subcmds學習部分和manifest_xml.py學習部分會單獨分析。

3.主體思路:

__main__ -->

_Main(sys.args[1:]) -->

optparse.OptionParser.parse_args[argv](第一次引數解析:解析在入口指令碼repo檔案內呼叫main.py時傳遞的三個引數:--repo-dir&--wrapper-version&--wrapper-path) -->

checkwrapperversio & checkrepodir (通過對比下載的repo倉內最新repo檔案提供的repo VERSION和執行環境本地入口指令碼repo檔案提供的repo VERSION來判斷本地入口指令碼repo是否需要強制/提示更新,並再次檢查關鍵變數repodir是否政策存在)-->

repo = _Repo(opt.repodir)(初始化_Repo型別的物件,包括兩個重要資料的賦值:repodir、all_commands物件陣列)-->

_init_ssh&_init_http(初始化網路環境)-->

repo._Run(argv)(執行_Run方法進行第二&三次引數解析和repo command呼叫執行)-->

分支:執行_Run過程中如丟擲RepoChangeException 則通過os.execv重新執行main.py

分支:執行_Run正常結束後close_ssh關閉ssh連線

對repo._Run(argv)的思路解析:

a.對argv進行第二次引數解析,將argv分解為glob、name和argv三部分,glob部分對應--time、--trace、--version等repo命令通用引數,name對應repo子命令command如init、sync、upload等,argv對應repo子命令的相關引數如-u、-b、-m等。-->

b.基於name獲取repo子命令對應的物件cmd = self.commands[name]  並對重要屬性進行賦值:repodir、manifest。 -->

c.對第二次解析得到的子命令相關引數argv進行第三次解析(通過cmd物件從頂層父類Command繼承來的OptionParser和cmd物件自身多型的_Options方法來解析)。 -->

d.呼叫cmd物件的Execute方法 cmd.Execute(copts, cargs) 執行子命令,執行過程中針對可能丟擲的Downloaderror、ManifestInvalidRevisionError、NosuchProjectError進行監視處理。

對repo命令的引數解析再多說兩句,整個repo執行過程中對於repo命令解析分為四層:

第一層:入口指令碼repo檔案中解析--repo-url、--repo-branch等引數用來下載repo倉庫初始化執行環境;

第二層:main.py中解析由入口指令碼repo檔案傳遞的三個引數:--repo-dir&--wrapper-version&--wrapper-path用來判斷執行環境中repo版本是否正確以及repodir是否正常存在;

第三層:main.py中執行Run時解析剩餘的repo命令引數獲得glob、name和argv三部分用來配置repo執行過程選項和確定repo子命令command;

第四層:Run中執行cmd.OptionParser方法,呼叫每個子命令的不同解析方法來差異化地解析對應repo子命令的相關引數如-u、-b、-m。

第一二三層都是針對repo命令的公共部分進行解析處理包括執行環境處理、repo版本檢驗、執行過程選項等;第四層則是針對repo命令中用於各個子命令的差異化引數,呼叫各個子命令的差異化解析方法來解析處理。

最後再次強調對main.py中_Repo類和來自外部import的all_commands物件陣列的深入掌握,這兩者是main.py完成總排程功能的核心資料結構;至於XmlManifest類則是貫穿後續repo子命令整個執行過程的核心資料結構之一。