codeclimate-duplication เป็นเครื่องยนต์ที่ห่อหุ้มและรองรับ Java, Ruby, Python, JavaScript และ PHP คุณสามารถเรียกใช้บนบรรทัดคำสั่งโดยใช้รหัส CIMITY CLI หรือบนแพลตฟอร์มการวิเคราะห์ที่โฮสต์ของเรา
อัลกอริทึมของเอ็นจิ้นการทำซ้ำน่าแปลกใจ แต่จริงๆแล้วมันง่ายมาก เรามีหน้าเอกสารอธิบายอัลกอริทึม
cd ลงในโฟลเดอร์ของโครงการของคุณและเรียกใช้ codeclimate analyze การวิเคราะห์การทำซ้ำถูกเปิดใช้งานโดยค่าเริ่มต้นดังนั้นคุณไม่จำเป็นต้องทำอย่างอื่น เราตั้งค่าเริ่มต้นเกณฑ์ที่เป็นประโยชน์สำหรับภาษาที่เราสนับสนุน แต่คุณอาจต้องการปรับการตั้งค่าเหล่านี้ตามแนวทางโครงการของคุณ
การกำหนดค่าเกณฑ์มวลหมายถึงขั้นต่ำ "มวล" บล็อกรหัสต้องได้รับการวิเคราะห์สำหรับการทำซ้ำ หากเครื่องยนต์รายงานการทำซ้ำได้ง่ายเกินไปลองเพิ่มเกณฑ์ หากคุณสงสัยว่าเครื่องยนต์ไม่ได้ทำซ้ำเพียงพอให้ลองลดเกณฑ์ การตั้งค่าที่ดีที่สุดมีแนวโน้มที่จะแตกต่างจากภาษาเป็นภาษา
ในการปรับการตั้งค่านี้ให้ใช้คีย์ checks ระดับบนสุดในไฟล์กำหนดค่าของคุณ:
checks :
identical-code :
config :
threshold : 25
similar-code :
config :
threshold : 50 โปรดทราบว่าคุณมีการอัปเดตโครงสร้าง YAML ภายใต้คีย์ languages เป็นประเภทแฮชเพื่อรองรับการกำหนดค่าพิเศษ
โดยค่าเริ่มต้นเอ็นจิ้นการทำซ้ำจะรายงานรหัสที่ซ้ำกันในสองสถานที่ คุณสามารถเข้มงวดน้อยลงโดยการเพิ่มคำเตือนหากรหัสซ้ำกันในสถานที่สามแห่งขึ้นไปเท่านั้น ในการปรับการตั้งค่านี้ให้เพิ่มปุ่ม count_threshold ในการกำหนดค่าของคุณ ตัวอย่างเช่นในการใช้ mass_threshold เริ่มต้นสำหรับทับทิม แต่เพื่อบังคับใช้กฎสามข้อคุณสามารถใช้การกำหนดค่านี้:
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 " โดยค่าเริ่มต้นเอ็นจิ้นการทำซ้ำจะใช้ตัวแยกวิเคราะห์ Python 2 ในการเปิดใช้งานการวิเคราะห์สำหรับรหัส Python 3 ให้ระบุ python_version ดังแสดงในตัวอย่างด้านล่าง สิ่งนี้จะเปิดใช้งานตัวแยกวิเคราะห์ Python 3 และเพิ่มส่วนขยายไฟล์ .py3 ในรายการรูปแบบไฟล์ที่รวมอยู่
plugins :
duplication :
enabled : true
config :
languages :
python :
python_version : 3บางครั้งความคล้ายคลึงกันของโครงสร้างมีรายงานว่าคุณไม่สนใจ ตัวอย่างเช่นเนื้อหาของอาร์เรย์หรือแฮชอาจมีโครงสร้างที่คล้ายกันและมีเพียงเล็กน้อยที่คุณสามารถทำได้เพื่อ refactor พวกเขา คุณสามารถระบุตัวกรองเฉพาะภาษาเพื่อละเว้นปัญหาใด ๆ ที่ตรงกับรูปแบบ นี่คือตัวอย่างที่กรองแฮชและอาร์เรย์ง่าย ๆ :
plugins :
duplication :
enabled : true
config :
languages :
ruby :
filters :
- " (hash (lit _) (str _) ___) "
- " (array (str _) ___) " ไวยากรณ์สำหรับรูปแบบนั้นค่อนข้างง่าย ในรูปแบบแรก: "(hash (lit _) (str _) ___)" ระบุ "แฮชที่มีคีย์ตัวอักษรค่าสตริงตามด้วยสิ่งอื่นใด (รวมถึงไม่มีอะไร)" คุณสามารถระบุ "(hash ___)" เพื่อเพิกเฉยต่อแฮชทั้งหมดทั้งหมด
การหาสิ่งที่ต้องกรองนั้นยุ่งยาก CodeClimate-Duplection มาพร้อมกับตัวเลือกการกำหนดค่าเพื่อช่วยในการค้นพบ แทนที่จะสแกนรหัสของคุณและพิมพ์ปัญหาสำหรับ 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, ...) ...)
การเป็นตัวแทนภายใน (ซึ่งเป็นทับทิม) นั้นแตกต่างจากภาษารูปแบบ (ซึ่งเป็นเหมือนเสียงกระเพื่อม) ดังนั้นก่อนอื่นเราต้องแปลง s(: เป็น ( และลบเครื่องหมายจุลภาคและ colons ทั้งหมด:
(ExpressionStatement expression (AssignmentExpression "=" left ...) ...)
ต่อไปเราไม่สนใจ expression การแข่งขันดังนั้นเรามากำจัดสิ่งนั้นโดยแทนที่ด้วยตัวจับคู่สำหรับองค์ประกอบเดียว _ ::
(ExpressionStatement _ (AssignmentExpression "=" left ...) ...)
เช่นเดียวกันสำหรับ "=" และ left แต่เราไม่สนใจเกี่ยวกับส่วนที่เหลือของโหนดการแสดงออกที่เหลือดังนั้นลองใช้ตัวจับคู่ที่จะไม่สนใจส่วนที่เหลือของต้นไม้ ___ :
(ExpressionStatement _ (AssignmentExpression ___) ...)
และในที่สุดเราก็ไม่สนใจสิ่งที่ตามมาใน ExpressionStatement ดังนั้นขอให้เพิกเฉยต่อส่วนที่เหลือด้วย:
(ExpressionStatement _ (AssignmentExpression ___) ___)
สิ่งนี้อ่านได้ว่า: "โหนด ExpressionStatement ใด ๆ ที่มีค่าใด ๆ และโหนดการมอบหมายงานที่มีสิ่งใดในนั้นตามด้วยสิ่งอื่นใด" มีวิธีอื่นในการเขียนรูปแบบเพื่อให้ตรงกับต้นไม้นี้ แต่มันค่อนข้างชัดเจน
จากนั้นคุณสามารถเพิ่มตัวกรองนั้นลงในการกำหนดค่าของคุณ:
---
plugins:
duplication:
enabled: true
config:
dump_ast: true
languages:
javascript:
filters:
- "(ExpressionStatement _ (AssignmentExpression ___) ___)"
จากนั้นเรียกใช้เครื่องวิเคราะห์อีกครั้งและหาว่าตัวกรองถัดไปควรเป็นอย่างไร เมื่อคุณมีความสุขกับผลลัพธ์ให้ลบ dump_ast config (หรือตั้งค่าเป็นเท็จ) เพื่อกลับไปที่การวิเคราะห์ปกติ
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการจับคู่รูปแบบดู sexp_processor โดยเฉพาะ sexp.rb