<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                本文譯自 Go += Package Versioning, Go & Versioning 的第 1 部分, 版權@歸原文所有. 我們需要將包版本控制添加到 Go. 更確切地說, 我們需要將軟件包版本的概念添加到 Go 開發人員和我們的工具的工作詞匯表中, 以便在彼此交談時準確地確定應該構建, 運行或分析哪個程序. go 命令需要能夠告訴開發人員具體哪些版本的軟件包在特定構建中, 反之亦然. 版本控制可以讓我們啟用可重復構建, 所以如果我告訴你試用我的程序的最新版本, 我知道你將不僅獲得我的代碼的最新版本, 而且還包括我的代碼所依賴包的精確的同一版本, 所以你和我將構建完全等價的二進制. 版本控制還可以讓我們確保明天程序的構建方式與今天的完全相同. 即使有更新版本的依賴, go 命令也不應該使用它們除非被要求這樣做. 盡管我們必須添加版本控制, 但我們也不能移除當前 go 命令的最佳部分: 簡單, 速度以及易懂. 當前, 許多程序員大多不關注版本控制, 而且大部分都工作良好. 如果我們正確地獲得了模型和默認值, 我們應該能夠以這樣的方式添加版本控制, 即程序員仍然大多不關注版本控制, 并且一切都更好, 而且更易于理解. 現有的工作流程應該盡可能少地改變. 發布新版本應該非常簡單. 一般來說, 版本管理工作必須從后臺淡出, 而不是日常關注. 簡而言之, 我們需要添加軟件包版本控制, 但我們還不能破壞 go get. 這篇文章草擬了一個做這件事的恰到好處的提案, 以及今天就可以嘗試的原型演示, 希望這將成為最終 go 命令集成的基礎. 我打算將這篇文章作為有效討論什么可行以及什么不可行的開始. 基于這一討論, 我將對提案和原型進行調整, 然后我將提交一份正式的 Go 提案, 作為可選功能集成到 Go 1.11 中. 這個提案保留了 go get 最好的部分, 增加了可重復構建, 采用了語義版本化, 消除了 vendoring, 棄用了 GOPATH 轉而采用了基于項目的工作流程, 并且提供了一個從 dep 和其前任們的平滑遷移. 也就是說, 這個提案還處于早期階段. 如果細節還不正確, 我們會花時間在集成進 Go 主發行版之前修復它們. 背景 在我們看這個提案之前, 讓我們看看我們做到了什么. 這可能有點長, 但歷史對當下有重要的啟示, 并有助于理解提案為什么會作出改變. 如果你不耐煩, 請跳到提案或閱讀附帶的示例博客文章. Makefiles, goinstall, 以及 go get 2009 年 11 月, Go 的最初版本是一個編譯器, 鏈接器和一些庫. 你必須運行 6g 和 6l 編譯和鏈接你的程序, 并且我們包含了示例 makefile(s). 在大多數情況下, 有一個最小化的 gobuild 封裝可以構建單個包并寫入一個合適的 makefile. 沒有既定的方式與其他人分享代碼. 我們知道還需要更多的東西, 但是我們已經發布了我們所有的東西, 并計劃在社區中完成剩下的工作. 2010 年 2 月, 我們提出了 goinstall 一個新的零配置命令, 用于從源碼控制倉庫(如 Bitbucket 和 GitHub )下載軟件包. Goinstall 引入了今天開發人員認為理所當然的導入路徑約定. 由于當時沒有任何代碼遵循這些約定, 所以 goinstall 起初只能處理除標準庫之外沒有任何其他包導入的軟件包. 但是開發人員很快從他們自己的各種命名方案轉移到了我們今天所知道的統一約定, 并且已發布的 Go 包集合發展成為一個連貫的生態系統. Goinstall 也消除了 makefile 以及與之相關的用戶定義構建變動的復雜性. 盡管對于包作者在每次構建期間不能生成代碼來說有時不方便, 但這種簡化對于包用戶來說非常重要: 用戶不必擔心首次安裝與構建之前使用的包作者相同的一組工具. 簡化對于工具來說也是至關重要的. makefile 是編譯包的一個必要的步驟, 反向工程如何應用不同的工具, 如 go vet 或代碼完成, 到相同的包, 可能會非常困難. 即使正確地獲得構建依賴關系, 以便在必要時重新構建包, 并且只在必要時重新構建包, 這對于任意 makefile 非常困難. 雖然有些人在靈活性被剝奪的時候表示反對, 但回想起來, 這些好處遠遠超過了不便之處. 2011 年 12 月, 作為 Go 1 準備工作的一部分, 我們推出了 go 命令, go get 替換了 gobuild . 總體而言, go get 具有變革意義, 可讓 Go 開發人員共享源代碼并構建彼此的工作, 并通過在 go 命令內部隔離構建系統的細節來啟用工具. 但是 go get 缺少任何版本控制的概念. 很明顯在第一次 goinstall 討論中我們需要做一些關于版本控制的內容. 不幸的是, 至少對于我們在 Go 團隊中, 我們不清楚究竟該怎么做. 當 go get 需要一個包時, 它總是獲取最新的副本, 將下載和更新操作委托給像 Git 或 Mercurial 這樣的版本控制系統. 軟件包版本的這種無知導致了至少兩個顯著的缺陷. 版本和 API 穩定性 go get 的第一個顯著缺點是, 如果沒有版本控制的概念, 它就不能告訴用戶對給定更新期望發生什么樣的變化. 2013 年 11 月, Go 1.2 添加了一個關于包版本控制的常見問題解答條目, 提供了基本的建議 (Go 1.10也沒有變): 打算供公眾使用的軟件包應該盡量保持向后兼容性. Go 1 兼容性準則在這里是一個很好的參考: 不要刪除導出的名稱, 鼓勵標記的復合文字等等. 如果需要不同的功能, 請添加新名稱而不是更改舊名稱. 如果需要完全打破兼容性, 請創建新的導入路徑的軟件包. 2014 年 3 月, Gustavo Niemeyer 創建了 gopkg.in, 廣而告之為 "Go語言的穩定API". 該域名是一個版本感知的 GitHub 重定向器, 允許導入路徑, 如 gopkg.in/yaml.v1 和 gopkg.in/yaml.v2 引用單個 Git 倉庫的不同提交 (可能位于不同分支上) . 在語義版本化之后, 包作者需要在進行重大更改時引入一個新的主要版本, 以便較早版本的 v1 導入路徑可以作為先前版本的替代版本, 而 v2 導入路徑可能是完全不同的 API. 2015 年 8 月, Dave Cheney 提出采用語義版本化的提案. 這在接下來的幾個月里引發了一場有趣的討論, 其中每個人似乎都認為, 使用語義版本標記代碼似乎是一個好主意, 但沒有人知道下一步: 這些版本應該使用什么工具 ? 任何關于語義版本的討論都不可避免地包含引用海勒姆法則的反駁, 其中指出: 擁有足夠數量的 API 用戶, 無論你在合同中承諾什么, 都無關緊要. 系統中所有可觀察到的行為都將被某人依賴. 雖然海勒姆法則在經驗上是真實的, 但是語義版本化仍然是一個有用的方法來構建對發布之間關系的期望. 從 1.2.3 更新到 1.2.4 不應該破壞你的代碼, 而從 1.2.3 更新到 2.0.0 是可能的. 如果代碼在更新到 1.2.4 后停止工作, 作者很可能會歡迎 bug 報告并在 1.2.5 中發布修復. 如果你的代碼在更新到 2.0.0 之后停止工作(甚至編譯), 那么這種改變更有可能是故意的, 并且在 2.0.1 中修復你的代碼的機會相對較少. 我沒有從海勒姆法則中得出結論: 語義版本化是不可能的, 我認為構建應該小心地使用作者所做的每個依賴的完全相同的版本, 除非被迫. 也就是說, 構建應該默認為盡可能重現. Vendoring 以及可重復性構建 go get 的第二個顯著的缺點是, 如果沒有版本控制的概念, 它不能確保甚至不能表達可重復構建的想法. 無法確定你的用戶正在編譯你的代碼所依賴的相同版本. 2013 年 11 月, Go 1.2 常見問題解答還添加了以下基本建議: 如果你使用的是外部提供的軟件包, 并擔心它可能會以意想不到的方式更改, 最簡單的解決方案是將其復制到本地倉庫 (這是 Google 內部采取的方法). 將副本存儲在新的導入路徑下, 以將其標識為本地副本. 例如, 你可能會復制 "original.com/pkg" 到 "you.com/external/original.com/pkg". Keith Rarick 的 goven 是幫助實現這一過程自動化的工具之一. Goven, Keith Rarick 于 2012 年 3 月開始創建, 它將依賴項復制到你的倉庫中, 并更新其中的所有導入路徑以反映新位置. 以這種方式修改依賴項的源代碼對于構建它而言是必要的, 但也是不幸的. 這些修改使得它難以與使用該依賴關系的其他復制代碼進行比較和合并更新的副本和所需的更新. Keith 在 2013 年 9 月宣布了 godep: "一個凍結軟件包依賴關系的新工具". godep 的主要進展是添加我們現在所理解的 Go vendoring - 即將依賴復制到項目中, 而不修改源文件 - 沒有直接工具鏈通過以某種方式設置 GOPATH 來支持. 2014 年 10 月, Keith 建議在 Go 工具鏈中增加對 "外部軟件包" 概念的支持, 以便工具可以更好地理解使用該約定的項目. 屆時, 有許多類似于 godep 的努力. Matt Farina 寫了一篇博客文章: "Glide In The Sea of Go Package Managers", 將最新的包管理器特別是 glide 與 godep 進行比較. 2015 年 4 月, Dave Cheney 介紹了 gb 一個 "基于項目的構建工具...允許通過源代碼 vendoring 重復構建", 而且無需重新導入. (gb 的另一個動機是避免將代碼存儲在 GOPATH 中的特定目錄中, 這對于許多開發人員的工作流程來說不太適合). 那年春天, Jason Buberel 對 Go 包管理進行了調查, 以了解可以采取什么措施來統一這些多重努力, 避免重復和浪費工作. 他的調查在 Go 團隊中清楚地表明, go 命令需要直接支持 vendoring 而不是重寫 import . 與此同時, Daniel Theophanes 開始了一個文件格式規范, 以描述 vendor 目錄中確切的出處和代碼版本. 2015 年 6 月, 我們接受 Keith 的提案作為 Go 1.5 vendor 實驗方式, 在 Go 1.5 中可選, 并在 Go 1.6 中默認啟用. 我們鼓勵所有 vendoring 工具作者與 Daniel 合作采用單一元數據文件格式. 將 vendoring 概念納入 Go 工具鏈允許程序分析工具如 go vet 使用 vendoring 更好地理解項目, 現在有十幾個 Go 軟件包管理器或 vendoring 工具來管理 vendor 目錄. 另一方面, 因為這些工具都使用不同的元數據文件格式, 所以它們不能互操作, 并且不能輕松共享關于依賴需求的信息. 從根本上說, vendoring 是解決軟件包版本問題的不完整方案. 它只提供可重復性構建. 它沒有幫助理解軟件包版本并決定使用哪個版本的軟件包. 軟件包管理器如 glide 和 dep 將版本控制的概念隱式地添加到 Go 中, 通過以某種方式設置 vendor 目錄而無需直接的工具鏈支持. 因此, Go 生態系統中的許多工具無法正確識別版本. 很明顯, Go 需要對軟件包版本提供直接的工具鏈支持. 官方包管理實驗 在 2016 年 GopherCon 大會上, 一群有趣的 gophers 在 Hack Day (現在是 Community Day) 聚在一起, 圍繞 Go 包管理進行廣泛的討論. 其中一個成果是成立了一個委員會和一個包管理工作咨詢小組, 目標是為 Go 包管理創建一個新工具. 愿景是為了統一和取代現有的工具, 但它仍然在直接工具鏈之外使用 vendor 目錄來實現. 由 Peter Bourgon 組織的委員會 Andrew Gerrand, Ed Muller, Jessie Frazelle 和 Sam Boyer 起草了一份規范, 然后由 Sam 領導, 將其實施為 dep. 有關背景信息, 請參閱 Sam 的 2016 年 2 月發布的文章: "所以你想寫一個包管理器", 他 2016 年 12 月發布的 "Go 的依賴管理傳奇" 和他 2017 年 7 月的 GopherCon 演講 "Go包管理的新時代". Dep 有許多用途: 它是對當前可用的實踐的重要改進, 它是朝著解決方案邁出的重要一步, 也是一個實驗 - 我們稱之為 "官方實驗" - 幫助我們更多地了解什么是對 Go 開發者友好的以及哪些不是. 但 dep 不是最終集成了包版本控制的 go 命令的直接原型. 它是一種強大的, 幾乎任意靈活的方式來探索設計空間, 在構建 Go 程序時扮演像 makefiles 一樣的角色. 但是, 一旦我們更好地理解設計空間并將其縮小到必須支持的幾個關鍵特性, 它將幫助 Go 生態系統移除其他特性, 降低表現力, 采用強制性約定, 使 Go 代碼庫更加均勻并且更容易理解并使工具更易于構建. 這篇文章是 dep 之后下一步的開始: 最終 go 命令集成原型的初稿, 即 goinstall 的包管理的等價物. 原型是我們所稱的獨立命令 vgo. 它是 go 命令的直接替代品, 但它增加了對軟件包版本控制的支持. 這是一個新的實驗, 我們將看到我們可以從中學到什么. 就像我們介紹 goinstall 的那樣, 當前一些代碼和項目已經可以使用 vgo, 其他項目需要進行更改才能兼容. 我們將拿走一些控制和表現力, 就像我們拿走了 makefile 一樣, 為簡化系統和消除用戶復雜性服務. 通常,我們正在尋找早期采用者來幫助我們進行實驗 vgo, 以便我們盡可能地從用戶那里學習. 開始嘗試 vgo 并不意味著結束對 dep 的支持. 我們將保持 dep 可用, 直到完成 go 命令集成的路徑被確定, 實施并且大體上可用. 我們也將盡可能順利地完成從最終過渡 dep 到 go 命令集成的各種形式. 尚未轉化到 dep 的項目仍然可以從中獲益. (注意, godep 和 glide 已經結束了活躍的開發, 鼓勵遷移到 dep). 其他項目不妨直接遷移到 vgo, 如果它已滿足需求. 提案 添加版本到 go 命令的提案有四個步驟. 首先, 采用 Go FAQ 和 gopkg.in 暗示的導入兼容性規則; 也就是說, 建立一個預期, 即具有給定導入路徑的軟件包的新版本應該與舊版本向后兼容. 其次, 使用簡單的新算法(稱為最小版本選擇)來選擇在給定構建中使用哪些版本. 第三, 引入 Go module 的概念, Go module 是一組版本為單個版本的軟件包, 并聲明了它們的依賴關系必須滿足的最低要求. 第四, 定義如何將所有這些改造成現有的 go 命令, 以便基本的工作流程從今天不再發生顯著變化. 本節的其余部分將介紹這些步驟中的每一個. 本周其他博客文章將更詳細地介紹. 導入 (Import) 兼容性規則 包裝管理系統中幾乎所有的痛苦都是由于試圖馴服不兼容而導致的. 例如, 大多數系統允許程序包 B 聲明它需要程序包 D 6 或更高版本, 然后允許程序包 C 聲明它需要D 2, 3 或 4, 但不是 5 或更高版本. 如果你正在編寫軟件包 A, 并且你想同時使用 B 和 C, 那么你運氣不好: 沒有一個 D 版本可以選擇將 B 和 C 一起構建到 A 中. 你什么也做不了: 這些系統說 B 和 C 這樣做是可以接受的 - 他們有效地鼓勵它 - 所以就這樣你被卡住了. 這個提案要求包作者遵循導入兼容性規則, 而不是設計一個不可避免導致大型程序無法構建的系統: 如果舊軟件包和新軟件包具有相同的導入路徑, 則新軟件包必須與舊軟件包向后兼容. 這條規則是對前面引用的 Go FAQ 中的建議的重申. 常見問題引文最后說到: "如果需要完全的破壞兼容性, 請使用新的導入路徑創建一個新包". 今天的開發人員希望使用語義版本來表達這樣一個破壞, 所以我們將語義版本集成到了我們的提案中. 具體來說, 主版本 2 和更高版本可以通過在路徑中包含版本來使用, 如下所示: ~~~ import "github.com/go-yaml/yaml/v2" ~~~ 創建 v2.0.0, 在語義版本化中表示一個重大破壞, 因此按照導入兼容性的要求, 創建具有新導入路徑的新包. 由于每個主要版本都有不同的導入路徑, 因此給定的 Go 可執行文件可能包含每個主要版本中的一個. 這是預期的和可取的. 它保持程序的構建, 并允許一個非常大的程序部分獨立地從 v1 更新到 v2. 期望包作者遵循導入兼容性規則, 可以避免嘗試馴服不兼容性, 使整個系統指數級更簡單, 并且軟件包生態系統更少碎片化. 當然, 實際上, 盡管作者做出了最大的努力, 但在同一個主要版本中的更新偶爾會破壞用戶使用. 因此, 使用升級速度不太快的升級機制很重要. 這將引領我們到下一步. 最小版本選擇 今天幾乎所有的軟件包管理器, 包括 dep 和 cargo, 使用最新允許的版本參與構建包. 我認為這是錯誤的違約, 有兩個重要原因. 首先, "最新允許版本"的含義可能因外部事件而改變, 即新版本正在發布. 也許今晚有人會推出一些新版本的依賴項, 然后明天你再運行今天的相同命令序列會產生不同的結果. 其次,為了覆蓋這個默認值, 開發人員花時間告訴包管理器 "不, 不要使用 X", 然后包管理器花時間尋找一種不使用 X 的方法. 這個提案采取了不同的方法, 我稱之為最小版本選擇. 它默認使用構建中涉及的每個包的最舊允許版本. 這個決定從今天到明天不會改變, 因為不會發布舊版本. 更好的是, 為了覆蓋這個默認值,開發人員花時間告訴包管理器, "不, 至少使用 Y", 然后包管理器可以輕松地決定使用哪個版本. 我稱之為最小版本選擇, 因為所選擇的版本是最小的, 也因為整個系統也可能是最小的, 避免了現有系統的幾乎所有復雜性. 最小版本選擇允許模塊僅指定其依賴模塊的最低需求. 它為升級和降級操作提供了定義明確的獨特答案, 并且這些操作的實施效率很高. 它還允許正在構建的整個模塊的作者指定要排除的依賴項版本, 或者指定將特定的依賴項版本替換為本地文件系統中的 forked 副本或作為其自己的模塊發布. 當模塊被構建為其他模塊的依賴項時, 這些排除和替換不適用. 這使用戶可以完全控制自己的程序的構建方式, 而不是其他人的程序構建方式. 最小版本選擇默認提供可重復的版本, 無需鎖定文件. 導入兼容性是簡化版本選擇的關鍵. 用戶不會說 "不, 這太新了", 他們只會說 "不, 這太舊了". 在這種情況下, 解決方案很明確: 使用(最低限度)更新的版本. 新版本同意成為老版本的可接受替代品. 定義 Go 模塊 Go 模塊是一組共享公共導入路徑前綴的軟件包, 稱為模塊路徑. 該模塊是版本控制的單元, 模塊版本被編寫為語義版本字符串. 在開發使用 Git 時, 開發人員將通過向模塊的 Git 倉庫添加標簽(tag)來定義模塊的新語義版本. 盡管強烈推薦使用語義版本, 但也支持引用特定的提交(commits). 一個模塊在一個稱作 go.mod 的新文件中定義了它所依賴的其他模塊的最低版本要求. 例如, 這里是一個簡單的 go.mod 文件: ~~~ // My hello, world. module "rsc.io/hello" require ( "golang.org/x/text" v0.0.0-20180208041248-4e4a3210bb54 "rsc.io/quote" v1.5.2 ) ~~~ 該文件定義了一個由路徑標識的模塊, 該模塊 rsc.io/hello 本身依賴于另外兩個模塊: golang.org/x/text 和 rsc.io/quote. 模塊本身的構建將始終使用 go.mod 文件中列出的特定版本的必需依賴項. 作為更大構建的一部分, 如果構建中的其他地方需要它, 它將只使用更新的版本. 期望包作者使用語義版本標記(tag)發布, vgo 鼓勵使用標記版本, 而不是任意提交. rsc.io/quote 模塊服務于 github.com/rsc/quote, 已經標記了版本, 包括 v1.5.2. 但是 golang.org/x/text 模塊尚未提供標簽版本. 要命名未標記的提交, 偽版本 v0.0.0-yyyymmddhhmmss-commit 標識在給定日期進行的特定提交. 在語義版本控制中, 這個字符串對應于一個 v0.0.0 預發行版, 預發行版標識符為 yyyymmddhhmmss - commit. 語義版本優先規則在 v0.0.0 或更高版本之前排序此類預發布, 并且它們通過字符串比較來排序預發布. 在偽版本語法中放置日期在前可確保字符串比較匹配日期比較. 除了 requirements 之外, go.mod 文件還可以指定上一節中提到的排除 (exclusions) 和替換 (replacements), 但這些僅在直接構建模塊時才應用, 而不是在作為較大程序的一部分構建模塊時應用. 這些例子演示了所有這些. Goinstall 和舊的 go get 直接調用版本控制工具, 如 git 和 hg 直接下載代碼, 導致許多問題, 其中包括碎片化. 例如, 用戶沒有 bzr 無法下載存儲在 Bazaar 倉庫中的代碼. 相比之下, 模塊始終下載通過 HTTP 提供的 zip 歸檔文件. 之前, go get 有特殊外殼為流行代碼托管站點選擇版本控制命令. 現在, vgo 有特殊外殼可以使用這些托管站點的 API 來獲取檔案. 將模塊統一表示為 zip 壓縮文件可以實現模塊下載代理的簡單協議和實現. 公司或個人可以出于任何原因運行代理, 包括安全性, 并希望能夠在刪除原始文件的情況下從緩存副本進行工作. 通過使用代理來確保可用性, 在 go.mod 中定義要使用的代碼, vendor 目錄不再需要. go 命令 go 命令必須更新以使用模塊. 一個顯著的變化是, 普通的構建命令, 如 go build, go install, go run 和 go test, 將按需解決新依賴, 只需要使用 golang.org/x/text 全新的模塊增加導入到 Go 源代碼并且構建代碼. 但是, 最重要的變化是 GOPATH 作為 Go 代碼工作的必需位置的結束. 因為該 go.mod 文件包含完整的模塊路徑, 并且還定義了正在使用的每個依賴項的版本, 所以帶有 go.mod 文件的目錄會將目錄樹的根標記為獨立的工作空間, 與其他任何此類目錄分開. 現在你只是 git clone, cd, 開始寫. 無處不可. 不需要 GOPATH. 接下來 我還發布了 "A Tour of Versioned Go" 來展示 vgo 的使用方式. 看這篇文章, 了解如何下載和實驗 vgo. 我會在整個一周發布更多信息, 以添加我在本文中跳過的詳細信息. 我鼓勵對這個帖子和其他人的評論發表意見, 我也會試著去看看 Go subreddit 和 golang-nuts 郵件列表. 周五, 我將發布 FAQ 作為系列文章的最后一篇博文(至少現在). 下周我會提交一份正式的 Go 提案. 請嘗試 vgo. 在存儲庫中開始標記版本. 創建并簽入 go.mod 文件. 請注意, 如果運行的是一個包含空的 go.mod 的倉庫, 但是, 它有一個現成的 dep, glide, glock, godep, godeps, govend, govendor 或 gvt 配置文件, vgo 將用它來填充 go.mod 文件. 我為 Go 添加版本到它的工作詞匯中這一姍姍來遲的一步感到興奮. 開發者在使用 Go 時遇到的一些最常見的問題是缺乏可重復的構建, go get 完全忽略發布標簽, GOPATH 無法理解包的多個版本以及想要或需要在 GOPATH 之外的源目錄中工作. 這里提出的設計消除了所有這些問題, 以及更多. 即便如此, 我確定有些細節是錯誤的. 我希望我們的用戶能夠通過嘗試新的 vgo 原型并參與富有成效的討論來幫助我們實現這一設計. 我希望 Go 1.11 為 Go 模塊提供初步支持, 作為一種技術預覽, 然后我希望 Go 1.12 能夠提供官方支持. 在稍后的一些版本中, 我們將刪除對舊的無版本的 go get 支持. 不過, 這是一個激進的時間表, 如果獲得正確的功能意味著等待以后的發布, 我們會. 我非常關心從舊的 go get 和無數的 vendoring 工具到新的模塊系統的過渡. 對于我來說, 這個過程就和獲得正確的功能同樣重要. 如果成功的轉換意味著等待以后的發布, 我們會. 感謝 Peter Bourgon, Jess Frazelle, Andrew Gerrand 和 Ed Mueller 以及 Sam Boyer 在包管理委員會的工作以及去年的許多有益討論. 還要感謝 Dave Cheney, Gustavo Niemeyer, Keith Rarick 和 Daniel Theophanes 對 Go 和包版本的關鍵貢獻. 再次感謝 Sam Boyer 創造 dep, 并感謝他和 dep 的所有貢獻者. 感謝所有曾經在許多早期的 vendoring 工具上創建或工作過的人. 最后, 感謝所有能夠幫助我們推進此提案的人, 找到并解決問題, 并盡可能順利地將軟件包版本控制添加到 Go. ![](https://box.kancloud.cn/032176b8778dbc41f1ce6b79a83d59c1_900x350.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看