أولاً ، خلفية صغيرة. في أوائل عام 2010 ، قمت بعمل أداة تحويل صغيرة لملفات BIN الخاصة بمحاكي BK-0010 إلى ملفات WAV. تمت كتابة الأداة المساعدة في Python بهدف أقصى قابلية للنقل ، وقد عملت دون مشاكل ، وقد نسيت ذلك لفترة من الوقت. ولكن في عام 2016 ، ظهر المستخدم ، الذي لم يكن لديه أي فكرة عن بيثون وكيفية تثبيته. أراد متراصة قابلة للتنفيذ بسيطة من شأنها أن "العمل فقط". بدا أن طلبه منطقي ، وقررت إعادة صياغة الأداة كمجموعة من الملفات التنفيذية الثنائية للأنظمة الأساسية.

لم تمنح Python و Java هذه الفرصة (ما لم تكن هناك بالطبع رغبة في تضخيم الأداة بعدة عشرات من الميجابايت). من المحتمل ، يمكن إجراء الحل في C / C ++ ، ولكن مع مثل هذه التغطية المستهدفة للمنصات ، فإن صعوبات التجميع المتقاطع ستتجاوز الوقت المخصص للمهمة (واضطررت إلى دعم التجميع المتزامن لنظامي التشغيل Windows و Linux و MacOS في 64 و 32 بت تجسيدات). لذا لفتت الانتباه إلى لغة Go ، التي تكتسب شعبية ، والتي أصبحت بحلول ذلك الوقت ناضجة بالفعل ، والوحيد الذي يقدم دون كل الرقصات مع الدف يوفر كل التجميع المتداخل المطلوب خارج الصندوق مباشرة (!) .
أحد المضايقات التي أزعجتني كثيرًا حول Go (خاصة كمطور Java) كانت ضعف التفكير في تنظيم بنية مشاريع Go والحاجة إلى ضبط البيئة باستمرار. ربما خطط مطورو Go مبدئيًا لاستخدام معين أو كان هناك تركيز على الحاويات ، لكنني اعتدت على الاستخدام "اللذيذ" ولأن أداةي الرئيسية في Java هي Maven ، فقد قررت إجراء مكوّن إضافي لإجراء مكالمات إلى الأدوات المساعدة وأوامر GoSDK مع الإنشاء التلقائي للأوامر الضرورية متغيرات البيئة.
لم يكن من المثير للاهتمام إنشاء مكوّن إضافي بسيط يسمي الأداة المساعدة go ، وقررت الانتقال من الخطوة - تثبيت GoSDK على النظام الأساسي المضيف. مباشرة بعد البدء ، يتم فحص GoSDK في دليل التكوين الخاص بها (اخترت المسار الافتراضي ~/.mvnGoLang
) ، وفي حالة عدم وجود الإصدار المطلوب ، يتم تنزيل أرشيف GoSDK تلقائيًا وتفريغه من الموقع الرسمي . سمح لنا ذلك بإنشاء مشاريع Go المحمولة دون القلق بشأن ما إذا كانت أداة الإصدار المطلوب مثبتة مسبقًا أم لا. بالطبع ، مع العديد من الإعدادات ، توقعت إمكانية استخدام إصدار مثبت مسبقًا وإعدادات إضافية لجميع الخطوات في العملية ، نظرًا لأن العديد من المشكلات مثل تعطيل التحقق من شهادة طبقة المقابس الآمنة أو جعل طلبات HTTP بالخارج عمومًا (مثل مشروع Keycloak ) ضرورية .
في الخطوة التالية ، غطيت في الأهداف (الأهداف) جميع أوامر الذهاب فائدة المقدمة في ذلك الوقت. نظرًا لوجود فرصة ظهور أمر جديد آخر مع الإصدار الجديد من GoSDK ، تمت إضافة مهمة custom
تتيح للمستخدم تحديد الأمر المرغوب به من تلقاء نفسه. بشكل افتراضي ، في إطار مراحل maven (المراحل) ، يتم تنفيذ المهام بالترتيب التالي:
- نظيفة كما
default-clean
في المرحلة نظيفة - إصلاح كإصلاح
default-fix
في مرحلة التحقق من الصحة - الحصول كما
default-get
مرحلة التهيئة - إنشاء
default-generate
في مرحلة إنشاء المصادر - fmt كما
default-fmt
في مرحلة مصادر العملية - اختبار كاختبار
default-test
في مرحلة الاختبار - بناء كما
default-build
في مرحلة الحزمة - كتثبيت
default-install
يتم تنفيذ المهمة الداخلية mvninstall في مرحلة التثبيت - تثبيت
default-deploy
في مرحلة النشر
يمكن تعطيل أي من الخطوات الأساسية عن طريق ترجمة المهمة إلى مرحلة غير موجودة:
<execution> <id>default-fix</id> <phase>none</phase> </execution>
في التنفيذ الداخلي ، تم تقسيم المهام إلى "العمل مع التبعيات" و "لا تتطلب دقة التبعية" ، بعد ظهور الدعم لوضع الوحدة النمطية ، انتقل معظمها إلى "العمل مع التبعيات".
حاولت بنية مشروع Go-maven الاقتراب من بنية المجلد القياسية المقبولة لـ Go (أي /src
و /bin
في جذر المشروع). ولكن نظرًا لأن Maven مسجون لجافا ، فلم يكن من الممكن بشكل مباشر "كسر" نهجه في تنظيم هيكل المشروع وجعل هذه الخطوة غير مرئية للمستخدم ، لذلك يبدو التكوين الأساسي للمكون الإضافي غير عادي قليلاً حتى بالنسبة للكثيرين على دراية بـ maven:
<build> ```${basedir}/src</sourceDirectory> <directory>${basedir}/bin</directory> <plugins> <plugin> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-wrapper</artifactId> <version>2.3.3</version> <extensions>true</extensions> <configuration> <goVersion>1.12.9</goVersion> </configuration> </plugin> </plugins> </build>
تحذير! لسبب ما ، قد يعرض HabR بشكل غير صحيح قسم <sourceDirectory>${basedir}/src</sourceDirectory>
عند تنسيق XML
كما ترى ، يجب عليك تحديد المجلد المصدر /src
والمجلد مباشرة بالنتيجة /bin
. من ناحية ، هذا ناقص ، من ناحية أخرى ، إمكانية تغيير موقعهم.
إن pom.xml الكامل البسيط لمشروع وحدة واحدة ، عالم مرحبا ، كما يلي:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-helloworld</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>mvn-golang</packaging> <build> ```${basedir}/src</sourceDirectory> <directory>${basedir}/bin</directory> <plugins> <plugin> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-wrapper</artifactId> <version>2.3.3</version> <extensions>true</extensions> <configuration> <goVersion>1.12.9</goVersion> </configuration> </plugin> </plugins> </build> </project>
يرجى ملاحظة أن عبوة المشروع مصممة كـ mvn-golang . هذا التكوين يكفي لبناء الملف القابل للتنفيذ ووضعه في مجلد الحاوية الناتج على أساس النصوص المصدر في مجلد src. سيتم أيضًا إنشاء ذاكرة التخزين المؤقت Go build في /bin
(كـ /bin/.goBuildCache
افتراضيًا) وسيتم مسحها بنظافة باستخدام هذا المجلد المؤقت.
في مرحلة التثبيت ، mvninstall
مهمة mvninstall
الداخلية ، والتي تقوم ببساطة بحزم المشروع بأكمله في أرشيف مضغوط mvninstall
تم إنشاؤها. في البداية ، قمت فقط بتخزين هذه القطع الأثرية ، لكن من الإصدار 2.3.2 ، تمت إضافة آلية لدعمها باعتبارها تبعيات مخضرمة معيارية وأصبح من الممكن تطوير مشاريع مع "مشاركة" الكود الشائع من خلال مستودع maven. من الواضح أن وضع النتائج الثنائية التي تم إنشاؤها في المستودع حيث أن القطع الأثرية هي فكرة سيئة نظرًا لمتطلبات النظام الأساسي وبالتالي فإن محتويات المجلد /bin
لا يتم تعبئتها في الأداة.
يبدو ربط مشروع آخر mvn-golang
مخضرم مثل هذا:
<dependency> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-go-test-mix-terminal</artifactId> <version>1.0.0-SNAPSHOT</version> <type>mvn-golang</type> </dependency>
مع الإصدار 2.3.3 ، تمت إضافة دعم للعمل مع آلية الانتقال للوحدات النمطية ، ولكن افتراضيًا لا يتم تنشيطه (للتوافق مع الإصدارات السابقة) ويتم تمكينه باستخدام معلمة التكوين:
<moduleMode>true</moduleMode>
عندما كانت آلية Go-modules لا تزال في المرحلة التجريبية ، أضفت دعمًا للعمل مع إصدارات التبعية من خلال مكالمات مباشرة إلى أدوات CVS ، تم تقديم مثال للاختبار . لكن الآن أعتقد أن مثل هذه الآلية لم تعد ذات أهمية كبيرة وأنها أكثر ربحية لاستخدام التبعيات القياسية من خلال وحدات. علاوة على ذلك ، فإن البرنامج المساعد قادر على go.mod
ملفات go.mod
مسبقًا في وقت بناء المشروع ، واستبدال المسارات إلى المجلدات المحلية إذا كان العمل مستمرًا في إطار مشروع متعدد الوحدات.
نظرًا لأن Maven يوفر إمكانية التوحيد باستخدام النماذج الأصلية ، فقد صنعت نموذجين:
- com.igormaznitsa: mvn-golang-hello: 2.3.3 لنموذج أصلي بسيط مكون من وحدة واحدة
- com.igormaznitsa: mvn-golang-hello-multi: 2.3.3 لمشروع متعدد الوحدات مع شفرة المصدر المشتركة
مثال على العمل مع النموذج الأصلي لمشروع وحدة واحدة يمكن أن ينظر إليه في الرسوم المتحركة أدناه
.
يمكنك أيضًا استنساخ مشروع "Hello World" واللعب حوله:
git clone https://github.com/raydac/mvn-golang-example.git

غالبًا ما يطرح سؤال معقول - لماذا كل هذا ضروري وما هي المكافآت التي يقدمها استخدام Maven في عملية بناء مشروع Go-project؟ سأحاول الإجابة عليه نقطة تلو الأخرى:
- Maven هي بيئة بناء مشاريع ناضجة للغاية ، عبر منصات ، مدعومة من قبل جميع منصات CI تقريبًا ، على سبيل المثال Jenkins ، باستخدام Go2XUnit ، يمكنك تحويل نتائج الاختبار إلى التنسيق الذي يتم عرضه عن طريق الإبلاغ عن المكونات الإضافية.
- Maven عبارة عن نظام أساسي متداخل ويدعمه جميع أنظمة التشغيل ، حيث يتم تضمينه في جميع المستودعات. إن وجود ملفات التعريف النشطة بمرونة يجعل من السهل تخصيص العملية لمختلف المنصات.
- تحتوي Maven على كمية هائلة من المكونات الإضافية ، مما يجعل من السهل الحصول على تأثير تآزري ، من خلال الجمع بين Go و GWT ، وربط ANTLR بالمشروع ، وإنشاء Go استنادًا إلى واصفات Protobuf وحتى إضافة المعالجة المسبقة . يمكن تنظيم كل ذلك يدويًا من خلال الملفات الدفعية ، ولكن إذا كان هناك مكونات إضافية مدعومة رسميًا ، فمن الأفضل استخدامها.
- يصبح المشروع سهل الحمل بين الأجهزة والمنصات ، ويتم تبديل إصدار GoSDK عن طريق تغيير سطر واحد.
- سهولة تنظيم مشاريع متعددة الوحدات ، مع فصل شفرة المصدر من خلال مستودع Maven.
- الأداة مألوفة ومألوفة لمطوري Java ، مما يسهل تكيفهم عند التبديل إلى التطوير على Golang أو عند تطوير حلول Go + Java متعددة اللغات.
- هناك إمكانية للتطوير الزائف في Go في بيئات تدعم Maven ، حتى لو لم يكن لديهم أي دعم لهذا النظام الأساسي ، على سبيل المثال ، في NetBeans IDE .
وأكبر عيوب في الحل ، في رأيي ، واحدة هنا - عدد محدود من المطورين المطلعين على مافن في مجتمع Golang. بالنسبة لأولئك الذين تحولوا إلى Golang باستخدام C / C ++ ، فمن الواضح أنه من الصعب العثور على شيء أقرب وأحب إلى صنعه ، بالإضافة إلى أنه لم يقم أحد بإلغاء أنظمة Go-build "الأصلية". لقد لاحظت أنه لسبب ما ، العديد من المطورين لا يحبون خلط المنصات.
لذلك ، عرضت بإيجاز إحدى الطرق لاستخدام Maven عند تطوير مشاريع Go باستخدام البرنامج المساعد mvn-golang-wrapper. تم تصميم مشروع البرنامج المساعد كمشروع OSS ونشره على جيثب . إذا كان شخص ما مهتمًا وسيستخدم في مشاريعه ، فلا تتردد في طرح الأسئلة و "الإبلاغ عن الأخطاء". حاولت أن أقدم مجموعة من الأمثلة لمناسبات مختلفة (يتم اختبار المكوّن الإضافي فيها) ، لكن لا يمكنني تغطية كل شيء.
تستخدم حالات الاختبار في مشروع البرنامج المساعد إصدار dev ، لذا إذا كنت ترغب في بنائها محليًا بعد استنساخ المشروع ، فأنت بحاجة أولاً إلى إنشاء إصدار dev من البرنامج المساعد باستخدام الأمر في دليل جذر المشروع:
mvn install
بعد ذلك ، يمكنك الذهاب إلى أي mvn-golang-examples
وبناء عليه
mvn clean install
يمكنك أيضًا البدء في بناء جميع الأمثلة من جذر المشروع ، باستخدام
mvn clean install -Pexamples
البرنامج المساعد يدعم تجميع مشاريع متعددة الخيوط ويمكن تسريعها باستخدام الوسيطة المقابلة ، على سبيل المثال تقسيم إلى 6 سلاسل
mvn clean install -Pexamples -T6
خلال التطوير ، جمع المشروع كمية لا بأس بها من "أجراس وصفارات" ، والتي قررت عدم تغطيتها في هذا المقال القصير. يمكن العثور على معلومات حول المعلمات مع أمثلة التكوين الصغيرة في الخريطة الذهنية لهذا البرنامج المساعد (الملف المصدر في تنسيق SciaReto هنا ):
