Arahan "go get" boleh menarik atau mengemas kini pakej kod dan pakej bergantungnya dari jauh dengan bantuan alatan pengurusan kod, dan melengkapkan kompilasi dan pemasangan secara automatik. Perintah "go get" secara dinamik boleh mendapatkan pakej kod jauh Sebelum menggunakan arahan "go get", anda perlu memasang alat pengurusan kod yang sepadan dengan pakej jauh, seperti Git, SVN, HG, dll., dan a. nama pakej perlu disediakan dalam parameter.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Arahan go get boleh menarik atau mengemas kini pakej kod dan pakej bergantungnya dari jauh dengan bantuan alatan pengurusan kod dan melengkapkan kompilasi dan pemasangan secara automatik. Seluruh proses adalah semudah memasang aplikasi.
Arahan ini boleh mendapatkan pakej kod jauh secara dinamik pada masa ini, BitBucket, GitHub, Google Code dan Launchpad disokong. Sebelum menggunakan arahan go get, anda perlu memasang alat pengurusan kod yang sepadan dengan pakej jauh, seperti Git, SVN, HG, dll., dan memberikan nama pakej dalam parameter.
Arahan ini sebenarnya dibahagikan kepada dua langkah secara dalaman: langkah pertama ialah memuat turun pakej kod sumber dan langkah kedua ialah melaksanakan go install.
pergi dapatkan arahan - dapatkan kod, susun dan pasang dengan satu klik
hc@ubt:~$ go get github.com/hyper-carrot/go_lib/logging
arahan go get
boleh berdasarkan keperluan dan syarat sebenar Muat turun atau kemas kini pakej kod tertentu dan pakej bergantungnya daripada Internet, susun dan pasangkannya. Dalam contoh di atas, kami memuat turun projek (atau pakej kod) daripada tapak pengehosan kod terkenal Github dan memasangnya ke dalam ruang kerja pertama yang disertakan dalam pembolehubah persekitaran GOPATH. Pada masa yang sama, kami juga tahu bahawa laluan import pakej kod ini ialah github.com/hyper-carrot/go_lib/logging.
Secara amnya, untuk memisahkan kod kami sendiri dan kod pihak ketiga, kami akan menyediakan dua atau lebih ruang kerja. Kami kini mempunyai ruang kerja dengan laluan direktori /home/hc/golang/lib, dan ia adalah laluan direktori pertama dalam nilai GOPATH pembolehubah persekitaran. Ambil perhatian bahawa laluan yang terkandung dalam pembolehubah persekitaran GOPATH tidak boleh sama dengan nilai pembolehubah persekitaran GOROOT. Baiklah, jika kita menggunakan perintah go get
untuk memuat turun dan memasang pakej kod, maka pakej kod ini akan dipasang di ruang kerja di atas. Mari kita panggil ruang kerja ini sebagai ruang kerja Lib buat sementara waktu. Selepas kami menjalankan go get github.com/hyper-carrot/go_lib/logging
, pakej kod harus disimpan dalam direktori src tugas Lib dan telah dipasang dengan betul, seperti yang ditunjukkan di bawah:
/home/hc/golang/lib: bin/ pkg/ linux_386/ github.com/ hyper-carrot/ go_lib/ logging.a src/ github.com/ hyper-carrot/ go_lib/ logging/ ...
Sebaliknya, jika kita mahu Jika projek dimuat naik ke tapak web Github (atau tapak web pengehosan kod lain) dan digunakan oleh orang lain, maka kami harus menganggap projek itu sebagai pakej kod. Sebenarnya, kami telah menyebut sebabnya sebelum ini Perintah go get
akan menyimpan semua subdirektori dan fail kod sumber di bawah projek ke dalam direktori src ruang kerja pertama, dan semua subdirektori di bawah direktori src akan menjadi sebahagian kod tertentu atau semua. laluan import pakej. Dalam erti kata lain, kita harus menyimpan pakej subkod dan fail kod sumber terus dalam direktori projek, dan nama pakej yang diisytiharkan oleh fail kod sumber yang disimpan terus dalam direktori projek hendaklah sama dengan nama projek (melainkan ia adalah sumber arahan fail kod). Melakukan ini akan membolehkan orang lain menggunakan projek anda secara langsung selepas memuat turunnya daripada Github menggunakan perintah go get
.
Malah, tidak disyorkan untuk menggunakan terus laluan direktori akar projek sebagai laluan ruang kerja seperti projek goc2p. Sebab utama untuk melakukan ini adalah untuk memudahkan pembaca memahami struktur projek dan konsep ruang kerja bahasa Go, dan juga untuk membolehkan pembaca melihat struktur projek yang lain. Sudah tentu, jika projek anda menggunakan alat seperti gb, itu adalah perkara lain. Direktori akar projek sedemikian harus dianggap sebagai ruang kerja (tetapi anda tidak perlu menambahkannya pada pembolehubah persekitaran GOPATH). Ia harus dimuat turun oleh git clone
di suatu tempat di luar ruang kerja bahasa Go, dan bukannya menggunakan perintah go get
.
Analisis laluan import jauh
Malah, tindakan yang dilakukan oleh perintah go get
juga dipanggil import pakej kod jauh dan pakej kod dihantar kepada arahan ialah Parameter laluan import juga dipanggil laluan import jauh pakej kod. Perintah
go get
bukan sahaja boleh memuat turun pakej kod dari tapak pengehosan kod terkenal seperti Github, tetapi juga boleh menyemak daripada mana-mana sistem kawalan versi kod (Sistem Kawalan Versi dalam bahasa Inggeris, dirujuk sebagai VCS) yang disokong oleh pakej kod arahan. Mana-mana tapak pengehosan kod menyediakan perkhidmatan muat naik dan muat turun kod melalui satu atau lebih sistem kawalan versi kod. Jadi, secara lebih tegas, apa yang dilakukan oleh perintah go get
ialah menyemak/kemas kini pakej kod daripada repositori jauh sistem kawalan versi kod dan menyusun serta memasangnya.
Maklumat VCS yang disokong oleh arahan ini adalah seperti berikut:
Jadual 0-2 go get
VCS yang disokong oleh arahan
名称 | 主命令 | 说明 |
---|---|---|
Mercurial | hg | Mercurial是一种轻量级分布式版本控制系统,采用Python语言实现,易于学习和使用,扩展性强。 |
Git | git | Git最开始是Linux Torvalds为了帮助管理 Linux 内核开发而开发的一个开源的分布式版本控制软件。但现在已被广泛使用。它是被用来进行有效、高速的各种规模项目的版本管理。 |
Subversion | svn | Subversion是一个版本控制系统,也是第一个将分支概念和功能纳入到版本控制模型的系统。但相对于Git和Mercurial而言,它只算是传统版本控制系统的一员。 |
Bazaar | bzr | Bazaar是一个开源的分布式版本控制系统。但相比而言,用它来作为VCS的项目并不多。 |
go get
mesti mengetahui sistem kawalan versi dan URL gudang jauh yang sepadan dengan laluan import jauh pakej kod sebelum menyemak pakej kod.
Jika pakej kod sudah wujud dalam ruang kerja setempat, cebisan maklumat ini akan ditentukan secara langsung dengan menganalisis laluannya. Beberapa sistem kawalan versi yang disokong oleh perintah go get
mempunyai satu persamaan, iaitu, direktori metadata akan disimpan dalam direktori projek yang telah didaftarkan, dengan nama yang diawali dengan "" ditambah dengan nama arahan utamanya. Sebagai contoh, Git akan menambah subdirektori bernama ".git" pada direktori projek yang didaftar keluar. Oleh itu, adalah mudah untuk menentukan sistem kawalan versi yang digunakan oleh pakej kod. Selain itu, memandangkan pakej kod sudah wujud, kami hanya perlu mengemas kini pakej kod melalui arahan kemas kini sistem kawalan versi kod, jadi tidak perlu mengetahui URL gudang jauhnya. Untuk pakej kod yang sudah wujud dalam ruang kerja setempat, perintah go get
tidak akan melakukan muat turun berulang melainkan pakej kod dikemas kini secara paksa. Jika anda ingin mengemas kini pakej kod secara paksa, anda boleh menambah tag go get
apabila melaksanakan perintah -u
. Penanda ini akan diperkenalkan kemudian.
Jika pakej kod tidak wujud dalam ruang kerja tempatan, maklumat yang berkaitan hanya boleh diperolehi dengan menganalisis laluan import jauh pakej kod. Pertama, arahan go get
akan melakukan analisis statik pada laluan import jauh pakej kod. Untuk menjadikan proses analisis lebih mudah dan pantas, program arahan go get
telah pratetap maklumat beberapa tapak web pengehosan kod terkenal. Seperti yang ditunjukkan dalam jadual berikut:
Jadual 0-3 Maklumat tentang tapak pengehosan kod pratetap
名称 | 主域名 | 支持的VCS | 代码包远程导入路径示例 |
---|---|---|---|
Bitbucket | bitbucket.org | Git, Mercurial | bitbucket.org/user/project bitbucket.org/user/project/sub/directory |
GitHub | github.com | Git | github.com/user/project github.com/user/project/sub/directory |
Google Code Project Hosting | code.google.com | Git, Mercurial, Subversion | code.google.com/p/project code.google.com/p/project/sub/directory code.google.com/p/project.subrepository code.google.com/p/project.subrepository/sub/directory |
Launchpad | launchpad.net | Bazaar | launchpad.net/project launchpad.net/project/series launchpad.net/project/series/sub/directory launchpad.net/user/project/branch launchpad.net/user/project/branch/sub/directory |
IBM DevOps Services | hub.jazz.net | Git | hub.jazz.net/git/user/project hub.jazz.net/git/user/project/sub/directory |
一般情况下,代码包远程导入路径中的第一个元素就是代码托管网站的主域名。在静态分析的时候,go get
命令会将代码包远程导入路径与预置的代码托管站点的主域名进行匹配。如果匹配成功,则在对代码包远程导入路径的初步检查后返回正常的返回值或错误信息。如果匹配不成功,则会再对代码包远程导入路径进行动态分析。至于动态分析的过程,我就不在这里详细展开了。
如果对代码包远程导入路径的静态分析或/和动态分析成功并获取到对应的版本控制系统和远程仓库URL,那么go get
命令就会进行代码包检出或更新的操作。随后,go get
命令会在必要时以同样的方式检出或更新这个代码包的所有依赖包。
自定义代码包远程导入路径
如果你想把你编写的(被托管在不同的代码托管网站上的)代码包的远程导入路径统一起来,或者不希望让你的代码包中夹杂某个代码托管网站的域名,那么你可以选择自定义你的代码包远程导入路径。这种自定义的实现手段叫做“导入注释”。导入注释的写法示例如下:
package analyzer // import "hypermind.cn/talon/analyzer"
代码包analyzer
实际上属于我的一个网络爬虫项目。这个项目的代码被托管在了Github网站上。它的网址是:https://github.com/hyper-carrot/talon。如果用标准的导入路径来下载analyzer
代码包的话,命令应该这样写go get github.com/hyper-carrot/talon/analyzer
。不过,如果我们像上面的示例那样在该代码包中的一个源码文件中加入导入注释的话,这样下载它就行不通了。我们来看一看这个导入注释。
导入注释的写法如同一条代码包导入语句。不同的是,它出现在了单行注释符//
的右边,因此Go语言编译器会忽略掉它。另外,它必须出现在源码文件的第一行语句(也就是代码包声明语句)的右边。只有符合上述这两个位置条件的导入注释才是有效的。再来看其中的引号部分。被双引号包裹的应该是一个符合导入路径语法规则的字符串。其中,hypermind.cn
是我自己的一个域名。实际上,这也是用来替换掉我想隐去的代码托管网站域名及部分路径(这里是github.com/hyper-carrot
)的那部分。在hypermind.cn
右边的依次是我的项目的名称以及要下载的那个代码包的相对路径。这些与其标准导入路径中的内容都是一致的。为了清晰起见,我们再来做下对比。
github.com/hyper-carrot/talon/analyzer // 标准的导入路径 hypermind.cn /talon/analyzer // 导入注释中的导入路径
你想用你自己的域名替换掉标准导入路径中的哪部分由你自己说了算。不过一般情况下,被替换的部分包括代码托管网站的域名以及你在那里的用户ID就可以了。这足以达到我们最开始说的那两个目的。
虽然我们在talon项目中的所有代码包中都加入了类似的导入注释,但是我们依然无法通过go get hypermind.cn/talon/analyzer
命令来下载这个代码包。因为域名hypermind.cn
所指向的网站并没有加入相应的处理逻辑。具体的实现步骤应该是这样的:
编写一个可处理HTTP请求的程序。这里无所谓用什么编程语言去实现。当然,我推荐你用Go语言去做。
将这个处理程序与hypermind.cn/talon
这个路径关联在一起,并总是在作为响应的HTML文档的头中写入下面这行内容:
<meta name="go-import" content="hypermind.cn/talon git https://github.com/hyper-carrot/talon">
hypermind.cn/talon/analyzer熟悉HTML的读者都应该知道,这行内容会被视为HTML文档的元数据。它实际上go get
命令的文档中要求的写法。它的模式是这样的:
<meta name="go-import" content="import-prefix vcs repo-root">
实际上,content
属性中的import-prefix
的位置上应该填入我们自定义的远程代码包导入路径的前缀。这个前缀应该与我们的处理程序关联的那个路径相一致。而vcs
显然应该代表与版本控制系统有关的标识。还记得表0-2中的主命令列吗?这里的填入内容就应该该列中的某一项。在这里,由于talon项目使用的是Git,所以这里应该填入git
。至于repo-root
,它应该是与该处理程序关联的路径对应的Github网站的URL。在这里,这个路径是hypermind.cn/talon
,那么这个URL就应该是https://github.com/hyper-carrot/talon
。后者也是talon项目的实际网址。
好了,在我们做好上述处理程序之后,go get hypermind.cn/talon/analyzer
命令的执行结果就会是正确的。analyzer
代码包及其依赖包中的代码会被下载到GOPATH环境变量中的第一个工作区目录的src子目录中,然后被编译并安装。
注意,具体的代码包源码存放路径会是/home/hc/golang/lib/src/hypermind.cn/talon/analyzer。也就是说,存放路径(包括代码包源码文件以及相应的归档文件的存放路径)会遵循导入注释中的路径(这里是hypermind.cn/talon/analyzer
),而不是原始的导入路径(这里是github.com/hyper-carrot/talon/analyzer
)。另外,我们只需在talon项目的每个代码包中的某一个源码文件中加入导入注释,但这些导入注释中的路径都必须是一致的。在这之后,我们就只能使用hypermind.cn/talon/
作为talon项目中的代码包的导入路径前缀了。一个反例如下:
hc@ubt:~$ go get github.com/hyper-carrot/talon/analyzer package github.com/hyper-carrot/talon/analyzer: code in directory /home/hc/golang/lib/src/github.com/hyper-carrot/talon/analyzer expects import "hypermind.cn/talon/analyzer"
与自定义的代码包远程导入路径有关的内容我们就介绍到这里。从中我们也可以看出,Go语言为了让使用者的项目与代码托管网站隔离所作出的努力。只要你有自己的网站和一个不错的域名,这就很容易搞定并且非常值得。这会在你的代码包的使用者面前强化你的品牌,而不是某个代码托管网站的。当然,使你的代码包导入路径整齐划一是最直接的好处。
OK,言归正传,我下面继续关注go get
这个命令本身。
命令特有标记
go get
命令可以接受所有可用于go build
命令和go install
命令的标记。这是因为go get
命令的内部步骤中完全包含了编译和安装这两个动作。另外,go get
命令还有一些特有的标记,如下表所示:
表0-4 go get
命令的特有标记说明
标记名称 | 标记描述 |
---|---|
-d | 让命令程序只执行下载动作,而不执行安装动作。 |
-f | 仅在使用-u 标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查。如果下载并安装的代码包所属的项目是你从别人那里Fork过来的,那么这样做就尤为重要了。 |
-fix | 让命令程序在下载代码包后先执行修正动作,而后再进行编译和安装。 |
-insecure | 允许命令程序使用非安全的scheme(如HTTP)去下载指定的代码包。如果你用的代码仓库(如公司内部的Gitlab)没有HTTPS支持,可以添加此标记。请在确定安全的情况下使用它。 |
-t | 让命令程序同时下载并安装指定的代码包中的测试源码文件中依赖的代码包。 |
-u | 让命令利用网络来更新已有代码包及其依赖包。默认情况下,该命令只会从网络上下载本地不存在的代码包,而不会更新已有的代码包。 |
为了更好的理解这几个特有标记,我们先清除Lib工作区的src目录和pkg目录中的所有子目录和文件。现在我们使用带有-d
标记的go get
命令来下载同样的代码包:
hc@ubt:~$ go get -d github.com/hyper-carrot/go_lib/logging
现在,让我们再来看一下Lib工作区的目录结构:
/home/hc/golang/lib: bin/ pkg/ src/ github.com/ hyper-carrot/ go_lib/ logging/ ...
我们可以看到,go get
命令只将代码包下载到了Lib工作区的src目录,而没有进行后续的编译和安装动作。这个加入-d
标记的结果。
再来看-fix
标记。我们知道,绝大多数计算机编程语言在进行升级和演进过程中,不可能保证100%的向后兼容(Backward Compatibility)。在计算机世界中,向后兼容是指在一个程序或者代码库在更新到较新的版本后,用旧的版本程序创建的软件和系统仍能被正常操作或使用,或在旧版本的代码库的基础上编写的程序仍能正常编译运行的能力。Go语言的开发者们已想到了这点,并提供了官方的代码升级工具——fix
。fix
工具可以修复因Go语言规范变更而造成的语法级别的错误。关于fix
工具,我们将放在本节的稍后位置予以说明。
假设我们本机安装的Go语言版本是1.5,但我们的程序需要用到一个很早之前用Go语言的0.9版本开发的代码包。那么我们在使用go get
命令的时候可以加入-fix
标记。这个标记的作用是在检出代码包之后,先对该代码包中不符合Go语言1.5版本的语言规范的语法进行修正,然后再下载它的依赖包,最后再对它们进行编译和安装。
标记-u
的意图和执行的动作都比较简单。我们在执行go get
命令时加入-u
标记就意味着,如果在本地工作区中已存在相关的代码包,那么就是用对应的代码版本控制系统的更新命令更新它,并进行编译和安装。这相当于强行更新指定的代码包及其依赖包。我们来看如下示例:
hc@ubt:~$ go get -v github.com/hyper-carrot/go_lib/logging
因为我们在之前已经检出并安装了这个代码包,所以我们执行上面这条命令后什么也没发生。还记得加入标记-v
标记意味着会打印出被构建的代码包的名字吗?现在我们使用标记-u
来强行更新代码包:
hc@ubt:~$ go get -v -u github.com/hyper-carrot/go_lib/logging github.com/hyper-carrot/go_lib (download)
其中,“(download)”后缀意味着命令从远程仓库检出或更新了该行显示的代码包。如果我们要查看附带-u
的go get
命令到底做了些什么,还可以加上一个-x
标记,以打印出用到的命令。读者可以自己试用一下它。
智能的下载
命令go get
还有一个很值得称道的功能。在使用它检出或更新代码包之后,它会寻找与本地已安装Go语言的版本号相对应的标签(tag)或分支(branch)。比如,本机安装Go语言的版本是1.x,那么go get
命令会在该代码包的远程仓库中寻找名为“go1”的标签或者分支。如果找到指定的标签或者分支,则将本地代码包的版本切换到此标签或者分支。如果没有找到指定的标签或者分支,则将本地代码包的版本切换到主干的最新版本。
前面我们说在执行go get
命令时也可以加入-x
标记,这样可以看到go get
命令执行过程中所使用的所有命令。不知道读者是否已经自己尝试了。下面我们还是以代码包github.com/hyper-carrot/go_lib
为例,并且通过之前示例中的命令的执行此代码包已经被检出到本地。这时我们再次更新这个代码包:
hc@ubt:~$ go get -v -u -x github.com/hyper-carrot/go_lib github.com/hyper-carrot/go_lib (download) cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git fetch cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git show-refcd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git checkout origin/masterWORK=/tmp/go-build034263530
在上述示例中,go get
命令通过git fetch
命令将所有远程分支更新到本地,而后有用git show-ref
命令列出本地和远程仓库中记录的代码包的所有分支和标签。最后,当确定没有名为“go1”的标签或者分支后,go get
命令使用git checkout origin/master
命令将代码包的版本切换到主干的最新版本。下面,我们在本地增加一个名为“go1”的标签,看看go get
命令的执行过程又会发生什么改变:
hc@ubt:~$ cd ~/golang/lib/src/github.com/hyper-carrot/go_lib hc@ubt:~/golang/lib/src/github.com/hyper-carrot/go_lib$ git tag go1 hc@ubt:~$ go get -v -u -x github.com/hyper-carrot/go_lib github.com/hyper-carrot/go_lib (download) cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git fetch cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git show-ref cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git show-ref tags/go1 origin/go1 cd /home/hc/golang/lib/src/github.com/hyper-carrot/go_lib git checkout tags/go1 WORK=/tmp/go-build636338114
将这两个示例进行对比,我们会很容易发现它们之间的区别。第二个示例的命令执行过程中使用git show-ref
查看所有分支和标签,当发现有匹配的信息又通过git show-ref tags/go1 origin/go1
命令进行精确查找,在确认无误后将本地代码包的版本切换到标签“go1”之上。
arahan go get
ini sangat berguna. Apabila kod kami secara langsung atau tidak langsung bergantung pada beberapa pakej kod yang dibangunkan untuk berbilang versi bahasa Go pada masa yang sama, versi yang betul boleh diperiksa secara automatik. Ia juga boleh dikatakan bahawa perintah go get
mempunyai fungsi tertentu terbina dalam untuk pengurusan pergantungan berbilang versi pakej kod.
Di sini, saya memperkenalkan kepada anda cara menggunakan arahan go get
. Perintah go get
, seperti dua arahan yang diperkenalkan sebelum ini, adalah alat bantu yang sangat diperlukan apabila kami menulis program bahasa Go dan membina projek bahasa Go.
[Cadangan berkaitan: Pergi tutorial video, Pengajaran pengaturcaraan]
Atas ialah kandungan terperinci Apakah kegunaan arahan go get?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!