Julia 擴(kuò)展包

2018-08-12 21:26 更新

擴(kuò)展包

Julia 內(nèi)置了一個(gè)包管理系統(tǒng),可以用這個(gè)系統(tǒng)來(lái)完成包的管理,當(dāng)然,你也可以用你的操作系統(tǒng)自帶的,或者從源碼編譯。

你可以在 http://pkg.julialang.org 找到所有已注冊(cè)(一種發(fā)布包的機(jī)制)的包的列表。

所有的包管理命令都包含在 Pkg 這個(gè) module 里面,Julia 的 Base install 引入了 Pkg 。

擴(kuò)展包狀態(tài)

可以通過(guò) Pkg.status() 這個(gè)方程,打印出一個(gè)你所有安裝的包的總結(jié)。

剛開始的時(shí)候,你沒(méi)有安裝任何包::

    julia> Pkg.status()
    INFO: Initializing package repository /Users/stefan/.julia/v0.3
    INFO: Cloning METADATA from git://github.com/JuliaLang/METADATA.jl
    No packages installed.

當(dāng)你第一次運(yùn)行 Pkg 的一個(gè)命令時(shí), 你的包目錄(所有的包被安裝在一個(gè)統(tǒng)一的目錄下)會(huì)自動(dòng)被初始化,因?yàn)?Pkg 希望有這樣一個(gè)目錄,這個(gè)目錄的信息被包含于 Pkg.status() 中。

這里是一個(gè)簡(jiǎn)單的,已經(jīng)有少量被安裝的包的例子:

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.8
     - UTF16                         0.2.0
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.6

這些包,都是已注冊(cè)了的版本,并且通過(guò) Pkg 管理。

安裝了的包可以是一個(gè)更復(fù)雜的"狀態(tài)",通過(guò)"注釋"來(lái)表明正確的版本;當(dāng)我們遇到這些“狀態(tài)”和“注釋”時(shí)我們會(huì)解釋的。

為了編程需要,Pkg.installed() 返回一個(gè)字典,這個(gè)字典對(duì)應(yīng)了安裝了的包的名字和其現(xiàn)在使用的版本:

    julia> Pkg.installed()

    ["Distributions"=>v"0.2.8","Stats"=>v"0.2.6","UTF16"=>v"0.2.0","NumericExtensions"=>v"0.2.17"]

添加和刪除擴(kuò)展包

Julia 的包管理有一點(diǎn)不同這是因?yàn)樗巧皇潜匾?。這意味著你告訴它你想要什么,它就會(huì)知道安裝什么版本(或移除)來(lái)有選擇地滿足那些需求 - 最低程度下地。所以不是安裝一個(gè)包,你只是添加它到需求列表然后“解決”什么需要被安裝。特別的,這意味著如果一些包因?yàn)樗荒阆胍獤|西的前一個(gè)版本所需要而已經(jīng)被安裝,而且一個(gè)更新的版本不再有那個(gè)需求了,更新將真正移除那個(gè)包。

你的包需求在文件 ~/.julia/v0.3/REQUIRE 中。你可以手動(dòng)編輯這個(gè)文件,然后調(diào)用 Pkg.resolve() 方法來(lái)安裝,升級(jí)或者移除包來(lái)有選擇地滿足需求,或者你可以做 Pkg.edit(),它將在你的編輯器中打開 REQUIRE(通過(guò) EDITOR 或者 VISUAL 環(huán)境變量配置),然后之后自動(dòng)調(diào)用 Pkg.resolve(),如果有必要的話。如果你僅僅想要添加或者移除一個(gè)單一包的需求,你也可以使用非交互的 Pkg.addPkg.rm 命令,它添加或移除一個(gè)單一的需求來(lái) REQUIRE,然后調(diào)用 Pkg.resolve()。

你可以用 Pkg.add 函數(shù)添加一個(gè)包到需求列表,這個(gè)包和所有它所依賴的包都將被安裝:

    julia> Pkg.status()
    No packages installed.

    julia> Pkg.add("Distributions")
    INFO: Cloning cache of Distributions from git://github.com/JuliaStats/Distributions.jl.git
    INFO: Cloning cache of NumericExtensions from git://github.com/lindahua/NumericExtensions.jl.git
    INFO: Cloning cache of Stats from git://github.com/JuliaStats/Stats.jl.git
    INFO: Installing Distributions v0.2.7
    INFO: Installing NumericExtensions v0.2.17
    INFO: Installing Stats v0.2.6
    INFO: REQUIRE updated.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.7
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.6

這所做的事情首先是添加 Distributions 到你的 ~/.julia/v0.3/REQUIRE 文件:

    $ cat ~/.julia/v0.3/REQUIRE
    Distributions

然后它使用這些新的需求運(yùn)行 Pkg.resolve(),它導(dǎo)向了 Distributions 包應(yīng)該被安裝因?yàn)樗潜匦璧亩覜](méi)有被安裝的結(jié)論。正如之前所聲明的,你可以通過(guò)手動(dòng)編輯你的 ~/.julia/v0.3/REQUIRE 文件完成相同的事情然后自己運(yùn)行 Pkg.resolve()。

    $ echo UTF16 >> ~/.julia/v0.3/REQUIRE

    julia> Pkg.resolve()
    INFO: Cloning cache of UTF16 from git://github.com/nolta/UTF16.jl.git
    INFO: Installing UTF16 v0.2.0

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.7
     - UTF16                         0.2.0
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.6

這和調(diào)用 Pkg.add("UTF16")功能相同,除了 Pkg.add 直到在安裝完成之后才改變 REQUIRE,所以如果有問(wèn)題的話,REQUIRE 將被剩下,正如在調(diào)用 Pkg.add 之前。REQUIRE 文件的格式在 Requirements Specification中被描述;它允許在其他事物中獲得特定包版本的范圍。

當(dāng)你決定你不想再擁有一個(gè)包,你可以使用 Pkg.rm 來(lái)從 REQUIRE 文件移除它的需求:

    julia> Pkg.rm("Distributions")
    INFO: Removing Distributions v0.2.7
    INFO: Removing Stats v0.2.6
    INFO: Removing NumericExtensions v0.2.17
    INFO: REQUIRE updated.

    julia> Pkg.status()
    Required packages:
     - UTF16                         0.2.0

    julia> Pkg.rm("UTF16")
    INFO: Removing UTF16 v0.2.0
    INFO: REQUIRE updated.

    julia> Pkg.status()
    No packages installed.

再一次,這和編輯 REQUIRE 文件來(lái)移除有著包名的那一行然后運(yùn)行 Pkg.resolve()來(lái)更改安裝包的集合來(lái)匹配相類似。盡管 Pkg.addPkg.rm 對(duì)于添加和移除單個(gè)包的需求來(lái)說(shuō)是方便的,當(dāng)你想要添加或移除多個(gè)包時(shí),你可以調(diào)用 Pkg.edit()來(lái)手動(dòng)地改變 REQUIRE 的內(nèi)容然后根據(jù)情況更新你的包。Pkg.edit()不回滾 REQUIRE 的內(nèi)容如果 Pkg.resolve()失效 - 不如說(shuō),你不得不再一次運(yùn)行 Pkg.edit()來(lái)修改文檔內(nèi)容。

因?yàn)榘芾韮?nèi)部使用 git 來(lái)管理包 git 倉(cāng)庫(kù),當(dāng)運(yùn)行 Pkg.add 時(shí),用戶可能會(huì)碰上協(xié)議的問(wèn)題(比如在一個(gè)防火墻后)。接下來(lái)的命令可在命令行中被運(yùn)行來(lái)告訴 git 當(dāng)克隆倉(cāng)庫(kù)時(shí)使用 'https' 而不是 'git' 協(xié)議。

    git config --global url."https://".insteadOf git://

安裝未注冊(cè)的擴(kuò)展包

Julia 包僅僅是 git 倉(cāng)庫(kù),在任何 git 支持的協(xié)議上都是可克隆的,而且包含遵循特定布局慣例的 Julia 代碼。官方的 Julia 包在 METADATA.jl 倉(cāng)庫(kù)中注冊(cè),在可以著名的地方可獲得。在之前的段落中,Pkg.addPkg.rm 命令和注冊(cè)的包交互,但是包管理也能安裝并使用未注冊(cè)的包。為了安裝未注冊(cè)的包,使用 Pkg.clone(url),在那里 url 是一個(gè)包能被克隆的 git URL:

    julia> Pkg.clone("git://example.com/path/to/Package.jl.git")
    INFO: Cloning Package from git://example.com/path/to/Package.jl.git
    Cloning into 'Package'...
    remote: Counting objects: 22, done.
    remote: Compressing objects: 100% (10/10), done.
    remote: Total 22 (delta 8), reused 22 (delta 8)
    Receiving objects: 100% (22/22), 2.64 KiB, done.
    Resolving deltas: 100% (8/8), done.

按照慣例,Julia 倉(cāng)庫(kù)用一個(gè) .jl 的結(jié)尾命名(附加的 .git 指示了一個(gè)“裸” git 倉(cāng)庫(kù)),這防止它們和其他語(yǔ)言的倉(cāng)庫(kù)碰撞,也使得 Julia 包在搜索引擎中方便找到。當(dāng)包在你的 .julia/v0.3 目錄下安裝時(shí),然而,擴(kuò)展是多余的,所以我們將它留下。

如果未注冊(cè)的包在它們的資源樹的頂部包含 REQUIRE 文件,那這個(gè)文件將被用來(lái)決定未注冊(cè)的包依賴于哪些注冊(cè)的包,而且它們將自動(dòng)被安裝。未注冊(cè)的包和注冊(cè)的包一樣,具有相同版本的解決邏輯,所以安裝過(guò)的包版本將在必要時(shí)調(diào)整來(lái)滿足注冊(cè)過(guò)的和未注冊(cè)過(guò)的包的需求。

[1] 官方的包集在 https://github.com/JuliaLang/METADATA.jl,但是個(gè)人和組織能簡(jiǎn)單地使用一個(gè)不同的元數(shù)據(jù)倉(cāng)庫(kù)。這允許包可以自動(dòng)安裝的控制。我們可以僅允許審計(jì)通過(guò)的和批準(zhǔn)的包版本,并使得私人的包和 fork 可被獲得。

更新擴(kuò)展包

當(dāng)包開發(fā)者發(fā)布你正在使用的新的注冊(cè)的包版本時(shí),你當(dāng)然,想要新的版本。為了獲得最新和最棒的包版本,只要 Pkg.update():

    julia> Pkg.update()
    INFO: Updating METADATA...
    INFO: Computing changes...
    INFO: Upgrading Distributions: v0.2.8 => v0.2.10
    INFO: Upgrading Stats: v0.2.7 => v0.2.8

更新包的第一步是將新的改變放入 ~/.julia/v0.3/METADATA 并看看是否有新的注冊(cè)包版本已經(jīng)被發(fā)布了。在這之后,Pkg.update()通過(guò)從包的上游庫(kù) pull 一些更改會(huì)更新在一個(gè)分支上被檢查且不 dirty(比如,在 git 下沒(méi)有對(duì)文件更改)的更新包。上游的改變僅僅在如果沒(méi)有合并或重定基地址是有必要的情況下應(yīng)用 - 比如,如果分支是 "fast-forwarded"。如果分支不是 fast-forwarded,就假設(shè)你正在使用它而且將自己更改倉(cāng)庫(kù)。

最后,更新的過(guò)程重新計(jì)算了一個(gè)最佳的包版本的集合來(lái)安裝以滿足你頂級(jí)的需求和 “fix” 包的需求。包被認(rèn)為是 fixed 如果它是下面幾條之一:

1.未注冊(cè):包不在 METADATA 中 - 你用 Pkg.clone 安裝過(guò)它。 2.被檢出:包倉(cāng)庫(kù)在一個(gè)開發(fā)分支上。 3.Dirty:在倉(cāng)庫(kù)中對(duì)文件進(jìn)行過(guò)了修改。

如果這些中的任何一項(xiàng)出現(xiàn),包管理者不能自由地更改安裝好的包版本,所以它的需求必須被滿足,無(wú)論它所選擇的其他包版本是怎樣的。在 ~/.julia/v0.3/REQUIRE 中的頂層需求的組合和修改過(guò)的包的需求被用來(lái)決定應(yīng)該安裝什么。

Checkout, Pin and Free

你可能想要使用包的 master 版本而不是注冊(cè)版本中的一個(gè)。在 master 上可能有修改或功能,它們是你所需要的且沒(méi)有在任何注冊(cè)版本上發(fā)布,或者你可能是一個(gè)包的開發(fā)者且想要改變 master 或一些其他的開發(fā)分支。在這些例子中,你能通過(guò) Pkg.checkout(pkg)來(lái)檢查 pkgPkg.checkout(pkg,branch)master 分支以檢查一些其他的分支:

    julia> Pkg.add("Distributions")
    INFO: Installing Distributions v0.2.9
    INFO: Installing NumericExtensions v0.2.17
    INFO: Installing Stats v0.2.7
    INFO: REQUIRE updated.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.7

    julia> Pkg.checkout("Distributions")
    INFO: Checking out Distributions master...
    INFO: No packages to install, update or remove.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9+             master
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.7

一旦在用 Pkg.add 安裝 Distributions 之后,在寫完的同時(shí)它就位于最新的注冊(cè)版本上 - 0.2.9。然后在運(yùn)行 Pkg.checkout("Distributions")之后,你可以從 Pkg.status()的輸出中看到 Distributions 比起 0.2.9 在一個(gè)未注冊(cè)的版本上更佳。由 “pseudo-version” 數(shù)字 0.2.9+ 指示。

當(dāng)你檢查一個(gè)未注冊(cè)的包版本時(shí),包倉(cāng)庫(kù)中 REQUIRE 文件的副本地位高于任何其他在 METADATA 中注冊(cè)的需求,所以開發(fā)者保持這個(gè)文件的正確性和及時(shí)性是很重要的,這反映了目前包版本的真正需求。如果在包倉(cāng)庫(kù)中的 REQUIRE 文件是不正確的或者遺失了,當(dāng)包被檢出時(shí)依賴性可能會(huì)被移除。這個(gè)文件也被用來(lái)填充新發(fā)布的包版本,如果你使用了 Pkg 為此提供的 API(在下面描述)。

當(dāng)你決定你不再想要讓一個(gè)包在分支上被檢出,你能使用 Pkg “釋放”它回到包管理者的控制之下。

    julia> Pkg.free("Distributions")
    INFO: Freeing Distributions...
    INFO: No packages to install, update or remove.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.7

在這之后,因?yàn)榘窃谝粋€(gè)注冊(cè)版本之上而且不在一個(gè)分支上,它的版本將被更新作為包的注冊(cè)版本被發(fā)布。

如果你想要在一個(gè)指定的版本上 pin 一個(gè)包以使調(diào)用 Pkg.update()不會(huì)改變包所在的版本,你可以使用 Pkg.pin 功能:

    julia> Pkg.pin("Stats")
    INFO: Creating Stats branch pinned.47c198b1.tmp

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.7              pinned.47c198b1.tmp

在這之后,Stats 包將以版本 0.2.7 保持 pin 的狀態(tài) - 或者更具體地說(shuō),在提交 47c198b1時(shí),但是自從版本被永久地和一個(gè)給定的 git hash 連接后,這就一樣了。Pkg.pin 通過(guò)為你想要 pin 包的提交創(chuàng)建一個(gè) throw-away 分支而運(yùn)行。默認(rèn)下,它在當(dāng)前的提交下 pin 了一個(gè)包,但是你能通過(guò)傳遞第二個(gè)參數(shù)選擇一個(gè)不同的版本:

    julia> Pkg.pin("Stats",v"0.2.5")
    INFO: Creating Stats branch pinned.1fd0983b.tmp
    INFO: No packages to install, update or remove.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.5              pinned.1fd0983b.tmp

現(xiàn)在 Stats 包在提交 1fd0983b 時(shí)被 pin 了,它和 0.2.5 版本相一致。當(dāng)你決定 “unpin” 一個(gè)包且讓包管理者再一次更新它時(shí),你可以使用 Pkg.free 就像你想要離開任何分支一樣:

    julia> Pkg.free("Stats")
    INFO: Freeing Stats...
    INFO: No packages to install, update or remove.

    julia> Pkg.status()
    Required packages:
     - Distributions                 0.2.9
    Additional packages:
     - NumericExtensions             0.2.17
     - Stats                         0.2.7

Julia 的包管理者被設(shè)計(jì)以讓當(dāng)你有一個(gè)包需要安裝時(shí),你就可以查看它的源代碼和完整的開發(fā)歷史。你也可以對(duì)包做出更改,使用 git 提交它們,并能簡(jiǎn)單地作出修改和增強(qiáng)。相類似的,系統(tǒng)被設(shè)計(jì)以讓如果你想要?jiǎng)?chuàng)建一個(gè)新的包,這么做最簡(jiǎn)單的方法就是在由包管理者提供的基礎(chǔ)設(shè)施內(nèi)部。

[2]:不在分支上的包也將被標(biāo)記為 dirty,如果你在倉(cāng)庫(kù)中作出改變,但是那是一件比較少見的事。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)