البدء
التثبيت
ثبّت Greph عبر Composer:
composer require greph/greph
يثبّت هذا المكتبة إلى جانب أربعة ملفات تنفيذية في vendor/bin/:
greph: بحث نصي أصلي، وبحث AST، وإعادة كتابة ASTgreph-index: فهرس نصي مُحمّى، وفهرس حقائق AST، وبحث AST مخزّن مؤقتًاrg: غلاف توافق بأسلوب ripgrepsg: غلاف توافق بأسلوب ast-grep
تعمل هذه الملفات التنفيذية انطلاقًا من vendor/bin/ الخاص بمشروعك منذ Greph 0.2.3. أما الإصدارات الأقدم فلم تكن تعثر على محمّل Composer التلقائي إلا داخل نسخة مستنسخة من مستودع Greph، لذا اشترط هذا الإصدار على الأقل:
composer require greph/greph:^0.2.3
المتطلبات
- PHP 8.2+ لدعم الأصناف للقراءة فقط والتعدادات وصياغة الدوال القابلة للاستدعاء من الدرجة الأولى وترقية المنشئات
- ext-json لمخرجات JSON وبيانات حمولة الفهرس المخزنة على القرص
- ext-ctype لتحليل الأنماط والخيارات
- ext-tokenizer لـ PHP-Parser ومرشحات AST المسبقة
- ext-zlib لمخزن AST المؤقت (
greph-index ast-cache) - nikic/php-parser (يُثبّت تلقائيًا باعتباره اعتماد Composer)
تكون ext-json وext-ctype وext-tokenizer مفعّلة في جميع إصدارات PHP تقريبًا. يصرّح composer.json حاليًا عن ext-json فقط (#5)، لذا لا يصدر Composer تحذيرًا عند غياب أي من الإضافات الأخرى.
اختياري:
- ext-pcntl لإجراء عمليات المسح بالتوازي. يعمل Greph بسلاسة في عملية واحدة عند غيابه.
- ملفات تنفيذية خارجية لـ
rgوgrepوsgلمقارنات الأداء. لا تكون مطلوبة مطلقًا أثناء التشغيل.
لا تستدعي عمليات البحث وإعادة الكتابة والفهرسة proc_open() أو shell_exec() مطلقًا؛ إذ تُنشئ عمليات المسح المتوازية عمليات فرعية فقط، وتعود إلى عملية واحدة عند غياب pcntl_fork(). راجع المضيفون المقيّدون بالعمليات للتعرّف على المضيفين الذين يعطّلون proc_open() أو shell_exec() أو pcntl_fork().
أول بحث نصي لك
الوضع الافتراضي لـ Greph هو البحث النصي المتوافق مع grep:
vendor/bin/greph -F "function" src
يستخدم الإخراج تنسيق file:line:content القياسي الذي تتوقعه grep وripgrep ومعظم تكاملات المحررات.
src/Greph.php:41: public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
src/Greph.php:50: public static function searchText(string $pattern, string|array $paths, ?TextSearchOptions $options = null): array
src/Greph.php:81: public static function buildTextIndex(
أضف -i لمطابقة الأحرف دون تمييز حالة الأحرف، و-w لمطابقة الكلمات كاملة، و-c لإظهار الأعداد، و-l لمسارات الملفات فقط، و-C 2 لإظهار سطرين من السياق، وما إلى ذلك. تجد القائمة الكاملة في مرجع CLI.
أول بحث AST لك
مرّر -p ونمطًا بصيغة PHP للانتقال إلى البحث البنيوي:
vendor/bin/greph -p 'new $CLASS()' src
$CLASS متغير وصفي يلتقط أي اسم فئة. يطابق النمط new $CLASS() كل تعبير new بلا وسيطات، بصرف النظر عن الفئة أو التنسيق أو التعليقات. استخدم new $CLASS($$$ARGS) لمطابقة الاستدعاءات التي تتضمن أي وسيطات.
تُطبع كل مطابقة AST مع الملف وسطر البداية والأكواد المطابقة:
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
أنماط أخرى مفيدة:
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src
# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src
# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' src
راجع الأوضاع / بحث AST للاطلاع على صياغة الأنماط كاملة.
أول إعادة كتابة لك
أضف -r لتحويل بحث AST إلى إعادة كتابة:
# Preview only
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src
# Apply
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' src
# Confirm each file before writing
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --interactive src
تحافظ عمليات إعادة الكتابة على التنسيق خارج الجزء المطابق: تُستبدل العقدة المطابقة وحدها، مع إبقاء المسافات البادئة والمسافات البيضاء والتعليقات المحيطة كما هي. أما العقدة المطابقة نفسها فتُطبع مجددًا من القالب، لذا يُوحّد تنسيقها وقد يُفقد تعليق بداخلها. راجع الأوضاع / إعادة الكتابة للتفاصيل.
PHP API
توفّر الواجهة الثابتة Greph\Greph العمليات نفسها التي توفّرها CLI:
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;
$results = Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, caseInsensitive: true),
);
foreach ($results as $file) {
foreach ($file->matches as $match) {
echo "{$file->file}:{$match->line}:{$match->content}\n";
}
}
$matches = Greph::searchAst(
'new $CLASS()',
'src',
new AstSearchOptions(),
);
foreach ($matches as $match) {
echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
يغطي مرجع API الواجهة كاملة.
البحث المفهرس
تستفيد أحمال العمل المتكررة من الفهارس المُحمّاة. أنشئ الفهرس مرة واحدة، ثم أجرِ الاستعلامات مرات عديدة:
# Text index
vendor/bin/greph-index build .
vendor/bin/greph-index search -F "function" .
# AST fact index
vendor/bin/greph-index ast-index build .
vendor/bin/greph-index ast-index search 'new $CLASS()' src
# Cached parsed-tree index
vendor/bin/greph-index ast-cache build .
vendor/bin/greph-index ast-cache search 'array($$$ITEMS)' src
توجد الفهارس افتراضيًا في .greph-index و.greph-ast-index و.greph-ast-cache ضمن جذر المشروع.
في الأشجار التي تتغير باستمرار، اختر ملف تعريف لدورة الحياة بدلًا من التعامل مع كل فهرس مُحمّى بالطريقة نفسها:
vendor/bin/greph-index build . --lifecycle static
vendor/bin/greph-index build . \
--lifecycle opportunistic-refresh \
--auto-refresh-max-files 32 \
--auto-refresh-max-bytes 1048576
vendor/bin/greph-index stats . --dry-refresh
النمط الشائع هو:
- احتفظ بخط أساس مستقر كـ
static - احتفظ بالتراكبات التي تتغير باستمرار كـ
opportunistic-refresh - افحص السلوك عند تقادم البيانات باستخدام
stats --dry-refresh
البحث في عدة فهارس مُحمّاة
يمكنك البحث في عدة فهارس مُحمّاة بأمر واحد:
vendor/bin/greph-index search -F "apply_filters" . \
--index-dir wordpress/.greph-index \
--index-dir wp-content/plugins/my-plugin/.greph-index \
--show-index-origin
vendor/bin/greph-index ast-index search 'new $CLASS()' . \
--index-dir wordpress/.greph-ast-index \
--index-dir wp-content/plugins/my-plugin/.greph-ast-index \
--show-index-origin
مجموعات الفهارس المسماة
إذا كنت تفعل ذلك باستمرار، فضع تخطيط الفهارس في .greph-index-set.json واستخدم الأوامر الفرعية للمجموعة بدلًا من تكرار الخيارات:
vendor/bin/greph-index set build
vendor/bin/greph-index set stats --dry-refresh
vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
vendor/bin/greph-index set search --mode ast-index 'new $CLASS()' .
vendor/bin/greph-index set search --mode ast-cache 'array($$$ITEMS)' .
تتبّع المخطِّط
لمعرفة كيفية تضييق البحث المُحمّى لنطاق المرشحين، أضف --trace-plan:
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
راجع المفهرس / النص والمفهرس / AST للاطلاع على سير العمل المُحمّى كاملًا.
أغلفة التوافق
إذا كانت لديك أدوات أو وكلاء يتعاملون بالفعل مع ripgrep أو ast-grep، فأضف الأغلفة التالية:
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
يعيد الغلافان استخدام المحرك نفسه، وقد جرى التحقق منهما باستخدام ملفات تنفيذية للمشروعات الأصلية. توثّق التوافق / rg والتوافق / sg الواجهات التي تم التحقق منها، كما يعرضها جدول الميزات المُنشأ.
الإعداد
يتعرّف Greph على اصطلاحين للتخزين على القرص:
.gitignore: يُطبّق افتراضيًا. مرّر--no-ignoreلتعطيله..grephignore: الصياغة نفسها مثل.gitignore، وتُطبّق فوقه. مفيد للاستثناءات الخاصة بالأداة التي لا تريد حفظها في نظام التحكم بالإصدارات.
مجلدات الفهرس الافتراضية هي .greph-index و.greph-ast-index و.greph-ast-cache في الجذر المحدد. تجاوزها باستخدام --index-dir مع أي أمر فرعي من greph-index، أو استخدم .greph-index-set.json لتخطيطات متعددة الفهارس قابلة للتكرار.