codeclimate-duplication هو محرك يلف Flay ويدعم Java و Ruby و Python و JavaScript و PHP. يمكنك تشغيله على سطر الأوامر باستخدام Code Climate CLI أو على منصة التحليل المستضافة.
يمكن أن تكون خوارزمية محرك الازدواجية مفاجئة ، لكنها في الواقع بسيطة للغاية. لدينا صفحة مستندات تشرح الخوارزمية.
cd في مجلد مشروعك وتشغيل codeclimate analyze . يتم تمكين تحليل الازدواجية بشكل افتراضي ، لذلك لا تحتاج إلى فعل أي شيء آخر. قمنا بتعيين الإعدادات الافتراضية للعتبة المفيدة للغات التي ندعمها ولكن قد ترغب في ضبط هذه الإعدادات بناءً على إرشادات المشروع الخاصة بك.
يمثل تكوين عتبة الكتلة الحد الأدنى "الكتلة" التي يجب أن يتم تحليل كتلة التعليمات البرمجية للتكرار. إذا كان المحرك هو الإبلاغ بسهولة عن الازدواجية ، فحاول رفع العتبة. إذا كنت تشك في أن المحرك لا يصطاد ما يكفي من الازدواجية ، فحاول خفض العتبة. أفضل إعداد يميل إلى الاختلاف من اللغة إلى اللغة.
لضبط هذا الإعداد ، استخدم مفتاح checks العليا في ملف التكوين الخاص بك:
checks :
identical-code :
config :
threshold : 25
similar-code :
config :
threshold : 50 لاحظ أن لديك تحديث بنية YAML ضمن مفتاح languages إلى نوع التجزئة لدعم التكوين الإضافي.
بشكل افتراضي ، سيقوم محرك التكرار بالإبلاغ عن رمز تم تكراره في موقعين فقط. يمكنك أن تكون أقل صرامة من خلال رفع تحذير فقط إذا تم تكرار الكود في ثلاثة مواقع أو أكثر فقط. لضبط هذا الإعداد ، أضف مفتاح count_threshold إلى التكوين الخاص بك. على سبيل المثال ، لاستخدام mass_threshold الافتراضية لـ Ruby ، ولكن لفرض قاعدة ثلاثة ، يمكنك استخدام هذا التكوين:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
count_threshold : 3 يمكنك أيضًا تغيير count_threshold الافتراضي لجميع اللغات:
plugins :
duplication :
enabled : true
config :
count_threshold : 3 تتحقق جميع المحركات فقط من الملفات المناسبة ولكن يمكنك تجاوز مجموعة الأنماط الافتراضية. يتم تشغيل الأنماط مقابل دليل جذر المشروع ، لذا عليك استخدام ** لمطابقة الملفات في الدلائل المتداخلة. لاحظ أيضًا أنه يتعين عليك تحديد جميع الأنماط ، وليس فقط الأنماط التي تريد إضافتها.
plugins :
duplication :
enabled : true
config :
languages :
ruby :
patterns :
- " **/*.rb
- " **/*.rake"
- " Rakefile "
- " **/*.ruby " بشكل افتراضي ، سيستخدم محرك الازدواجية محلل بيثون 2. لتمكين تحليل رمز Python 3 ، حدد python_version كما هو موضح في المثال أدناه. سيمكن ذلك محلل Python 3 وإضافة ملحق ملف .py3 إلى قائمة أنماط الملفات المضمنة.
plugins :
duplication :
enabled : true
config :
languages :
python :
python_version : 3في بعض الأحيان يتم الإبلاغ عن أوجه التشابه الهيكلية أنك لا تهتم بها. على سبيل المثال ، قد تحتوي محتويات المصفوفات أو التجزئة على هياكل مماثلة ولا يوجد الكثير مما يمكنك فعله لإعادة تشكيلها. يمكنك تحديد المرشحات الخاصة باللغة لتجاهل أي مشكلات تتطابق مع النمط. فيما يلي مثال على ترشيح تجزئة بسيطة ومصفوفات:
plugins :
duplication :
enabled : true
config :
languages :
ruby :
filters :
- " (hash (lit _) (str _) ___) "
- " (array (str _) ___) " بناء الجملة للأنماط بسيطة جدا. في النمط الأول: "(hash (lit _) (str _) ___)" يحدد "تجزئة مع مفتاح حرفي ، قيمة سلسلة ، تليها أي شيء آخر (بما في ذلك لا شيء)". يمكنك أيضًا تحديد "(hash ___)" لتجاهل جميع التجزئة تمامًا.
معرفة ما يجب تصفية أمر صعب. يأتي الترميز الترميز مع خيار تكوين للمساعدة في الاكتشاف. بدلاً من مسح الكود الخاص بك وطباعة المشكلات الخاصة بـ CodecLimate ، فإنه يطبع أشجار التحليل بدلاً من ذلك! فقط أضف dump_ast: true debug: true في ملف .codeclimate.yml:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
debug: true
... rest of config ...
ثم قم بتشغيل codeclimate analyze أثناء استخدام علامة التصحيح لإخراج Stderr:
% CODECLIMATE_DEBUG=1 codeclimate analyze
قد يؤدي تشغيل هذا الأمر إلى إخراج شيء مثل:
Sexps for issues:
# 1) ExpressionStatement#4261258897 mass=128:
# 1.1) bogus-examples.js:5
s(:ExpressionStatement,
:expression,
s(:AssignmentExpression,
:"=",
:left,
s(:MemberExpression,
:object,
s(:Identifier, :EventBlock),
:property,
s(:Identifier, :propTypes)),
... LOTS more...)
... even more LOTS more...)
هذا هو التمثيل الداخلي للرمز الفعلي. على افتراض أنك نظرت إلى هذه المشكلات وحددتها ألا تكون مشكلة تريد معالجتها ، يمكنك تصفيةها عن طريق كتابة سلسلة نمط من شأنها أن تتطابق مع تلك الشجرة.
بالنظر إلى إخراج الشجرة مرة أخرى ، هذه المرة تسطيته:
s(:ExpressionStatement, :expression, s(:AssignmentExpression, :"=",:left, ...) ...)
يختلف التمثيل الداخلي (وهو روبي) عن لغة النمط (التي تشبه lisp) ، لذلك أولاً نحتاج إلى تحويل s(: إلى ( وإزالة جميع الفواصل والكولون:
(ExpressionStatement expression (AssignmentExpression "=" left ...) ...)
بعد ذلك ، لا نهتم expression عن المباراة ، لذلك دعونا نتخلص من ذلك عن طريق استبداله بالمطابقة لأي عنصر واحد _ :
(ExpressionStatement _ (AssignmentExpression "=" left ...) ...)
ينطبق الشيء نفسه على "=" left ، لكننا في الواقع لا نهتم بباقي عقدة التعيين ، لذلك دعونا نستخدم المطابقة التي ستتجاهل بقية الشجرة ___ :
(ExpressionStatement _ (AssignmentExpression ___) ...)
وأخيرًا ، لا نهتم بما يلي في ExpressionStatement لذلك دعونا نتجاهل الباقي أيضًا:
(ExpressionStatement _ (AssignmentExpression ___) ___)
يقرأ هذا: "أي عقدة تعبير ، مع أي قيمة وعقدة التخصيص مع أي شيء فيه ، تليها أي شيء آخر". هناك طرق أخرى لكتابة نمط لمطابقة هذه الشجرة ، ولكن هذا واضح للغاية.
ثم يمكنك إضافة هذا المرشح إلى التكوين الخاص بك:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
languages:
javascript:
filters:
- "(ExpressionStatement _ (AssignmentExpression ___) ___)"
ثم إعادة تشغيل المحلل واكتشف ما يجب أن يكون المرشح التالي. عندما تكون سعيدًا بالنتائج ، قم بإزالة تكوين dump_ast (أو قم بتعيينه على خطأ) للعودة إلى التحليل العادي.
لمزيد من المعلومات حول مطابقة الأنماط ، راجع sexp_processor ، وخاصة sexp.rb