هل صحيح أن GOPATH و GOROOT لم تعد هناك حاجة؟

لقد حدث أن المطورين الذين بدأوا للتو بالتعرف على Go يواجهون غالبًا مشكلة اختيار دليل عمل لمشاريع Go. لذلك ، في دردشة مؤتمر GolangConf ، تم طرح هذا السؤال أيضًا. غالبا ما يخيف الغريم الجدد بعضهم البعض بالكلمات GOPATH و GOROOT . ومع ذلك ، في أدلة البداية السريعة مع الإصدار الحالي من Go (1.13) ، لم يتم ذكر هاتين الكلمتين "المخيفتين" على الإطلاق.


دعنا نرى لماذا. من أجل نقاء التجربة ، قمت بنشر تطبيق Ubuntu جديدًا على جهاز افتراضي وتثبيت Go وفقًا لتعليمات Wiki :


sudo add-apt-repository ppa:longsleep/golang-backports sudo apt-get update sudo apt-get install golang-go 

Go 1.13 مثبت وجاهز للاستخدام:


 $ go version go version go1.13 linux/amd64 $ which go /usr/bin/go $ whereis go go: /usr/bin/go /usr/lib/go /usr/share/go /usr/share/man/man1/go.1.gz 

GOROOT


حول GOROOT تمت GOROOT بالفعل بشكل تام في مقال 2015 ، ولا تزال هذه المعلومات ذات صلة.


من المضحك أنه من بين قائمة الأدلة الصادرة عن الأمر الأخير ( whereis go ) ، فإن GOROOT ليست في الحقيقة:


 $ go env GOROOT /usr/lib/go-1.13 

لذلك ، على سبيل المثال ، إذا كنت بحاجة لمعرف IDE لتحديد المسار إلى ملفات مكتبة Go القياسية ، فسوف أقوم بتحديد /usr/lib/go-1.13 . ربما ، في هذا السيناريو ، ينتهي استخدام GOROOT في الحياة اليومية.


GOPATH والوحدات


يبدو أنه من الضروري في هذا المكان التسرع في تثبيت GOPATH ، لكنني لن أفعل ذلك. في الواقع تم تعيين GOPATH بالفعل:


 $ go env GOPATH /home/elena/go 

أنا مرتاح GOPATH في ~/go ، مما يعني أنني لن GOPATH .


سأقوم على الفور بإنشاء دليل لمشروعي الأول على Go. يمكن القيام بذلك في أي مكان ، على سبيل المثال ، مباشرة في الدليل الرئيسي الخاص بك. أيضًا ، سأبدأ على الفور العمل باستخدام أداة Go Modules :


 $ mkdir ~/hello $ go mod init github.com/rumyantseva/hello go: creating new go.mod: module github.com/rumyantseva/hello 

بالنسبة إلى الأمر go mod init ، قمت بتحديد مسار وحدة نمطية فريد لمشروعي. بهذه الطريقة ، يمكن للوكيل أو أداة أخرى ، إذا لزم الأمر ، العثور على ملفات مشروعي.


بعد استدعاء الأمر go mod init ، ظهر دليل go mod init في الدليل الرئيسي الخاص بي:


 $ tree ~/go /home/elena/go └── pkg └── mod └── cache └── lock 3 directories, 1 file 

في هذه الحالة ، لا يزال ملف القفل (في أسفل الشجرة) فارغًا.


ظهر ملف go.mod في دليل ~/hello مع المحتويات التالية:


 module github.com/rumyantseva/hello go 1.13 

في go.mod جميع المعلومات المتعلقة go.mod الوحدة الخاصة بي لاحقًا.


دعونا الآن كتابة تطبيق باستخدام التبعية الخارجية. في دليل ~/hello ، أقوم بإنشاء الملف main.go واكتب التعليمة البرمجية التالية فيه:


 package main import ( "github.com/sirupsen/logrus" ) func main() { logrus.Info("Hello, world!") } 

بالطبع في الحياة الحقيقية لكتابة "مرحبا ، العالم!" يمكنك الاستغناء عن logrus ، ولكن في هذا المثال ، ستساعدنا هذه المكتبة في معرفة مكان تخزين ملفات التبعيات الخارجية.


أقوم بتشغيل التطبيق بأبسط الطرق:


 $ go run main.go go: finding github.com/sirupsen/logrus v1.4.2 go: downloading github.com/sirupsen/logrus v1.4.2 go: extracting github.com/sirupsen/logrus v1.4.2 go: downloading golang.org/x/sys v0.0.0-20190422165155-953cdadca894 go: extracting golang.org/x/sys v0.0.0-20190422165155-953cdadca894 go: finding golang.org/x/sys v0.0.0-20190422165155-953cdadca894 INFO[0000] Hello, world! 

قبل أن يتم إنشاء التطبيق وتشغيله ، تعمل أداة go mod . قام بتعريف تبعية خارجية github.com/sirupsen/logrus ، وأخذ أحدث إصدار له v1.4.2 وذهب إلى التبعيات متعدية.


تمت إضافة سطر إلى ملف go.mod مع وصف الاعتماد على logrus :


 module github.com/rumyantseva/hello go 1.13 require github.com/sirupsen/logrus v1.4.2 // indirect 

go.sum ملف go.sum أيضًا ، حيث يتم تخزين معلومات حول تجزئات التبعيات العابرة ، بالإضافة إلى تجزئة تبعية logrus :


 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 

أين هو رمز التبعية نفسه؟ يمكن العثور عليها في ~/go/pkg/mod . أيضًا ، سيتم تخزين المجموع الاختباري ومعلومات الحمل الأخرى للعمل مع التبعيات في ~/go/pkg .


إذا واجهت بالفعل أداة go get ، فأنت تعلم أنه عند سحب التبعيات ، فإنها في الواقع تقوم git clone المستودعات (على سبيل المثال ، في حالة git مع git clone ). ولكن go mod لا يعمل بهذه الطريقة. بالنسبة إلى go mod الوحدة الرئيسية في الكود هي الوحدة. وحدات هي المحفوظات. عند العمل مع تبعيات go mod ، فإنه بشكل صريح (إذا قمت GOPROXY الأمر go mod download ) أو بشكل ضمني (إذا بدأت ترجمة التطبيق) التنزيلات GOPROXY أرشيفات عبر GOPROXY . دعونا نرى كيف يتم تعيين الوكيل في Go 1.13 افتراضيًا:


 $ go env GOPROXY https://proxy.golang.org,direct 

لذلك ، وكوكيل عند بناء بلدي "مرحبا ، العالم!" المستخدمة من قبل proxy.golang.org . بالطبع ، يمكن تغيير هذا المتغير عن طريق اختيار مستودع مختلف للوحدات النمطية. على سبيل المثال ، يمكنك نشر شركة البروكسي الداخلية الخاصة بك ، والتي سيتم تخزينها ، بما في ذلك المكتبات الداخلية ، التي لم يتم نشر رمزها في المصدر المفتوح.


بشكل عام ، إذا بدأت مشروعًا جديدًا ولا أمانع في استخدام Go Modules ، فقد لا أعرف أي شيء عن GOPATH . سيقوم Go بإنشاء دليل ~/go من تلقاء نفسه عند الحاجة.


متى يحتاج GOPATH؟


إذا كنت لا تستخدم Go Modules بشكل أساسي (على سبيل المثال ، في مشروع قديم) ، فقد لا يكون الابتعاد عن العمل الأكثر وضوحًا مع GOPATH بهذه البساطة.


لمعرفة ما سيحدث ~/hello/go.mod ، إذا قررت عدم استخدام go mod ، فاحذف الملفات ~/hello/go.mod و ~/hello/go.sum . سأقوم أيضًا بإزالة ~/go للعودة إلى حالة النظام الذي كان لدي في البداية:


 rm -rf ~/go ~/hello/go.mod ~/hello/go.sum 

يبقى ملف main.go فقط في دليل ~/hello . ماذا يحدث الآن إذا حاولت تشغيله باستخدام go run ؟


 $ go run main.go main.go:4:2: cannot find package "github.com/sirupsen/logrus" in any of: /usr/lib/go-1.13/src/github.com/sirupsen/logrus (from $GOROOT) /home/elena/go/src/github.com/sirupsen/logrus (from $GOPATH) 

ها هم ، هذه GOROOT مخيفة و GOPATH :)


من أجل ترجمة التطبيق ، أحتاج إلى سحب التبعية في GOPATH . أفعل هذا مع go get القديم الجيد go get :


 $ go get -v github.com/sirupsen/logrus github.com/sirupsen/logrus (download) created GOPATH=/home/elena/go; see 'go help gopath' get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/unix?go-get=1 get "golang.org/x/sys/unix": verifying non-authoritative meta tag golang.org/x/sys (download) golang.org/x/sys/unix github.com/sirupsen/logrus 

ماذا حدث بادئ ذي go get ، go get إنشاء دليل ~/go (الدليل المحدد باسم GOPATH ). ثم بدأت عملية استنساخ المستودعات بالتبعية. من المضحك أن مستودعات الاستنساخ تبدو أبطأ بشكل ملحوظ من الخيار عندما استخدمنا go mod لتنزيل وفك الوحدات. ومع ذلك ، يمكن الآن العثور على رمز التبعية داخل ~/go/src/ .


بالمناسبة ، لا يوجد عميل git على تثبيت Ubuntu النظيف ، ولكي go get العمل ، كان علي تثبيته.


أقوم بتشغيل التطبيق:


 $ go run main.go INFO[0000] Hello, world! 

إنه يعمل!


هذا فقط على مستوى التطبيق ، وأنا الآن لا تتبع إصدار التبعيات الخارجية. ماذا لو لم يكن المستودع الذي توقعته ، في وقت ما في مستودع github.com/sirupsen/logrus هو المسجل الذي كنت أتوقعه ، ولكن بعض الأكواد الخبيثة؟ عاجلاً أم آجلاً ، ما زلت أحتاج إلى أداة للتعامل مع التبعيات ، وإذا لم يكن تطبيق Go Modules لسبب ما مناسبًا ، فيجب عليك البحث عن شيء آخر ...


استنتاج


لم تتناول هذه المقالة بعض النقاط المحددة ، ولا يزال العمل مع التبعيات الخارجية في Go يسبب الكثير من الأسئلة. ومع ذلك ، لا تفرض الإصدارات الجديدة من Go على الأقل قيودًا على أماكن إنشاء أدلة العمل الخاصة بمشروعاتك.


إذا كنت تبدأ مشروعًا جديدًا ، فجرّب Go Modules! العودة إلى النهج القديم للعمل مع التبعيات أمر منطقي فقط إذا حدث خطأ ما. بالمناسبة ، إذا كنت تفضل تخزين جميع التبعيات داخل المشروع ، فإن Go Modules تدعم وضع البائع.


إذا كنت بحاجة إلى العمل مع مشروع موجود ، ولسبب ما لا ترغب في ترجمته إلى Go Modules ، فمن المهم الإشارة في وثائق المشروع إلى ميزات نشره وإدارة التبعية. إذا كان الوافدون الجدد على دراية بالمناهج القديمة للعمل مع التبعيات ، فقد أصبح من الأسهل بالنسبة لهم التعامل مع المشروع في حالة وجود جميع الوثائق.


بالمناسبة ، في 7 أكتوبر في مؤتمر GolangConf ، كواحد من الأنشطة الخاصة ، نخطط لمنطقة خبراء حيث يمكن لأي شخص طرح أي أسئلة حول Go to أعضاء لجنة برنامج المؤتمر وعشاق مجتمع Go Goos الروسي. تثبيت الذهاب؟ تعامل مع الإدمان؟ اكتب microservice؟ هذا لنا!

Source: https://habr.com/ru/post/ar467697/


All Articles