واحدة من ميزات لغة جو هو أنها تتضمن عددًا كبيرًا من الوحدات مفتوحة المصدر، وبالتالي يمكن الوصول إليها وفحصها واستخدامها والتعلم منها بحرية. أحيانًا يكون من الضروري إنشاء وحدة جو خاصة لأسباب مختلفة، مثل الاحتفاظ بمنطق عمل داخلي خاص بالشركة.
ستتعلم في هذه المقالة كيفية نشر وحدة module خاصة في لغة جو، وكيفية إعداد الاستيثاق authentication للوصول إليها، وستتعلم أيضًا كيفية استخدام هذا النوع من الوحدات ضمن مشروع.
المتطلبات الأساسية
- أن يكون لديك مساحة عمل خاصة في لغة جو، وإذا لم يكن لديك اتبع سلسلة المقالات التالية:
- أن تكون على دراية بكيفية إنشاء الوحدات في لغو جو. يمكنك مراجعة مقالة كيفية استخدام الوحدات Modules في لغة جو Go.
- لديك معرفة مسبقة بنظام التحكم بالإصدار غيت Git. يمكنك مراجعة مقالة ما هو جيت Git؟.
- إنشاء مستودع فارغ باسم mysecret للوحدة التي ستنشرها.
- رمز وصول شخصي Personal access token على جيت هاب. ستحتاجه للسماح للغة جو بالوصول إلى مستودعك الخاص.
توزيع وحدة خاصة
على عكس العديد من لغات البرمجة، توزّع لغة جو الوحدات البرمجية من المستودعات بدلًا من خادم الحزمة المركزي. تتمثل إحدى فوائد هذا النهج في أن نشر وحدة خاصة يشبه إلى حد بعيد نشر وحدة عامة، إذ تُوزّع الوحدة الخاصة من خلال مستودع شيفرة مصدر خاص، بدلًا من طلب خادم حزمة خاص منفصل تمامًا. نظرًا لأن معظم خيارات استضافة التعليمات البرمجية المصدر تدعم هذا الأمر بما يكفي، فلا داع لإعداد خادم خاص إضافي.
من أجل استخدام وحدة خاصة، ينبغي أن يكون لديك حق الوصول إلى وحدة خاصة. سنُنشئ في هذا القسم وحدةً خاصة وننشرها، وستتمكن من استخدامها لاحقًا خلال هذه المقالة من الوصول إلى وحدة خاصة من شيفرة أُخرى.
سنستخدم بدايةً الأمر git clone
لأخذ نسخة محلية من المستودع الفارغ الذي لا بُد أن نكون قد أنشأناه لأنه جزء من المتطلبات الأساسية. يجب أن يكون هذا المستودع خاصًا، وسنفترض أن اسمه "mysecret". يمكن نسخ هذا المستودع إلى أي مكان نريده على جهاز الحاسوب، لكن يميل العديد من المطورين إلى إنشاء مجلد خاص يتضمن جميع مشاريعهم. سنستخدم هنا مجلدًا باسم "projects". ابدأ بإنشاء المجلد وانتقل إليه:
$ mkdir projects $ cd projects
من مجلد "projects"، شغل الأمر git clone
لنسخ المستودع "mysecret" إلى جهاز الحاسب:
$ git clone git@github.com:your_github_username/mysecret.git
ستعطي جو تأكيدًا على عملية نسخ الوحدة، وقد تحذّرك بأنك قد استنسخت مستودعًا فارغًا، إذا حصل ذلك فلا داعٍ للقلق بشأن ذلك الأمر:
Cloning into 'mysecret'... warning: You appear to have cloned an empty repository.
انتقل الآن باستخدام الأمر cd
إلى المجلد الجديد "mysecret" الذي استنسخته واستخدم الأمر go mod init
لإنشاء الوحدة الجديدة وتمرير موقع المستودع اسمًا لها:
$ cd mysecret $ go mod init github.com/your_github_username/mysecret
يُعد التأكد من تطابق اسم الوحدة مع موقع المستودع أمرًا مهمًا؛ لأن هذه هي الطريقة التي تعثر بها أداة go mod init
على مكان تنزيل الوحدة عند استخدامها في مشاريع أخرى.
سنستخدم الآن محرر نصوص مثل نانو nano، لإنشاء وفتح ملف يحمل نفس اسم المستودع "mysecret.go".
$ nano mysecret.go
يمكن تسمية هذا الملف بأي اسم، ولكن يُفضّل استخدام نفس اسم الحزمة لتسهيل معرفة مكان البدء عند العمل مع حزمة غير مألوفة.
نضيف إلى الملف "mysecret.go" الدالة SecretProcess
لطباعة الرسالة !Running the secret process
:
package mysecret import "fmt" func SecretProcess() { fmt.Println("Running the secret process!") }
يمكنك الآن نشر الوحدة الخاصة ليستخدمها الآخرون. بما أن المستودع الذي أنشأته هو مستودع خاص، بالتالي لا يمكن لشخص غيرك الوصول إليه، ويمنحك ذلك إمكانية التحكم في حق وصول الآخرين إلى وحدتك، وبالتالي يمكنك السماح لأشخاص محددين فقط بالوصول إليها أو عدم السماح لأي شخص بالوصول.
بما أن الوحدات البرمجية الخاصة والعامة في لغة جو هي مستودعات مصدرية، فإن عملية نشر وحدة خاصة تتبع نفس نهج عملية نشر وحدة عامة.
يجب علينا الآن إدراج stage الملفات باستخدام git add
وإيداعها بالمستودع باستخدام git commit
، لكي ننشر الوحدة:
$ git add . $ git commit -m "Initial private module implementation"
سترى تأكيدًا من جيت بأن الإيداع الأولي قد نجح، إضافةً إلى ملخص للملفات المضمنة في الإيداع. سيكون الخرج كما يلي:
[main (root-commit) bda059d] Initial private module implementation 2 files changed, 10 insertions(+) create mode 100644 go.mod create mode 100644 mysecret.go
نستخدم الآن الأمر git push
لدفع الوحدة إلى مستودع غيت هب:
$ git push
سيدفع جو تغييراتك ويجعلها متاحة لأي شخص يملك حق الوصول إلى مستودعك الخاص، وسيكون الخرج كما يلي:
git push origin main Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 404 bytes | 404.00 KiB/s, done. Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:your_github_username/mysecret.git * [new branch] main -> main
يمكنك أيضًا إضافة إصدارات إلى الوحدة الخاصة التي أنشأتها بنفس الطريقة التي نفعلها مع الوحدات العامة.
أنشأت في هذا القسم وحدةً برمجيةً جديدةً تمتلك دالة تُدعى SecretProcess
ونشرتها في مستودع mysecret الخاص بك على غيت هب، وبما أن هذا المستودع خاص، فهذا يعني أن الوحدة خاصة أيضًا، ومن أجل الوصول إلى هذه الوحدة من شيفرة أخرى أو برنامج آخر في جو، ستحتاج إلى إعداد مُحدد، حتى يعرف مُصرّف اللغة كيفية الوصول إليها.
ضبط جو لمنح إمكانية الوصول إلى الوحدات البرمجية الخاصة
كما ذكرنا سابقًا، تُوّزع الوحدات البرمجية المكتوبة بلغة جو من مستودعات الشيفرة المصدرية. يُضيف فريق تطوير لغة جو بعض الخدمات المركزية إلى هذه الوحدات للمساعدة في ضمان استمرار وجود هذه الوحدات في حالة حدوث شيء ما للمستودع الأصلي. تتضمن الإعدادات الافتراضية في لغة جو استخدام هذه الخدمات تلقائيًا، ولكن يمكن أن تحدث مشاكل عند محاولة تنزيل وحدة خاصة لأنها تتضمن إمكانية وصول مُقيّدة.
لإخبار مُصرّف اللغة بأن بعض مسارات الاستيراد خاصة وأنه لا يجب محاولة استخدام خدمات جو المركزية معها، يمكنك استخدام متغير البيئة GOPRIVATE
، وهو يمثّل قائمةً من بادئات مسار الاستيراد مفصولة بفواصل، إذ ستحاول أدوات جو الوصول إليها مباشرةً عند مواجهتها بدلًا من المرور عبر الخدمات المركزية. أحد الأمثلة على ذلك هو الوحدة الخاصة التي أنشأتها للتو.
إذًا، من أجل استخدام الوحدة الخاصة، ينبغي أن نخبر مُصرّف اللغة عن المسار الذي نعدّه خاصًا، وذلك عن طريق ضبط قيمة المتغير GOPRIVATE
. هناك عدد قليل من الخيارات الممكن إجراؤها عند ضبط قيم متغير GOPRIVATE
، وأحد الخيارات هو ضبطه على github.com
، لكن قد لا يفي ذلك بالغرض لأن هذا سيخبر جو بعدم استخدام الخدمات المركزية لأي وحدة مستضافة على github.com
، بما في ذلك الوحدات التي لا تمتلكها.
الخيار الثاني هو ضبط GOPRIVATE
على مسار المستخدم الخاص بك فقط، مثلًا github.com/your_github_username
، فهذا يحل المشكلة السابقة التي تتجلى بعدّ كل الوحدات المستضافة خاصة، ولكن في وقت ما قد يكون لديك وحدات عامة أنشأتها وتريد تنزيلها من نفس الحساب. قد يكون هذا حلًا مناسبًا لحد ما، ولكن كما ذكرنا، قد يمنعك من استخدام وحدات عامة من نفس الحساب.
الخيار الأكثر دقة هو إعداد GOPRIVATE
، بحيث يُطابق مسار الوحدة الخاصة بك تمامًا، مثلًا github.com/your_github_username/mysecret
، إذ يحل ذلك المشاكل السابقة التي رأيناها في الخيار الأول والثاني، ولكن هنا يجب أن نضيف كل وحدة خاصة إلى هذا المتغير (قد تكون هذه مشكلةً للبعض) كما يلي:
GOPRIVATE=github.com/your_github_username/mysecret,github.com/your_github_username/othersecret
يعود اختيار الخيار الأفضل لك، حسبما تراه مناسبًا أكثر.
نظرًا لأن لديك الآن وحدةً خاصة واحدة فقط، سنستخدم اسم المستودع الكامل قيمةً للمتغير. لإجراء ذلك، استخدم الأمر export
كما يلي:
$ export GOPRIVATE=github.com/your_github_username/mysecret
إذا كنت ترغب في التحقق من نجاح عملية ضبط المتغير، فيمكنك استعراض قيمته باستخدام الأمر env
مع grep
:
$ env | grep GOPRIVATE
سيكون الخرج كما يلي:
GOPRIVATE=github.com/your_github_username/mysecret
الآن، أصبح مُصرّف اللغة يعرف أن وحدتك خاصة، لكن هذا لا يزال غير كافٍ لاستخدام الوحدة في شيفرة أو برنامج آخر. جرّب تشغيل هذه الوحدة في وحدة أخرى:
$ go get github.com/your_github_username/mysecret
وسترى الخطأ التالي:
go get: module github.com/your_github_username/mysecret: git ls-remote -q origin in /Users/your_github_username/go/pkg/mod/cache/vcs/2f8c...b9ea: exit status 128: fatal: could not read Username for 'https://github.com': terminal prompts disabled Confirm the import path was entered correctly. If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
تشير رسالة الخطأ هذه إلى أن مُصرّف اللغة حاول تنزيل الوحدة الخاصة بك، لكنه واجه شيئًا لا يمكنه الوصول إليه. بما أنك تستخدم غيت لتنزيل الوحدة، فغالبًا سيُطلب منك إدخال بيانات الاعتماد credentials الخاصة بك، لكن هنا يتصل مُصرّف اللغة بغيت نيابةً عنك، وبالتالي لا يمكنه مطالبتك بإدخال بيانات الاعتماد، وبالتالي يظهر الخطأ. إذًا، أنت بحاجة إلى توفير طريقة لغيت لاسترداد بيانات الاعتماد الخاصة بك.
توفير بيانات الاعتماد اللازمة للاتصال بالوحدة الخاصة عند استخدام بروتوكول HTTPS
هناك طريقة واحدة لإخبار جو بكيفية تسجيل الدخول نيابةً عنك، وهي ملف "netrc." الموجود في المجلد الرئيسي "Home" الخاص بالمستخدم؛ إذ يحتوي هذا الملف على أسماء مُضيفات مختلفة Hosts مع بيانات اعتماد تسجيل الدخول لهم، ويستخدم على نطاق واسع في عدة أدوات برمجية بما في ذلك لغة جو.
سيحاول الأمر go get
استخدام HTTPS أولًا عندما يحاول تنزيل الوحدة، لكن كما ذكرنا؛ لا يمكنه مطالبتك باسم المستخدم وكلمة المرور. لمنح غيت بيانات الاعتماد الخاصة بك، يجب أن يكون لديك ملف "netrc." يتضمن github.com
في مجلدك الرئيسي.
لإنشاء ملف "netrc." على نظام لينوكس Linux أو ماك أو اسم MacOS أو على نظام ويندوز الفرعي لنظام لينوكس Windows Subsystem for Linux -أو اختصارًا WSL، افتح ملف "netrc." في المجلد الرئيسي (/~) حتى تتمكن من تحريره:
$ nano ~/.netrc
أنشئ الآن مدخلًا جديدًا إلى هذا الملف. ينبغي أن تكون قيمة الحقل machine
هي اسم المضيف الذي تضبط بيانات الاعتماد له، وهو github.com
في هذه الحالة، أما قيمة login
فهي اسم المستخدم الخاص بك على غيت هب. أخيرًا، قيمة password
يجب أن تكون رمز الوصول الشخصي الخاص بك، والذي من المفترض أن تكون قد أنشأته على غيت هب.
machine github.com login your_github_username password your_github_access_token
يمكنك أيضًا وضع جميع المدخلات ضمن سطر واحد في الملف:
machine github.com login your_github_username password your_github_access_token
ملاحظة: إذا كنت تستخدم بيت باكيت Bitbucket لاستضافة شيفرة المصدر الخاصة بك، فقد تحتاج أيضًا إلى إضافة مُدخل ثاني من أجل api.bitbucket.org
إضافةً إلى bitbucket.org
. كانت بيت باكيت توفّر سابقًا استضافةً لأنواع متعددة من أنظمة التحكم في الإصدار، لذلك سيستخدم مُصرّف جو واجهة برمجة التطبيقات للتحقق من نوع المستودع قبل محاولة تنزيله. هذا الأمر كان في الماضي ولم يعد الأمر كذلك، إلا أن واجهة برمجة التطبيقات التي تُمكّنك من فحص نوع المستودع ما زالت موجودة. بكافة الأحوال، إذا واجهت هذه المشكلة، فقد تبدو رسالة الخطأ على النحو التالي:
go get bitbucket.org/your_github_username/mysecret: reading https://api.bitbucket.org/2.0/repositories/your_bitbucket_username/protocol?fields=scm: 403 Forbidden server response: Access denied. You must have write or admin access.
إذا رأيت رسالة الخطأ "403 Forbidden" أثناء محاولة تنزيل وحدة خاصة، تحقق من اسم مستخدم جو الذي تحاول الاتصال به؛ فمن الممكن أن تشير إلى اسم مستخدم مختلف مثل api.bitbucket.org
، والذي ينبغي إضافته إلى الملف "netrc.".
بذلك تكون قد أعددت بيئتك لاستخدام مصادقة HTTPS لتنزيل الوحدة الخاصة بك. ذكرنا سابقًا أن الأمر go get
يستخدم افتراضيًا HTTPS عندما يحاول تنزيل الوحدة، لكن من الممكن أيضًا جعله يستخدم بروتوكول النقل الآمن Secure Shell -أو اختصارًا SSH- بدلًا من ذلك. يمكن أن يكون استخدام SSH بدلًا من HTTPS مفيدًا حتى تتمكن من استخدام نفس مفتاح SSH الذي استخدمته لدفع الوحدة الخاصة بك، كما يسمح لك باستخدام مفاتيح النشر deploy keys عند إعداد بيئة CI/CD إذا كنت تفضل عدم إنشاء رمز وصول شخصي.
توفير بيانات الاعتماد اللازمة للاتصال بالوحدة الخاصة عند استخدام بروتوكول SSH
يوفر غيت خيار إعداد يُسمى insteadOf
لاستخدام مفتاح SSH الخاص بك بمثابة طريقة للمصادقة مع الوحدة الخاصة بك بدلًا من HTTPS. يتيح لك هذا الخيار أن تقول "بدلًا من" استخدام "/https://github.com" مثل عنوان URL لإرسال طلبات إلى غيت، تُريد استخدام "/ssh://git@github.com".
يتواجد هذا الإعداد في أنظمة لينوكس وماك ونظام ويندوز الفرعي WSL في ملف "gitconfig.". قد تكون على دراية بهذا الملف فعلًا، إذ يتضمن أيضًا إعدادات عنوان البريد الإلكتروني والاسم الخاصين بك. افتح هذا الملف "gitconfig./~" الآن من مجلدك الرئيسي "Home" باستخدام محرر النصوص الذي تفضله وليكن نانو هنا:
$ nano ~/.gitconfig
عدّل هذا الملف ليحتوي على قسم url
من أجل "/ssh://git@github.com" كما يلي:
[user] email = your_github_username@example.com name = Sammy the Shark [url "ssh://git@github.com/"] insteadOf = https://github.com/
ترتيب قسم user
بالنسبة للقسم url
غير مهم، ولا داع للقلق إن لم يكن هناك أي شيء آخر غير قسم url
الذي أضفته منذ قليل. أيضًا تريتب حقلي email
و name
داخل قسم user
غير مهم.
سيخبر القسم الجديد الذي أضفته غيت أن أي عنوان URL تكون بادئته "/https://github.com" يجب أن تُستبدل بادئته إلى "/ssh: //git@github.com" (الاختلاف بالبادئة). هذا سيؤثر طبعًا على أوامر go get
، لأن جو تستخدم HTTPS افتراضيًا. لو أخذنا مسار الوحدة الخاصة بك مثالًا، فإن جو سيُحوّل مسار الاستيراد "github.com/your_github_username/mysecret" إلى عنوان URL يكون كما يلي: "https://github.com/your_github_username/mysecret". عندما يصادف جو عنوان URL هذا، سيرى عنوان URL يطابق البادئة "/https://github.com" المشار إليها بواسطة insteadOf
وسيعيد عنوان URL إلى "ssh://git@github.com/your_github_username/mysecret" يمكن أيضًا استخدام هذا النمط لنطاقات أخرى وليس فقط لغيت هب، طالما أن @ssh://git يعمل مع ذلك المضيف أيضًا.
ضبطنا خلال هذا القسم غيت لاستخدام SSH، وذلك من أجل تنزيل وحدات جو، وذلك من خلال تحديث ملف "gitconfig."، إذ أضفنا القسم url
. الآن بعد أن أكملنا الإعدادات اللازمة للمصادقة، أصبح بالإمكان الوصول إلى الوحدة واستخدامها في برامج جو.
استخدام وحدة خاصة
تعلمت خلال الأقسام السابقة كيفية إعداد جو ليتمكن من الوصول إلى الوحدة الخاصة بك عبر HTTPS أو SSH أو ربما كليهما. إذًا، أصبح بإمكانك الآن استخدامها مثل أي وحدة عامة أخرى. ستنشئ الآن وحدةً جديدةً تستخدم وحدتك الخاصة.
أنشئ الآن مجلدًا باسم "myproject" باستخدام الأمر mkdir
وضعه في مجلد المشاريع الخاص بك "projects":
$ mkdir myproject
انتقل الآن إلى المجلد الذي أنشأته باستخدام الأمر cd
وهيّئ الوحدة الجديدة باستخدام الأمر go mod init
اعتمادًا على عنوان URL للمستودع الذي ستضع فيه المشروع، مثل "github.com/your_github_username/myproject". إذا كنت لا تخطط لدفع المشروع إلى مستودع آخر، فيمكن أن يكون اسم الوحدة myproject
أو أي اسم آخر، ولكن من الممارسات الجيدة استخدام عناوين URL الكاملة، لأن معظم الوحدات التي تجري مشاركتها ستحتاج إليها.
$ cd myproject $ go mod init github.com/your_github_username/myproject
سيكون الخرج على النحو التالي:
go: creating new go.mod: module github.com/your_github_username/myproject
انشئ الآن ملف "main.go" لتضع فيه أول شيفرة باستخدام محرر النصوص الذي تفضله وليكن نانو:
$ nano main.go
ضع الشيفرة التالية داخل هذا الملف، والتي تتضمن الدالة main
التي سنستدعي الوحدة بداخلها:
package main import "fmt" func main() { fmt.Println("My new project!") }
شغل ملف "main.go" باستخدام الأمر go run
لرؤية المشروع النهائي الذي يستخدم الوحدة الخاصة بك:
$ go run main.go
سيكون الخرج على النحو التالي:
My new project!
أضف الآن وحدتك الخاصة مثل اعتمادية لمشروعك الجديد باستخدام الأمر go get
تمامًا كما تفعل مع الوحدة العامة:
$ go get github.com/your_github_username/mysecret
تنزّل عندها أداة go
شيفرة الوحدة الخاصة وتضيفها مثل اعتمادية باستخدام سلسلة نصية للإصدار تطابق إيداع التعميلة hash الأخير ووقت ذلك الإيداع:
go: downloading github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2 go get: added github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2
افتح ملف "main.go" مرةً أخرى وحدّثه لإضافة استدعاء لدالة الوحدة الخاصة SecretProcess
ضمن دالة main
الرئيسية. ستحتاج أيضًا إلى تحديث عبارة import
لإضافة وحدتك الخاصة github.com/your_github_username/mysecret
:
package main import ( "fmt" "github.com/your_github_username/mysecret" ) func main() { fmt.Println("My new project!") mysecret.SecretProcess() }
شغل ملف "main.go" باستخدام الأمر go run
لرؤية المشروع النهائي الذي يستخدم الوحدة الخاصة بك:
$ go run main.go
ستلاحظ أن الخرج يتضمن الجملة !My new project
من الشيفرة الأصلية، كما يتضمن الجملة !Running the secret process
من الوحدة mysecret التي استوردناها.
My new project! Running the secret process!
استخدمنا في هذا القسم الأمر go init
لإنشاء وحدة جديدة للوصول إلى الوحدة الخاصة التي نشرناها سابقًا. بعد إنشاء الوحدة، ستتمكن من استخدام الأمر go get
لتنزيل الوحدة الخاصة بك؛ تمامًا كما لو كنت تتعامل مع وحدة عامة. استخدمنا أيضًا الأمر go run
لتصريف وتشغيل البرنامج الذي يستخدم الوحدة الخاصة.
الخاتمة
نشرنا خلال هذه المقالة وحدة خاصة باستخدام لغة جو، وتعلمنا كيفية إعداد متطلبات المصادقة باستخدام بروتوكول HTTPS ومفتاح SSH من أجل الوصول إلى الوحدة الخاصة من شيفرة أخرى. استخدمنا أيضًا الوحدة الخاصة ضمن مشروع.
ترجمة -وبتصرف- للمقال How to Use a Private Go Module in Your Own Project لصاحبه Kristin Davidson.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.