03

البنية المعمارية

الطبقات، وخريطة الوحدات، ومراحل التحليل السبع، وتدفق البيانات بين الوحدات

5 دقائق قراءة6 أقسام

الطبقات

CleanLens مشروع TypeScript فيه محرّك واحد وواجهتان خفيفتان.

text
┌──────────────────────────────┐   ┌──────────────────────────────┐
│  VS Code extension           │   │  CLI                         │
│  src/extension.ts            │   │  src/cli/index.ts            │
│  src/views/*                 │   │  src/cli/format.ts           │
└──────────────┬───────────────┘   └──────────────┬───────────────┘
               │   analyzeRepository(root, opts)  │
               └───────────────┬──────────────────┘
                               ▼
┌────────────────────────────────────────────────────────────────┐
│  Core pipeline — src/core/analyzeRepository.ts (no VS Code API) │
├──────────────┬──────────────┬───────────────┬──────────────────┤
│ git/         │ configuration│ analyzers/    │ attribution/     │
│ git commands │ config, rules│ rule checks   │ commit replay    │
│ + identities │ presets,     │ per file      │ + fingerprints   │
│              │ excludes     │               │                  │
├──────────────┴──────────────┴───────────────┼──────────────────┤
│ cache/ — per-commit results on disk         │ scoring/ — score │
└─────────────────────────────────────────────┴──────────────────┘
  • فقط src/extension.ts وsrc/views/* تستورد vscode. كل ما عداهما Node.js عادي، ولهذا يمكن تشغيله من أداة سطر الأوامر ومن الاختبارات.
  • لا توجد اعتماديات وقت التشغيل سوى typescript (يستخدمه محلل JS كـ parser، ويدمجه esbuild في الحزمة). كل الوصول إلى Git يتم عبر execFile("git", …).

خريطة الوحدات

المجلدالملفالمسؤولية
src/extension.tsالتفعيل، وتسجيل الأوامر، وواجهة التقدّم، وقراءة إعدادات VS Code، وربط التنبيهات المباشرة
src/core/analyzeRepository.tsخط التحليل المشترك؛ يدمج الإعدادات فوق ملف الإعدادات؛ يبني الذاكرة المؤقتة؛ ويعيد ProjectReport
src/cli/index.tsتحليل المعاملات، ورموز الخروج، والتعامل مع stdout/stderr
format.tsالتقرير ← نص / Markdown؛ وفحص --fail-on
src/git/gitService.ts"هل هذا مستودع؟"، "هل فيه commits؟"، وgit log لإحصاءات المساهمين
contributors.tsيجمع الـ commits في مطورين؛ ويدمج الهويات المكررة
commitHistory.tsيسرد الـ commits غير الدمجية (أحدث N / منذ تاريخ)، من الأقدم للأحدث
diffService.tsأمر git diff واحد لكل commit ← الملفات المتغيرة، ومدى الأسطر، ومعرّفات الـ blobs؛ وgit cat-file --batch لقراءة الـ blobs
blameService.tsمحلل لمخرجات git blame --line-porcelain. قديم (من محرّك blame السابق)؛ ما زال مختبَراً، ولا يستخدمه خط التحليل
src/configuration/types.tsأنواع الإعدادات، ومعرّفات القواعد الأربع عشرة وعناوينها وفئاتها، وأسماء الملفات
configValidator.tsالتحقق من بنية .clean-code-tracker.json
configLoader.tsتحميل الإعدادات (أو الإعداد المسبق الافتراضي)، ودمج التخصيص المحلي، وكتابة ملف إعدادات جديد
presets.tsالإعدادات المسبقة الأربعة؛ واكتشاف الإعداد المناسب تلقائياً
excludes.tsالاستثناءات المدمجة؛ وقراءة .gitignore / .gitattributes؛ وكشف ترويسة الملفات المولَّدة
src/analyzers/fileScanner.tsاستعراض المجلدات لفحص HEAD
glob.tsتحويل glob بسيط إلى RegExp، وExcludeMatcher
jsAnalyzer.tsقواعد مبنية على شجرة AST لـ JS/TS (واجهة مترجم TypeScript)
pyAnalyzer.tsقواعد مبنية على الأسطر والمسافة البادئة لـ Python
duplicateCode.tsكشف الكتل المكررة بنافذة منزلقة
secrets.ts، names.tsقواعد تقديرية مشتركة للأسرار والأسماء غير الواضحة
model.tsRawFinding ← Violation؛ ودوال مساعدة لقراءة تفعيل القاعدة وحدّها وخياراتها
runAnalyzers.tsتنسيق فحص HEAD؛ واختيار المحلل حسب امتداد الملف
analyzeRevision.tsتحليل نسخة واحدة من ملف (blob) وإعطاء كل مخالفة بصمة
src/attribution/commitAttribution.tsيمر على الـ commits، ويقارن قبل/بعد، ويصنّف كل مخالفة
attributeReport.tsيدمج مخالفات HEAD مع نتائج الـ commits؛ ويقيّم المطورين
fingerprint.tsدالة hash من نوع FNV-1a؛ والبصمة الثابتة للمخالفة
ownership.tsخريطة البريد الإلكتروني ← معرّف المطوّر (+ دوال blame القديمة)
src/scoring/scoringConfig.tsكل ثابت قابل للضبط: الأوزان، والمقاييس، والقيمة المسبقة، والحدود، وENGINE_VERSION
cleanCodeScore.tsمعادلة الدرجة
src/cache/analysisCache.tsذاكرة JSON المؤقتة لكل commit + بصمة الإعدادات
src/types/index.tsSeverity وViolation وDeveloper وProjectReport والحالات
src/views/treeProviders.tsأشجار الشريط الجانبي + ReportStore
dashboardPanel.tsدورة حياة لوحة الـ webview ورسائلها
dashboardHtml.tsتوليد HTML/CSS/JS خالص للوحة المعلومات
diagnostics.tsتنبيهات المحرر: تغذية التقرير الكامل والتغذية المباشرة

خط التحليل خطوة بخطوة

الدالة analyzeRepository(root, opts) في src/core/analyzeRepository.ts:

text
 1. Git checks        git rev-parse --is-inside-work-tree, git rev-parse HEAD
 2. Config            loadConfig()  →  applySettings(VS Code / CLI overrides)
                      readRepoAttributes() (.gitignore, .gitattributes)
                      mergedExcludeGlobs(), resolveScoring(), analysisConfigHash()
 3. Developers        git log --no-merges → aggregateContributors() → toDevelopers()
 4. HEAD scan         analyzeProject(): walk files → analyzer per file → duplicates
                      → sorted Violation[]
 5. Commit walk       attributeCommits(): newest N commits, oldest first,
                      12 in parallel, each: diff → blobs → analyze before/after
                      → introduced / fixed / existing
 6. Merge + score     attributeReport(): fingerprint every HEAD violation, look up
                      its origin, set status/confidence/developer; compute the
                      project prior; score every developer
 7. Display           extension: tree views, dashboard, diagnostics
                      CLI: text / Markdown / JSON + exit code

المراحل:

  1. فحوصات Git: هل المجلد مستودع؟ وهل فيه commit؟
  2. الإعدادات: تحميل ملف الإعدادات ودمج إعدادات VS Code أو خيارات سطر الأوامر فوقه، وقراءة .gitignore و.gitattributes، وبناء قائمة الاستثناءات وثوابت التقييم وبصمة الإعدادات.
  3. المطورون: قراءة سجل Git وتجميع الـ commits في مطورين.
  4. فحص HEAD: تحليل الملفات الحالية وإنتاج قائمة المخالفات مرتبة.
  5. مرور الـ commits: أحدث N commit من الأقدم للأحدث، 12 بالتوازي؛ لكل واحد: diff ← blobs ← تحليل قبل/بعد ← أُدخلت / أُصلحت / موجودة سابقاً.
  6. الدمج والتقييم: بصمة لكل مخالفة في HEAD، والبحث عن أصلها، وتحديد حالتها وثقتها ومطوّرها؛ ثم حساب متوسط المشروع وتقييم كل مطوّر.
  7. العرض: في الإضافة: الأشجار ولوحة المعلومات والتنبيهات؛ وفي سطر الأوامر: نص / Markdown / JSON + رمز الخروج.

المراحل 1–6 متطابقة في الواجهتين. الذي يختلف هو الخيارات فقط:

الخيارالإضافةأداة سطر الأوامر
configيُحمَّل من المستودعيُحمَّل من المستودع، أو --preset
settingsمن إعدادات VS Code ‏(cleanlens.*)من --max-commits و--full-history و--since
cacheDircontext.globalStorageUri<os tmpdir>/cleanlens-cache
cachecleanlens.cache.enabledيُعطَّل بـ --no-cache
signalزر Cancel في إشعار التقدّملا يوجد

الأخطاء المتوقعة

يُرمى AnalysisError في المشاكل التي يستطيع المستخدم إصلاحها: المجلد ليس مستودع Git، ولا توجد commits، وملف الإعدادات غير صالح. الإضافة تعرضه كرسالة خطأ، وأداة سطر الأوامر تطبع error: … وتخرج بالرمز 2. أي استثناء آخر يعني وجود خلل في الكود.

تدفق البيانات والأنواع

text
RawFinding  ──toViolation()──▶  Violation (severity, category, weight, id)
                                   │
       analyzeRevision()           │  fingerprintFor()
                                   ▼
RevisionViolation (+fingerprint) ─▶ CommitContribution (per commit, cached)
                                   │
                    attributeCommits() aggregates
                                   ▼
            DeveloperAttribution (per developer) + origins (fingerprint → commit)
                                   │
                        attributeReport()
                                   ▼
                  ProjectReport { developers[], violations[] }

تعريفات الأنواع موجودة في src/types/index.ts وsrc/configuration/types.ts. وصيغة التقرير موثّقة حقلاً بحقل في 14 — بنية التقرير.

تحليلان لغرضين مختلفين

هذه أهم نقطة في التصميم يجب فهمها:

فحص HEAD (المرحلة 4)مرور الـ commits (المرحلة 5)
المدخلالملفات الموجودة على القرص الآنالـ blobs من سجل Git
المخرجقائمة المخالفات التي تُعرض لكمن أدخل / أصلح ماذا، والأسطر المحللة
كشف التكرارعبر كل الملفاتداخل كل ملف فقط
النطاقكل ملف قابل للتحليلفقط الملفات التي غيّرتها الـ commits المحللة

المرحلة 6 تربط بينهما بالبصمات. مخالفة في HEAD أُدخلت بصمتها أثناء مرور الـ commits تُنسب إلى كاتب ذلك الـ commit. ومخالفة في HEAD لم تظهر أبداً أثناء المرور هي أقدم من نافذة التحليل ← existing.

مخرجات البناء

يجمّع esbuild ملفين مستقلين:

  • dist/extension.js — نقطة الدخول src/extension.ts، ويبقى vscode خارج الحزمة.
  • dist/cli.js — نقطة الدخول src/cli/index.ts، مع سطر #!/usr/bin/env node في البداية؛ ويُعرض كأمر cleanlens.

انظر 15 — دليل التطوير لأوامر البناء.