اذهب إلى المحتوى

كيفية استخدام وحدة خاصة Private Module ضمن مشروعك بلغة Go


هدى جبور

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

ستتعلم في هذه المقالة كيفية نشر وحدة module خاصة في لغة جو، وكيفية إعداد الاستيثاق authentication للوصول إليها، وستتعلم أيضًا كيفية استخدام هذا النوع من الوحدات ضمن مشروع.

المتطلبات الأساسية

توزيع وحدة خاصة

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

من أجل استخدام وحدة خاصة، ينبغي أن يكون لديك حق الوصول إلى وحدة خاصة. سنُنشئ في هذا القسم وحدةً خاصة وننشرها، وستتمكن من استخدامها لاحقًا خلال هذه المقالة من الوصول إلى وحدة خاصة من شيفرة أُخرى.

سنستخدم بدايةً الأمر 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.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...