doctordanila / scancore
Console tool to scan project structure and dump file contents, respecting .scancoreignore
Requires
- php: >=7.4
README
Консольный инструмент для сканирования файловой структуры PHP-проекта и генерации дампа содержимого файлов с учётом правил игнорирования (.scancoreignore). Полезен для передачи контекста проекта в LLM, анализа кода, ревью или документирования.
Возможности
- init - команда для явного создания или перезаписи файла
.scancoreignore. При первом запуске любой команды файл также создаётся автоматически (если отсутствует). - tree - отображение структуры проекта в виде дерева (аналог команды
treeв Linux). - dump - создание текстового файла со всеми неигнорируемыми файлами и их содержимым.
- stats - сбор расширенной статистики по проекту:
- Общее количество файлов и строк кода (без учёта пустых строк и комментариев).
- Среднее количество строк на файл.
- Распределение по типам файлов (PHP, JS, CSS, конфиги и т.д.).
- Самые большие файлы (топ-10 по размеру).
- Файлы с наибольшим количеством зависимостей (входящих и исходящих) - анализ
use,extends,implementsдля PHP. - Активность по дням (количество изменённых файлов за последние даты).
- Генерация HTML-отчёта с интерактивным графом зависимостей (на русском языке).
- Генерация JSON-файла с полной информацией для дальнейшего анализа LLM.
- Интеллектуальная фильтрация для команд
dumpиstats:- Фильтр по именам классов или неймспейсов (
--class). - Фильтр по содержимому файла (регулярное выражение,
--pattern). - Фильтр по типу файла (например, только контроллеры, только модели) на основе имени файла (
--type). - Фильтр по реализуемому интерфейсу (
--impl). - Фильтр по наследуемому классу (
--ext). - Фильтр по использованию трейта/класса (оператор
use) (--use). - Возможность комбинировать несколько фильтров (логическое И) и передавать несколько значений через запятую или повторением опции.
- Фильтр по именам классов или неймспейсов (
- Временные исключения из командной строки - флаг
--ignore=шаблондля командtree,dump,stats. Позволяет временно добавить правила игнорирования помимо основного файла.scancoreignore. Управляется через файл.env(можно исключить отдельные команды). - Поддержка
.scancoreignoreс синтаксисом, близким к.gitignore(кроме негативных шаблонов!). - Фильтрация по подпапке для всех команд.
- Кроссплатформенность (Windows, Linux, macOS).
Требования
- PHP 7.4 или выше.
Установка
Установите пакет через Composer (рекомендуется в require-dev):
composer require doctordanila/scancore --dev
После установки исполняемый файл будет доступен как vendor/bin/scancore (в Windows - vendor\bin\scancore).
Настройка игнорирования
В корне проекта создайте файл .scancoreignore и перечислите пути/шаблоны, которые нужно исключить.
Правила обрабатываются аналогично .gitignore.
Не волнуйтесь если не знаете, что добавлять в файл игнорирования.
При первом запуске любой команды (tree, dump, stats) файл .scancoreignore создаётся автоматически, если его нет.
Сначала предпринимается попытка скопировать содержимое .gitignore из корня проекта.
Если .gitignore отсутствует, генерируется базовый шаблон со стандартными исключениями (системные папки, зависимости, логи, конфигурации, git). Для явного создания или принудительной перезаписи используйте команду init (см. ниже).
Пример:
# Системные папки
.idea
.vscode
.DS_Store
# Зависимости
/vendor
/node_modules
# Логи и временные файлы
*.log
/runtime
# Конфигурации окружения
.env
/phpunit.xml
# Git
.git/
.github/
Пояснения:
/vendor - игнорируется только папка vendor в корне.
.idea - игнорируется на любом уровне.
tests/_output/* - игнорируются файлы внутри tests/_output/ (но только в корне).
**/tests/_output/ - папка _output на любом уровне (слеш в конце означает "только директория").
Использование
Команда tree
Вывод полной структуры проекта:
vendor/bin/scancore tree
Вывод структуры только указанной подпапки (например, modules):
vendor/bin/scancore tree modules/tasks
Пример вывода:
modules/tasks/
├─ Module.php
├─ config/
│ └─ di.php
├─ domain/
│ ├─ entity/
│ │ └─ Task.php
│ └─ valueObject/
│ └─ TaskId.php
└─ presentation/
└─ controller/
└─ TaskController.php
Команда dump
Создание файла scancore_output.txt со всеми неигнорируемыми файлами и их содержимым:
vendor/bin/scancore dump
Указать имя выходного файла:
vendor/bin/scancore dump my_project_scan.txt
Ограничить дамп только файлами из определённой подпапки (например, modules/tasks):
vendor/bin/scancore dump . modules/tasks
Пояснения:
Команда нужна для того, чтобы вывести в единый файл всё содержимое файлов вашего проекта или отдельной его папки.
. во втором аргументе использует вывод в файл по умолчанию, используется, для того, чтобы не менять файл вывода, но указать определённую директорию сканирования
Содержимое результирующего файла:
Файл: modules/tasks/Module.php
<?php
// содержимое файла
Файл: modules/tasks/domain/entity/Task.php
<?php
// содержимое файла
...
Команда stats
Сбор статистики проекта и генерация двух отчётов: HTML (с графами и таблицами) и JSON (для LLM).
Базовый запуск (в текущей папке):
vendor/bin/scancore stats
Будут созданы файлы stats.html и stats_llm.txt.
Указать базовое имя файлов (например, myproject):
vendor/bin/scancore stats myproject
Создадутся myproject.html и myproject_llm.txt.
Ограничить анализ только подпапкой (например, src/):
vendor/bin/scancore stats . src
Здесь . означает использовать имя по умолчанию (stats), а src - подпапка для сканирования.
Что содержится в HTML-отчёте?
- Общая информация: количество файлов, строк кода, среднее количество строк на файл.
- Распределение по типам файлов (расширениям).
- Таблица самых больших файлов (топ-10).
- Таблица активности по дням (количество изменённых файлов за последние даты).
- Две таблицы зависимостей:
- Файлы, от которых чаще всего зависят другие (наибольшее количество входящих зависимостей).
- Файлы с наибольшим числом зависимостей (которые сами больше всего используют другие классы/интерфейсы).
- Интерактивный граф зависимостей для PHP-файлов (направленные рёбра: от файла к тому, от которого он зависит).
Что содержится в JSON-файле (*_llm.txt)?
Все данные в машиночитаемом формате, включая полный граф зависимостей, списки файлов с зависимостями и метрики. Удобно для передачи в LLM для дальнейшего анализа.
Интеллектуальная фильтрация (dump и stats)
Для команд dump и stats доступны следующие фильтры, позволяющие оставить только те файлы, которые удовлетворяют заданным критериям. Фильтры комбинируются по логическому И (файл должен удовлетворять всем указанным фильтрам). Внутри одного фильтра значения объединяются по ИЛИ (если передано несколько значений, достаточно совпадения с любым).
Доступные фильтры
| Опция | Описание | Пример значения | Поддержка в dump | Поддержка в stats |
|---|---|---|---|---|
--class |
Имена классов (полностью квалифицированные). Включает файлы, в которых встречается указанный класс. | App\Controller\UserController |
✅ | ✅ |
--pattern |
Регулярное выражение для поиска в содержимом файла. | "/function (calculate|compute)/i" |
✅ | ✅ |
--type |
Подстрока в имени файла (например, Controller, Model, Service). |
Controller |
✅ | ✅ |
--impl |
Имя интерфейса. Включает файлы, реализующие данный интерфейс. | Psr\Log\LoggerInterface |
❌ (игнорируется) | ✅ |
--ext |
Имя родительского класса. Включает файлы, наследующие указанный класс. | Illuminate\Database\Eloquent\Model |
❌ (игнорируется) | ✅ |
--use |
Имя трейта или класса. Включает файлы, использующие его через use (для трейтов) или импортирующие. |
Scancore\Filter\FilterInterface |
❌ (игнорируется) | ✅ |
Примечание: Фильтры
--impl,--ext,--useработают только в командеstats, так как требуют предварительного анализа зависимостей (карты классов). В командеdumpони игнорируются с предупреждением.
Передача нескольких значений
Значения можно указывать через запятую:
--class="App\Controller\UserController,App\Controller\AdminController"
или
--class="UserController,AdminController"
Или повторять опцию несколько раз:
--class=UserController --class=AdminController
Оба способа эквивалентны.
Примеры:
Только файлы, содержащие класс FilterManager:
vendor/bin/scancore stats --class=Scancore\\Filter\\FilterManager
Файлы, в имени которых есть "Command" (например, все классы команд):
vendor/bin/scancore stats --type=Command
Файлы, реализующие интерфейс FilterInterface:
vendor/bin/scancore stats --impl=Scancore\\Filter\\FilterInterface
Комбинация: файлы, содержащие слово "collect" (регистронезависимо) и являющиеся PHP-файлами (type=php):
vendor/bin/scancore dump --pattern="/collect/i" --type=php my_dump.txt
Несколько классов через запятую:
vendor/bin/scancore stats --class=Collector,HtmlGenerator
Все фильтры вместе (stats):
vendor/bin/scancore stats \
--class=UserController \
--pattern="/function index/i" \
--type=Controller \
--impl=SomeInterface \
--ext=BaseController \
--use=SomeTrait
Команда init
Явное создание файла .scancoreignore в корне проекта.
vendor/bin/scancore init
Если файл уже существует, команда сообщит об этом и ничего не изменит. Для принудительной перезаписи используйте флаг --force (сокращённо -f):
vendor/bin/scancore init --force
# или
vendor/bin/scancore init -f
При создании файла используется тот же алгоритм, что и при автоматической генерации:
- Если в корне есть
.gitignore, его содержимое копируется в.scancoreignore. - Иначе создаётся файл с базовым набором правил (см. пример ниже).
Временные исключения из командной строки (--ignore)
Для всех команд (tree, dump, stats) можно добавить временные правила игнорирования прямо в команде, используя флаг --ignore=шаблон. Флаг можно повторять несколько раз.
Пример:
vendor/bin/scancore tree --ignore=tests/* --ignore=*.log
vendor/bin/scancore dump --ignore=cache/* mydump.txt
vendor/bin/scancore stats --ignore=*.min.js
Важно: временные правила применяются только при наличии файла .env в корне проекта.
Если файл отсутствует, будет выведено предупреждение, и флаги --ignore будут проигнорированы (в таком случае сканирование выполнится только по правилам из .scancoreignore).
Настройка исключений для команд
По умолчанию команда init исключена из обработки --ignore.
Вы можете изменить это, создав файл .env (на основе .env.example) и указав список команд, для которых временные игноры не должны применяться:
IGNORE_EXCEPT_COMMANDS=init,someothercommand
Если вы хотите, чтобы --ignore работал для всех команд, просто оставьте переменную пустой или удалите её(создав файл .env из .env.example).
Обновление включает:
Новые возможности интеллектуальной фильтрации:
- Фильтр по классам (
--class) - включает файлы, содержащие указанный PHP-класс (полное имя). - Фильтр по содержимому (
--pattern) - регулярное выражение для поиска в тексте файла. - Фильтр по типу (
--type) - подстрока в имени файла (например, для выделения контроллеров, моделей). - Фильтры на основе зависимостей:
--impl- файлы, реализующие заданный интерфейс.--ext- файлы, наследующие заданный класс.--use- файлы, использующие указанный трейт/класс (через use).
- Комбинирование фильтров - все фильтры работают одновременно (логическое И). Несколько значений внутри одного фильтра обрабатываются как ИЛИ.
- Поддержка в командах
dumpиstats- фильтры, требующие анализа зависимостей, доступны только в stats (с предупреждением в dump).