ฉันจะนำเข้าแพ็คเกจเวอร์ชันเฉพาะโดยใช้ go get ได้อย่างไร


109

มาจากNodeสภาพแวดล้อมที่ฉันเคยติดตั้งเวอร์ชันเฉพาะของผู้จำหน่าย lib ลงในโฟลเดอร์โครงการ ( node_modules) โดยบอกnpmให้ติดตั้ง lib เวอร์ชันนั้นจากpackage.jsonหรือแม้แต่โดยตรงจากคอนโซลเช่น:

$ npm install express@4.0.0

จากนั้นฉันเคยนำเข้าเวอร์ชันของแพ็คเกจนั้นในโครงการของฉันด้วย:

var express = require('express');

goตอนนี้ผมต้องการที่จะทำสิ่งเดียวกันกับ ฉันจะทำเช่นนั้นได้อย่างไร? เป็นไปได้ไหมที่จะติดตั้งแพ็คเกจเวอร์ชันเฉพาะ ถ้าใช้แบบรวมศูนย์$GOPATHฉันจะนำเข้าเวอร์ชันหนึ่งแทนที่จะเป็นเวอร์ชันอื่นได้อย่างไร

ฉันจะทำสิ่งนี้:

$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2

แต่แล้วฉันจะสร้างความแตกต่างระหว่างการนำเข้าได้อย่างไร


4
คุณไม่ได้go getเป็นเครื่องมือที่ถูกต้องหากคุณต้องการพฤติกรรมนี้ คุณสามารถ Google เพื่อหาแนวทางแก้ไขปัญหาเฉพาะของคุณ
Wessie


stackoverflow.com/questions/30188499/…สิ่งนี้ก็มีประโยชน์เช่นกัน
earlonrails

สำหรับ Go 1.11 ขึ้นไปโปรดดู Go Modules: stackoverflow.com/questions/53682247/…
Everton

คำตอบ:


47

Go 1.11 จะมีคุณสมบัติที่เรียกว่า go module และคุณสามารถเพิ่มการพึ่งพาด้วยเวอร์ชันได้ ทำตามขั้นตอนเหล่านี้:

go mod init .
go mod edit -require github.com/wilk/uuid@0.0.1` 
go get -v -t ./...   
go build
go install 

ข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนั้น - https://github.com/golang/go/wiki/Modules


4
จะทำอย่างไรกับ go get only? ฉันต้องการติดตั้ง global go binary เป็นเวอร์ชันเฉพาะ
James Tan

7
@JamesTan go get github.com/wilk/uuid@0.0.1(with GO111MODULE=on)
Neil Conway

7
คำถามที่ใช้ไม่ได้go get go mod
Bernardo Loureiro

40

จริงๆไม่มีใครแปลกใจที่ได้กล่าวถึงgopkg.in

gopkg.inเป็นบริการที่มี Wrapper (เปลี่ยนเส้นทาง) ที่ให้คุณแสดงเวอร์ชันเป็น URL ของ repo โดยไม่ต้องสร้าง repos จริงๆ เช่นgopkg.in/yaml.v1เทียบกับgopkg.in/yaml.v2แม้ว่าทั้งคู่จะอาศัยอยู่ที่https://github.com/go-yaml/yaml

สิ่งนี้ไม่สมบูรณ์แบบหากผู้เขียนไม่ปฏิบัติตามแนวทางปฏิบัติในการกำหนดเวอร์ชันที่เหมาะสม (โดยการเพิ่มหมายเลขเวอร์ชันเมื่อทำลายความเข้ากันได้แบบย้อนกลับ) แต่ใช้ได้กับสาขาและแท็ก


5
ฉันชอบ (และใช้) gopkg แต่การกำหนดเวอร์ชันทำงานไม่ถูกต้องกับแพ็คเกจย่อย สิ่งที่ต้องระวัง
Alec Thomas

gopkg.in ไม่ได้รับการทดสอบอย่างสมบูรณ์ใน git เวอร์ชันเก่าดังนั้นจึงทำงานไม่ถูกต้องกับ git <v1.9
BMW

นอกจากนี้ยังใช้งานได้กับเวอร์ชันหลักเท่านั้น ไม่สามารถรับประกันการสร้างที่ทำซ้ำได้
CAFxX

26

คุณสามารถใช้git checkoutเพื่อรับเวอร์ชันเฉพาะและสร้างโปรแกรมของคุณโดยใช้เวอร์ชันนี้

ตัวอย่าง:

export GOPATH=~/
go get github.com/whateveruser/whateverrepo
cd ~/src/github.com/whateveruser/whateverrepo
git tag -l
# supose tag v0.0.2 is correct version
git checkout tags/v0.0.2
go run whateverpackage/main.go

วิธีแก้ปัญหาคือการเข้าเช็คเอาต์และไปติดตั้ง
ptman

@ aliaksei-maniuk ให้ทางออกที่ดีกว่าแก่เรา ใช้https://github.com/golang/dep
JoãoParaná

15

Glideเป็นการจัดการแพ็คเกจที่ยอดเยี่ยมสำหรับ Go โดยเฉพาะอย่างยิ่งถ้าคุณมาจาก Node's npm หรือ Rust's cargo

มันทำงานใกล้เคียงกับคุณสมบัติผู้ขายใหม่ของ Godep ใน 1.6 แต่เป็นวิธีที่ง่ายกว่า การอ้างอิงและเวอร์ชันของคุณถูก "ล็อก" ภายในไดเร็กทอรี projectdir / vendor ของคุณโดยไม่ต้องอาศัย GOPATH

ติดตั้งด้วยเบียร์ (OS X)

$ brew install glide

เริ่มต้นไฟล์ glide.yaml (คล้ายกับ package.json) นอกจากนี้ยังจับแพ็คเกจที่นำเข้าที่มีอยู่ในโครงการของคุณจาก GOPATH แล้วคัดลอกไปยังผู้จัดจำหน่าย / ไดเรกทอรีของโครงการ

$ glide init

รับแพ็คเกจใหม่

$ glide get vcs/namespace/package

อัปเดตและล็อกเวอร์ชันของแพ็กเกจ สิ่งนี้จะสร้างไฟล์ glide.lock ในไดเร็กทอรีโปรเจ็กต์ของคุณเพื่อล็อกเวอร์ชัน

$ glide up

ฉันลองร่อนและใช้มันอย่างมีความสุขกับโครงการปัจจุบันของฉัน


1
เพื่อความสมบูรณ์นี่คือเว็บไซต์สำหรับ glide: glide.sh และนี่คือ repo: github.com/Masterminds/glide
Michael Franzl

น่าเสียดายที่ Glide ไม่ "ใช้งานอยู่" อีกต่อไปในหน้า github พวกเขาแนะนำให้ย้ายไปที่การจัดการแพ็คเกจอย่างเป็นทางการ (ไปที่โมดูลแล้ว)
damoiser

13

อัปเดต 18-11-23 : จาก Go 1.11 mod เป็นการทดลองอย่างเป็นทางการ โปรดดูคำตอบของ @krish
อัปเดต 19-01-01 : จาก Go 1.12 mod ยังคงเป็นการทดลองอย่างเป็นทางการ เริ่มต้นใน Go 1.13 โหมดโมดูลจะเป็นค่าเริ่มต้นสำหรับการพัฒนาทั้งหมด
อัปเดต 19-10-17 : จาก Go 1.13 mod เป็นตัวจัดการแพ็คเกจอย่างเป็นทางการ

https://blog.golang.org/using-go-modules

คำตอบเก่า:

คุณสามารถตั้งค่าโดยรุ่นอย่างเป็นทางการDEP

dep ensure --add github.com/gorilla/websocket@1.2.0

3
คำถามที่ใช้ไม่ได้go get dep
Bernardo Loureiro

11

จาก Go 1.5 มี"การทดสอบผู้ขาย"ที่ช่วยคุณจัดการการอ้างอิง ตั้งแต่ Go 1.6 นี่ไม่ใช่การทดลองอีกต่อไป เอาใจใส่ยังบางตัวเลือกอื่น ๆ ในวิกิพีเดียไป .

แก้ไข: ตามที่กล่าวไว้ในคำตอบนี้ gopkg.inเป็นตัวเลือกที่ดีสำหรับการตรึง github-depdencies ก่อน 1.5


9

depเป็นการทดลองอย่างเป็นทางการสำหรับการจัดการการพึ่งพาสำหรับภาษา Go ต้องใช้ Go 1.8 หรือใหม่กว่าในการคอมไพล์

ในการเริ่มจัดการการอ้างอิงโดยใช้depให้รันคำสั่งต่อไปนี้จากไดเร็กทอรีรูทของโปรเจ็กต์ของคุณ:

dep init

หลังจากเรียกใช้ไฟล์สองไฟล์จะถูกสร้างขึ้น: Gopkg.toml("manifest") Gopkg.lockและแพ็คเกจที่จำเป็นจะถูกดาวน์โหลดลงในvendorไดเร็กทอรี

สมมติว่าคุณมีโครงการที่ใช้github.com/gorilla/websocketแพ็คเกจ depจะสร้างไฟล์ต่อไปนี้:

Gopkg.toml

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
#   name = "github.com/user/project"
#   version = "1.0.0"
#
# [[constraint]]
#   name = "github.com/user/project2"
#   branch = "dev"
#   source = "github.com/myfork/project2"
#
# [[override]]
#  name = "github.com/x/y"
#  version = "2.4.0"


[[constraint]]
  name = "github.com/gorilla/websocket"
  version = "1.2.0"

Gopkg.lock

# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.


[[projects]]
  name = "github.com/gorilla/websocket"
  packages = ["."]
  revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
  version = "v1.2.0"

[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "941e8dbe52e16e8a7dff4068b7ba53ae69a5748b29fbf2bcb5df3a063ac52261"
  solver-name = "gps-cdcl"
  solver-version = 1

มีคำสั่งที่ช่วยให้คุณอัปเดต / ลบ / ฯลฯ แพ็คเกจโปรดดูข้อมูลเพิ่มเติมเกี่ยวกับrepo github อย่างเป็นทางการของdep(เครื่องมือจัดการการพึ่งพาสำหรับ Go)


7

ทุกวันนี้คุณสามารถใช้go getมันได้ คุณสามารถดึงการอ้างอิงของคุณโดยแท็กเวอร์ชันสาขาหรือแม้แต่การคอมมิต

go get github.com/someone/some_module@master
go get github.com/someone/some_module@v1.1.0
go get github.com/someone/some_module@commit_hash

รายละเอียดเพิ่มเติมที่นี่ - จะชี้ Go module dependency ใน go.mod ไปยังคอมมิตล่าสุดใน repo ได้อย่างไร?

Go getจะติดตั้งไบนารีเช่นเดียวกับที่ระบุไว้ในเอกสารประกอบ -

Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.

(จากhttps://golang.org/cmd/go/ )


4

go get คือ Go package manager มันทำงานในลักษณะที่กระจายอำนาจอย่างสมบูรณ์และการค้นพบแพ็คเกจยังคงเป็นไปได้อย่างไรหากไม่มีที่เก็บแพ็กเกจส่วนกลาง

นอกเหนือจากการค้นหาและดาวน์โหลดแพ็กเกจบทบาทสำคัญอื่น ๆ ของตัวจัดการแพ็กเกจคือการจัดการแพ็กเกจเดียวกันหลายเวอร์ชัน Go ใช้แนวทางที่น้อยที่สุดและเป็นประโยชน์ที่สุดสำหรับผู้จัดการแพ็คเกจใด ๆ ไม่มีสิ่งที่เรียกว่าแพ็กเกจ Go หลายเวอร์ชัน

go getเสมอดึงจาก HEAD ของสาขาเริ่มต้นในที่เก็บ เสมอ. สิ่งนี้มีนัยสำคัญสองประการ:

  1. ในฐานะผู้เขียนแพ็คเกจคุณต้องยึดมั่นในปรัชญา HEAD ที่มั่นคง สาขาเริ่มต้นของคุณต้องเป็นแพคเกจเวอร์ชันเสถียรและเปิดตัวเสมอ คุณต้องทำงานในสาขาฟีเจอร์และผสานเมื่อพร้อมเผยแพร่เท่านั้น

  2. เวอร์ชันหลักใหม่ของแพ็กเกจของคุณต้องมีที่เก็บของตนเอง กล่าวง่ายๆว่าแต่ละเวอร์ชันหลักของแพ็กเกจของคุณ (ตามการกำหนดเวอร์ชันเชิงความหมาย) จะมีที่เก็บของตัวเองดังนั้นจึงมีเส้นทางการนำเข้าของตัวเอง

    เช่น github.com/jpoehls/gophermail-v1 และ github.com/jpoehls/gophermail-v2

ในฐานะที่มีคนสร้างแอปพลิเคชันใน Go ปรัชญาข้างต้นไม่มีข้อเสีย ทุกเส้นทางการนำเข้าเป็น API ที่เสถียร ไม่มีหมายเลขเวอร์ชันที่ต้องกังวล สุดยอด!

สำหรับรายละเอียดเพิ่มเติม: http://zduck.com/2014/go-and-package-versioning/


45
ข้อความของคุณเกี่ยวกับฟังก์ชันการทำงานของ go tools นั้นถูกต้อง แต่แทบไม่มีใครรวมเวอร์ชันไว้ในชื่อที่เก็บ git ของพวกเขาและหลายคนไม่ถือว่า master / HEAD เป็น API ที่เสถียร ขณะนี้ฉันมีบริการเล็ก ๆ ที่มีการอ้างอิงประมาณแปดรายการ มีเพียงหมายเลขเดียวเท่านั้นที่มีหมายเลขเวอร์ชัน Amazon ผลักดันการเปลี่ยนแปลงอย่างสิ้นเชิงไปที่ github.com/aws/aws-sdk-go go getการแคชหมายความว่าคุณจะไม่สังเกตเห็นสักระยะหนึ่งเว้นแต่คุณจะมีเซิร์ฟเวอร์บิวด์ที่ช่วยอัปเดตคุณเป็นเวอร์ชันล่าสุดทุกครั้ง มีผู้จัดการแพคเกจบุคคลที่สาม แต่ส่วนใหญ่เป็นคนเลว
dhasenan

19
@faisal_kk คุณต้องอยู่ในโลกแห่งความฝัน ในโลกแห่งความเป็นจริงของชุมชนโอเพ่นซอร์สที่ยอดเยี่ยมทุกคนต่างยึดมั่นในปรัชญาของตนเอง ไม่มีการแตกแขนงออกไปฉันดีใจที่เรามีแท็ก

28
สร้างที่เก็บสำหรับทุกเวอร์ชันหรือไม่ มันบ้ามาก
deFreitas

8
นี่เป็นพฤติกรรมที่ผิดโดยพื้นฐาน ซอร์สโค้ดไม่เหมือนกับแพ็กเกจที่นำออกใช้และคุณไม่สามารถใส่ผู้เขียนแพ็กเกจเพื่อให้แน่ใจว่าสามารถทำงานร่วมกันได้แบบย้อนกลับ / ไปข้างหน้า ไม่ใช่เพราะนักพัฒนาไร้ความสามารถ แต่เนื่องจากเป็นไปไม่ได้ในทางทฤษฎีเมื่อจำนวนการอ้างอิงแพ็คเกจเพิ่มขึ้นเกินกว่าหนึ่ง Go get จึงถูกกำหนดให้ไปทางเดียวกันกับ bower ซึ่งข้อบกพร่องหลักคือข้อบกพร่องนี้ การกำหนดเวอร์ชันเชิงความหมายก็ไม่แข็งแรงพอเช่นกันการตรวจสอบไบนารีเป็นวิธีเดียวที่จะไปได้
Gudlaugur Egilsson

5
"ไม่มีหมายเลขเวอร์ชันให้กังวลน่ากลัว!" นั่นจะต้องเป็นคำพูดที่ไร้สาระที่สุดในคำตอบ SO เลยทีเดียว การกำหนดเวอร์ชันมีเหตุผล Go ไม่มีตัวจัดการแพ็คเกจซึ่งมีการกำหนดค่าแบบ inbuilt หรือกลไกที่มุ่งเน้นคำสั่งสำหรับการกำหนดเวอร์ชันของการอ้างอิงต่อคำพูดไม่ได้หมายความว่าการกำหนดเวอร์ชันเป็นสิ่งที่น่ารำคาญ ลงคะแนน!
Harindaka

2

วิธีการที่ฉันได้พบที่สามารถทำงานได้เป็นระบบ submodule คอมไพล์ของ การใช้ที่คุณสามารถใช้โมดูลย่อยในโค้ดเวอร์ชันที่กำหนดและการอัปเกรด / ดาวน์เกรดเป็นสิ่งที่ชัดเจนและบันทึกไว้ - อย่าจับจด

โครงสร้างโฟลเดอร์ที่ฉันใช้คือ:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.

ฉันใช้แนวทางนี้เหมือนกัน โดยพื้นฐานแล้วจะเป็นไปตามโครงสร้างโฟลเดอร์เดียวกันกับ go get แต่ช่วยให้คุณสามารถควบคุมเวอร์ชันที่คุณได้รับได้ดีขึ้น
Brad Peabody

คำตอบไม่ตอบคำถามด้วยเกณฑ์ที่ถาม (โดยใช้go get)
Baptiste Mille-Mathias


2

มีคำสั่งgo edit -replaceเพื่อต่อท้ายคอมมิตเฉพาะ (แม้จะมาจากที่เก็บอื่นที่แยกออกจากกัน) ที่ด้านบนของเวอร์ชันปัจจุบันของแพ็กเกจ สิ่งดีๆเกี่ยวกับตัวเลือกนี้เป็นคือการที่คุณไม่จำเป็นต้องรู้แน่นอนรุ่นหลอกก่อนเพียงกระทำ ID

ตัวอย่างเช่นฉันใช้แพ็คเกจเวอร์ชันเสถียร "github.com/onsi/ginkgo v1.8.0"

ตอนนี้ฉันต้องการ - โดยไม่ต้องแก้ไขบรรทัดของแพ็คเกจที่จำเป็นใน go.mod - เพื่อต่อท้ายแพทช์จากส้อมของฉันที่ด้านบนของเวอร์ชันแปะก๊วย:

$ GO111MODULE="on"  go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo@d6423c2

หลังจากสร้างหรือทดสอบโมดูลครั้งแรก GO จะพยายามดึงเวอร์ชันใหม่จากนั้นสร้างบรรทัด "แทนที่" ด้วยเวอร์ชันหลอกที่ถูกต้อง ตัวอย่างเช่นในกรณีของฉันมันจะเพิ่มที่ด้านล่างของ go.mod:

แทนที่ github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451


1

เอกสารสรุปเล็กน้อยเกี่ยวกับแบบสอบถามโมดูล

ในการตรวจสอบเวอร์ชันที่มีอยู่ทั้งหมด: เช่น go list -m -versions github.com/gorilla/mux

  1. เวอร์ชันเฉพาะ @ v1.2.8
  2. เฉพาะการกระทำ @ c783230
  3. เฉพาะการกระทำ @master
  4. คำนำหน้าเวอร์ชัน @ v2.0
  5. เปรียบเทียบ @> = 2.1.5
  6. ล่าสุด @latest

เช่น go get github.com/gorilla/mux@v1.7.4

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.