تحليل طلبات الدمج في GitLab باستخدام PVS-Studio لـ C #

image1.png


هل تحب GitLab وتكره الحشرات؟ هل تريد تحسين جودة شفرة المصدر الخاصة بك؟ ثم كنت قد وصلنا إلى المكان الصحيح. سنخبرك اليوم بكيفية إعداد محلل PVS-Studio C # للتحقق من طلبات الدمج. كل مزاج وحيد القرن وقراءة ممتعة.



PVS-Studio هي أداة لاكتشاف الأخطاء ونقاط الضعف المحتملة في الكود المصدري للبرامج المكتوبة بلغة C و C ++ و C # و Java. يعمل في أنظمة 64 بت على Windows و Linux و macOS. يمكن تحليل التعليمات البرمجية لأنظمة ARM 32 بت و 64 بت والمضمنة.



بالمناسبة ، أصدرنا PVS-Studio 7.08 ، حيث قمنا بالكثير من الأشياء المثيرة للاهتمام . على سبيل المثال:



  • محلل C # لنظامي Linux و macOS ؛
  • البرنامج المساعد لراكب.
  • الوضع الجديد لفحص قائمة الملفات.


وضع فحص قائمة الملفات



في السابق ، من أجل التحقق من ملفات معينة ، كان من الضروري تمرير ملف .xml مع قائمة بالملفات إلى المحلل اللغوي. ولكن نظرًا لأنها ليست مريحة للغاية ، فقد أضفنا القدرة على نقل .txt ، مما يبسط الحياة بشكل كبير.



للتحقق من ملفات معينة ، تحتاج إلى تحديد علامة --sourceFiles ( -f ) وتمرير .txt بقائمة من الملفات. تبدو هكذا:



pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json


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



دمج مبدأ التحقق من الطلب



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



هذا ما يبدو عليه طلب الدمج قبل تنفيذ محلل ثابت:



image2.png


أي أن جميع الأخطاء التي كانت في فرع التغييرات ستنتقل إلى الفرع الرئيسي. نظرًا لأننا لا نحب هذا ، نضيف التحليل ، والآن يبدو الرسم التخطيطي على النحو التالي:



image3.png


نقوم بتحليل التغييرات 2 ، وفي حالة عدم وجود أخطاء ، نقبل طلب الدمج ، وإلا فإننا نرفضه.



بالمناسبة ، إذا كنت مهتمًا بتحليل الالتزامات وسحب الطلبات لـ C / C ++ ، فيمكنك القراءة عنها هنا .



جيتلاب



GitLab عبارة عن أداة دورة حياة DevOps مفتوحة المصدر قائمة على الويب توفر نظامًا لإدارة مستودع الأكواد لـ Git مع wiki الخاص بها ، وتعقب الأخطاء ، وخط أنابيب CI / CD ، والمزيد.



قبل أن تبدأ في تنفيذ تحليل طلبات الدمج ، تحتاج إلى التسجيل وتحميل مشروعك. إذا كنت لا تعرف كيفية القيام بذلك ، فأقترح مقالًا بقلم زميلي.



ملحوظة... تعد طريقة إعداد البيئة الموضحة أدناه واحدة من الطرق الممكنة. الهدف هو إظهار خطوات إعداد البيئة المطلوبة للتحليل وتشغيل المحلل. ربما ، في حالتك ، سيكون من الأفضل فصل مراحل إعداد البيئة (إضافة مستودعات ، تثبيت المحلل) والتحليل: على سبيل المثال ، إعداد صور Docker مع البيئة اللازمة واستخدامها ، أو طريقة أخرى.



لفهم ما سيحدث الآن بشكل أفضل ، أقترح إلقاء نظرة على المخطط التالي:



image4.png


يتطلب المحلل .NET Core SDK 3 للعمل ، لذا قبل تثبيت المحلل ، تحتاج إلى إضافة مستودعات Microsoft ، والتي سيتم من خلالها تثبيت التبعيات اللازمة للمحلل. إضافة مستودعات Microsoft لتوزيعات Linux المختلفة موصوفة في المستند المقابل .



لتثبيت PVS-Studio من خلال مدير الحزم ، ستحتاج أيضًا إلى إضافة مستودعات PVS-Studio. تم وصف إضافة مستودعات للتوزيعات المختلفة بمزيد من التفصيل في القسم المقابل من الوثائق .



يتطلب المحلل مفتاح ترخيص للعمل. يمكنك الحصول على ترخيص تجريبي على صفحة تنزيل المحلل .



ملحوظة... يرجى ملاحظة أن وضع التشغيل الموضح (تحليل طلبات الدمج) يتطلب ترخيص Enterprise. لذلك ، إذا كنت ترغب في تجربة وضع التشغيل هذا ، فلا تنس الإشارة في حقل "الرسالة" إلى أنك بحاجة إلى ترخيص Enterprise.



في حالة حدوث طلب دمج ، فإننا نحتاج إلى تحليل قائمة الملفات التي تم تغييرها فقط ، وإلا فإننا نحلل جميع الملفات. بعد التحليل ، نحتاج إلى تحويل السجلات إلى التنسيق الذي نحتاجه.



الآن ، بعد أن أمامك خوارزمية العمل ، يمكنك المتابعة لكتابة السيناريو. للقيام بذلك ، تحتاج إلى تعديل ملف .gitlab-ci.yml أو ، إذا لم يكن كذلك ، قم بإنشائه. لإنشائه ، تحتاج إلى النقر فوق اسم مشروعك -> إعداد CI / CD .



image5.png


الآن نحن جاهزون لكتابة السيناريو. لنكتب أولاً الكود الذي سيقوم بتثبيت المحلل وإدخال الترخيص:



before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln


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



التحضير لتثبيت المحلل:



  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update


إضافة مستودعات ومحلل PVS-Studio:



  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet


تفعيل الترخيص:



  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY


$ PVS_NAME - اسم المستخدم.



$ PVS_KEY - مفتاح المنتج.



استعادة تبعيات المشروع ، حيث يكون $ CI_PROJECT_DIR هو المسار الكامل إلى دليل المشروع:



  - dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln


من أجل التحليل الصحيح ، يجب بناء المشروع بنجاح ، ويجب استعادة تبعياته (على سبيل المثال ، يجب تحميل حزم NuGet الضرورية).



يمكنك تعيين متغيرات البيئة التي تحتوي على معلومات الترخيص عن طريق النقر فوق الإعداد ، ثم على CI / CD .



image6.png


في النافذة التي تفتح ، نجد عنصر المتغيرات ، على اليمين ، انقر فوق الزر توسيع وأضف المتغيرات. يجب أن تبدو النتيجة كما يلي:



image7.png


الآن يمكنك المتابعة إلى التحليل. أولاً ، دعنا نضيف نصًا للتحليل الكامل. نقوم بتمرير المسار إلى الحل في العلامة -t ، وفي العلامة -o نكتب المسار إلى الملف الذي ستُكتب فيه نتائج التحليل. نحن مهتمون أيضًا برمز الإرجاع. في هذه الحالة ، نحن مهتمون بإنهاء العملية عندما يحتوي كود الإرجاع على معلومات تفيد بأن التحذيرات صدرت أثناء التحليل. هذا ما يبدو عليه هذا المقتطف:



job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi


تعمل رموز الإرجاع مثل قناع بت. على سبيل المثال ، إذا تم إصدار تحذيرات نتيجة للتحليل ، فسيكون رمز الإرجاع 8. إذا انتهت صلاحية الترخيص في غضون شهر ، فسيكون رمز الإرجاع 4. إذا تم العثور على أخطاء أثناء التحليل ، وانتهت صلاحية الترخيص في غضون شهر ، في الكود العودة ، ستتم كتابة كلا القيمتين: اجمع الأرقام معًا واحصل على رمز الإرجاع النهائي - 8 + 4 = 12. وبالتالي ، من خلال التحقق من البتات المقابلة ، يمكن الحصول على معلومات حول الحالات المختلفة أثناء التحليل. تم وصف رموز الإرجاع بمزيد من التفصيل في قسم "رموز إرجاع pvs-studio-dotnet (Linux / macOS)" من المستند " التحقق من مشاريع Visual Studio / MSBuild / .NET Core من سطر الأوامر باستخدام PVS-Studio ".



في هذه الحالة ، نحن مهتمون بجميع رموز الإرجاع ،حيث تظهر 8.



  - exit_code=$((($exit_code & 8)/8))


سنحصل على 1 عندما يحتوي رمز الإرجاع على جزء من الرقم الذي نهتم به ، وإلا فسنحصل على 0.



حان الوقت لإضافة تحليل طلب الدمج. قبل القيام بذلك ، دعنا نجهز مكانًا للنص. نحتاج فقط إلى تنفيذه عند حدوث طلب دمج. تبدو هكذا:



merge:
  script:
  only:
  - merge_requests


دعنا ننتقل إلى النص نفسه. صادفت حقيقة أن الآلة الافتراضية لا تعرف شيئًا عن الأصل / الرئيسي . لذلك نساعدها قليلاً:



  - git fetch origin


الآن دعنا نحدد الفرق بين الفروع ونحفظ النتيجة في ملف txt :



  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt


حيث يكون $ CI_COMMIT_SHA هو تجزئة الالتزام الأخير.



بعد ذلك ، نقوم بتحليل قائمة الملفات باستخدام العلامة -f . نقوم بنقل ملف .txt الذي تم استلامه سابقًا إليه. حسنًا ، بالقياس مع التحليل الكامل ، ننظر إلى أكواد الإرجاع:



  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi


سيبدو النص الكامل للتحقق من طلب الدمج كما يلي:



merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests


يبقى فقط لإضافة تحويل السجل بعد تشغيل جميع البرامج النصية. نحن نستخدم after_script التسمية و plog المحول فائدة :



after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json


الأداة المساعدة plog-converter عبارة عن مشروع مفتوح المصدر يُستخدم لتحويل تقرير خطأ المحلل إلى أشكال مختلفة ، مثل HTML. ويرد وصف أكثر تفصيلاً عن الأداة في القسم الفرعي "Plog Converter Utility" في القسم المقابل من الوثائق .



بالمناسبة ، إذا كنت تريد العمل بشكل ملائم مع تقرير .json محليًا من IDE ، فأنا أقترح المكون الإضافي الخاص بنا لـ IDE Rider. تم وصف استخدامه بمزيد من التفصيل في الوثيقة المقابلة .



للراحة ، إليك ملف .gitlab-ci.yml بأكمله :



image: debian

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  
after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json


بمجرد إضافة كل شيء إلى الملف ، انقر فوق تنفيذ التغييرات . لكي ترى أن كل شيء صحيح ، انتقل إلى CI / CD -> خطوط الأنابيب -> قيد التشغيل . ستفتح نافذة آلة افتراضية ، في نهايتها يجب أن تكون كما يلي:



image8.png


رأينا أيوب نجح - نجاح ، كل شيء على ما يرام. الآن يمكنك اختبار ما قمت به.



أمثلة على العمل



للحصول على مثال للعمل ، دعنا ننشئ مشروعًا بسيطًا ( رئيسيًا ) حيث سيكون هناك عدة ملفات. بعد ذلك ، في فرع آخر ، سنقوم بتغيير ملف واحد فقط ونحاول تقديم طلب دمج.



ضع في اعتبارك حالتين: عندما يحتوي الملف المعدل على خطأ ومتى لا. أولاً ، مثال به خطأ.



لنفترض أن هناك ملف Program.cs في الفرع الرئيسي ، والذي لا يحتوي على أخطاء ، وفي فرع آخر ، أضاف المطور رمزًا خاطئًا ويريد تقديم طلب دمج. ما نوع الخطأ الذي ارتكبه ليس مهمًا جدًا ، الشيء الرئيسي هو أنه موجود. على سبيل المثال، لقد نسيت رمي المشغل (نعم، أنهم مخطئون جدا ):



void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // do something
  ....
}


لنلقِ نظرة على نتيجة تحليل مثال به خطأ. أيضًا ، للتأكد من تحليل ملف واحد فقط ، أضفت العلامة -r إلى سطر بدء تشغيل pvs-studio-dotnet:



image9.png


نرى أن المحلل وجد خطأ ولم يسمح بدمج الفروع.



التحقق من المثال دون خطأ. إصلاح الكود:



void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // do something
  ....
}


نتائج تحليل طلب الدمج:



image10.png


كما نرى ، لم يتم العثور على أخطاء ، وتم تنفيذ المهمة بنجاح ، الأمر الذي أردنا التحقق منه.



خاتمة



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



شكرآ لك على أهتمامك.





إذا كنت ترغب في مشاركة هذه المقالة مع جمهور يتحدث الإنجليزية ، فيرجى استخدام رابط الترجمة: نيكولاي ميرونوف. تحليل طلبات الدمج في GitLab باستخدام PVS-Studio لـ C # .



All Articles