Руководство по импорту новых проектов в систему CodeGraph.
Примечание: В этом руководстве описывается создание новых данных CPG из исходного кода. Для использования существующих данных CPG зарегистрируйте проект через
projects.registry.<имя>.db_pathвconfig.yaml.
Содержание¶
- Обзор
- Поддерживаемые языки
- Использование CLI
- Полный конвейер (одна команда)
- Поддержка Docker
- Управление проектами
- Задачи импорта
- Импорт комментариев
- Пошаговый импорт
- Список поддерживаемых языков
- Использование REST API
- Получить список поддерживаемых языков
- Запуск импорта (асинхронно)
- Проверка статуса импорта
- Список всех задач импорта
- Отмена импорта
- Запуск отдельного шага
- Импорт с использованием Docker
- Управление проектами (REST)
- WebSocket для отслеживания прогресса
- Параметры импорта
- Режимы импорта
- Параметры клонирования
- Параметры GoCPG
- Параметры документации
- Результат импорта
- Структура результата (ProjectImportResult)
- Проверка CPG
- Оценка качества (0–100)
- Проверяемые метрики
- Импорт исходного кода
- Принцип работы
- Поддерживаемые расширения файлов
- Ограничение на размер файла
- Нормализация путей
- Статистика импорта
- Плагин домена
- Структура плагина
- Конфигурация: subsystems.yaml
- Конфигурация: prompts.yaml
- Активация плагина домена
- Работа с большими репозиториями
- Большие проекты на C/C++
- Рекомендации
- Python API
- Запуск отдельных шагов
- Устранение неполадок
- Не найден модуль анализа GoCPG
- Сбой процесса GoCPG
- Язык не распознан
- Ошибка проверки CPG
- Конфигурация (config.yaml)
- Архитектура компонентов
- ProjectRegistry
- GoCPGClient
- См. также
Обзор¶
Система поддерживает автоматический импорт кодовых баз на различных языках программирования. Процесс включает 8 шагов конвейера:
- Клонирование — клонирование репозитория
- Определение языка — определение языка программирования
- Создание CPG — построение графа свойств кода (GoCPG записывает результат напрямую в DuckDB)
- Проверка — проверка целостности CPG
- Синхронизация ChromaDB — индексирование документации в ChromaDB
- Генерация документации — автоматическая генерация документации из CPG
- Индексирование векторов — индексирование коллекций для поиска
- Настройка домена — генерация доменного плагина
Поддерживаемые языки¶
| Язык | Расширения файлов | Описание |
|---|---|---|
| C/C++ | .c, .h, .cpp, .hpp, .cc, .cxx |
Исходный код на C/C++ |
| C# | .cs |
Исходный код на C# |
| Go | .go |
Исходный код на Go |
| Java | .java |
Исходный код на Java |
| JavaScript | .js, .jsx, .mjs |
Исходный код на JavaScript |
| TypeScript | .ts, .tsx |
TypeScript (выделенный модуль анализа GoCPG) |
| Kotlin | .kt, .kts |
Исходный код на Kotlin |
| PHP | .php |
Исходный код на PHP |
| Python | .py, .pyw |
Исходный код на Python |
| 1C:Предприятие | .bsl, .os |
1C:Предприятие (BSL/SDBL), только модуль анализа GoCPG |
Использование CLI¶
Полный конвейер (одна команда)¶
# Импорт из репозитория GitHub
python -m src.cli.import_commands full \
--repo https://github.com/postgres/postgres \
--branch master \
--shallow \
--language c
# Импорт локального проекта
python -m src.cli.import_commands full \
--path /путь/к/проекту \
--language java
# Избирательный импорт (только определённые директории)
python -m src.cli.import_commands full \
--repo https://github.com/postgres/postgres \
--include src/backend src/include \
--exclude test tests
# Импорт с использованием Docker
python -m src.cli.import_commands full \
--repo https://github.com/example/project \
--docker
Поддержка Docker¶
Система поддерживает запуск GoCPG в контейнере Docker для кроссплатформенной работы:
# Импорт с Docker (локальная сборка GoCPG не требуется)
python -m src.cli.import_commands full \
--repo https://github.com/example/project \
--docker
# С указанием конкретного образа Docker
python -m src.cli.import_commands full \
--repo https://github.com/example/project \
--docker \
--docker-image codegraph/gocpg:v4.0.0
Преимущества использования Docker: - Не требуется локальная сборка GoCPG - Единообразное поведение на всех платформах (Windows, Linux, macOS) - Изолированная среда выполнения - Автоматическое управление ресурсами
Управление проектами¶
# Список всех импортированных проектов
python -m src.cli.import_commands projects list
# Информация о проекте
python -m src.cli.import_commands projects info my_project
# Активация проекта (установка в качестве текущего)
# При наличии поля `domain` соответствующий доменный плагин активируется автоматически.
python -m src.cli.import_commands projects activate my_project
# Переименование проекта
python -m src.cli.import_commands projects rename my_project new_name
python -m src.cli.import_commands projects rename my_project new_name --group my_group
# Удаление проекта (только метаданные)
python -m src.cli.import_commands projects delete my_project
# Удаление проекта вместе с файлами (CPG, DuckDB)
python -m src.cli.import_commands projects delete my_project --delete-files
# Удаление проекта вместе с коллекциями ChromaDB
python -m src.cli.import_commands projects delete my_project --delete-collections
# Удаление без подтверждения
python -m src.cli.import_commands projects delete my_project --delete-files --delete-collections -y
Все команды проектов поддерживают флаг --group для указания группы проекта.
Проекты регистрируются в config.yaml в секции projects.registry:
projects:
active: postgres
registry:
postgres:
db_path: data/projects/postgres.duckdb
source_path: /path/to/source
language: c
domain: postgresql_v2 # Автоматически активирует доменный плагин при переключении
my_python_app:
db_path: data/projects/myapp.duckdb
source_path: /path/to/myapp
language: python
domain: python_generic
Поле domain является необязательным. Если указано, при переключении на проект автоматически активируется соответствующий доменный плагин (например, postgresql_v2, python_generic). Коллекции ChromaDB также изолируются по проектам.
Задачи импорта¶
# Список последних задач импорта
python -m src.cli.import_commands jobs
# С фильтрами
python -m src.cli.import_commands jobs --limit 20 --status completed
python -m src.cli.import_commands jobs --status failed
Импорт комментариев¶
# Импорт комментариев из исходного кода в существующую базу DuckDB
python -m src.cli.import_commands import-comments --db data/projects/postgres.duckdb
# С явным указанием пути к исходному коду
python -m src.cli.import_commands import-comments --db data/projects/postgres.duckdb --source /путь/к/исходному/коду
Пошаговый импорт¶
# 1. Клонирование репозитория
python -m src.cli.import_commands clone \
--repo https://github.com/org/repo \
--branch main \
--shallow \
--depth 1
# 2. Определение языка
python -m src.cli.import_commands detect --path ./workspace/repo
# 3. Создание CPG (результат записывается напрямую в DuckDB)
python -m src.cli.import_commands cpg \
--path ./workspace/repo \
--language c
# 4. Проверка
python -m src.cli.import_commands validate --db ./workspace/repo.duckdb
# 5. Импорт документации
python -m src.cli.import_commands docs \
--path ./workspace/repo \
--db ./workspace/repo.duckdb
# 6. Создание Domain Plugin
python -m src.cli.import_commands domain \
--path ./workspace/repo \
--name my_project \
--db ./workspace/repo.duckdb
Список поддерживаемых языков¶
python -m src.cli.import_commands languages
Использование REST API¶
Получить список поддерживаемых языков¶
GET /api/v1/import/languages
Ответ:
{
"languages": [
{
"id": "c",
"name": "C",
"extensions": [".c", ".h", ".cpp", ".hpp"],
"gocpg_frontend": "c",
"gocpg_lang": "C"
},
{
"id": "java",
"name": "JAVA",
"extensions": [".java"],
"gocpg_frontend": "java",
"gocpg_lang": "JAVA"
}
]
}
Запуск импорта (асинхронно)¶
POST /api/v1/import/start
Content-Type: application/json
{
"repo_url": "https://github.com/postgres/postgres",
"branch": "master",
"shallow_clone": true,
"language": null,
"mode": "full",
"include_paths": ["src/backend", "src/include"],
"exclude_paths": ["test", "tests"],
"create_domain_plugin": true,
"import_docs": true
}
Ответ:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"message": "Импорт запущен. Используйте job_id для отслеживания прогресса."
}
Проверка статуса импорта¶
GET /api/v1/import/status/{job_id}
Ответ:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"project_name": "postgres",
"status": "in_progress",
"steps": [
{"name": "Clone Repository", "status": "completed", "progress": 100},
{"name": "Detect Language", "status": "completed", "progress": 100},
{"name": "Generate CPG", "status": "in_progress", "progress": 45, "message": "Создание узлов CPG..."},
{"name": "Validate CPG", "status": "pending", "progress": 0},
{"name": "Sync Documentation", "status": "pending", "progress": 0},
{"name": "Generate Documentation", "status": "pending", "progress": 0},
{"name": "Index Vector Collections", "status": "pending", "progress": 0},
{"name": "Setup Domain Plugin", "status": "pending", "progress": 0}
],
"current_step": "gocpg_parse",
"overall_progress": 35,
"created_at": "2024-12-09T10:00:00Z",
"updated_at": "2024-12-09T10:05:00Z"
}
Список всех задач импорта¶
GET /api/v1/import/jobs?status_filter=in_progress&limit=10
Отмена импорта¶
DELETE /api/v1/import/cancel/{job_id}
Запуск отдельного шага¶
POST /api/v1/import/step
Content-Type: application/json
{
"step_id": "validate",
"context": {
"duckdb_path": "./workspace/project.duckdb"
}
}
Импорт с использованием Docker¶
POST /api/v1/import/start
Content-Type: application/json
{
"repo_url": "https://github.com/example/project",
"branch": "main",
"use_docker": true,
"docker_image": "codegraph/gocpg:latest"
}
Управление проектами (REST)¶
Список проектов:
GET /api/v1/projects
Ответ:
{
"projects": [
{
"id": "123",
"name": "my_project",
"language": "python",
"cpg_path": "./workspace/my_project.cpg",
"duckdb_path": "./workspace/my_project.duckdb",
"is_active": true,
"created_at": "2024-12-10T10:00:00Z"
}
]
}
Создание проекта:
POST /api/v1/projects
Content-Type: application/json
{
"group_id": "group-uuid",
"name": "my_project",
"db_path": "./data/projects/my_project.duckdb",
"language": "python",
"domain": "python_generic"
}
Активация проекта:
POST /api/v1/projects/{project_id}/activate
Удаление проекта:
DELETE /api/v1/projects/{project_id}
Удаление коллекций:
DELETE /api/v1/projects/{project_id}/collections
WebSocket для отслеживания прогресса¶
const ws = new WebSocket('ws://localhost:8000/api/v1/ws/jobs/550e8400-e29b-41d4-a716-446655440000');
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'job.progress':
console.log(`Ход выполнения: ${msg.payload.progress}% - ${msg.payload.message}`);
break;
case 'job.completed':
console.log('Импорт завершён:', msg.payload.result);
break;
case 'job.failed':
console.error('Импорт не удался:', msg.payload.error);
break;
}
};
Параметры импорта¶
Режимы импорта¶
| Режим | Описание |
|---|---|
full |
Полный импорт всей кодовой базы |
selective |
Импорт только указанных путей (include_paths) |
incremental |
Импорт только изменений с момента последнего импорта |
Параметры клонирования¶
| Параметр | По умолчанию | Описание |
|---|---|---|
shallow_clone |
true |
Использовать неглубокое клонирование |
shallow_depth |
1 |
Глубина неглубокого клонирования |
branch |
"main" |
Ветка для клонирования |
Параметры GoCPG¶
| Параметр | По умолчанию | Описание |
|---|---|---|
gocpg_memory_gb |
16 |
Объём памяти для GoCPG (в ГБ) |
batch_size |
10000 |
Размер пакета для экспорта в DuckDB |
use_docker |
false |
Использовать Docker для GoCPG |
docker_image |
codegraph/gocpg:latest |
Docker-образ GoCPG |
Параметры документации¶
| Параметр | По умолчанию | Описание |
|---|---|---|
import_docs |
true |
Импортировать документацию |
import_readme |
true |
Индексировать файлы README |
import_comments |
true |
Импортировать комментарии в коде |
Результат импорта¶
После успешного импорта создаются следующие элементы:
workspace/
├── postgres/ # Исходный код
└── postgres.duckdb # База данных DuckDB (CPG + граф)
chroma_db/
└── postgres_documentation/ # Коллекция ChromaDB
src/domains/
└── postgres/ # Плагин домена
├── __init__.py
├── plugin.py
├── subsystems.yaml
└── prompts.yaml
Структура результата (ProjectImportResult)¶
{
"cpg_path": "./workspace/postgres.cpg",
"duckdb_path": "./workspace/postgres.duckdb",
"domain_plugin_path": "./src/domains/postgres",
"chromadb_collection": "postgres_documentation",
"chromadb_stats": {
"readme_indexed": 45,
"docs_indexed": 230,
"comments_indexed": 1500
},
"cpg_stats": {
"methods": 125000,
"calls": 450000,
"identifiers": 890000
},
"source_info": {
"files_imported": 6307,
"files_skipped_size": 12,
"total_size_mb": 84.95
},
"validation_report": {
"status": "passed",
"quality_score": 85
},
"detected_language": "c",
"import_duration_seconds": 3600.5
}
Проверка CPG¶
Оценка качества (0–100)¶
Оценка качества импортированного CPG:
| Критерий | Баллы |
|---|---|
| Найдены методы | +50 |
| Файлы, связанные с методами (>50%) | +20 |
| Наличие рёбер AST | +8 |
| Наличие рёбер CFG | +7 |
| Отсутствие ошибок проверки | +15 |
Проверяемые метрики¶
methods_exist— количество методовcalls_exist— количество вызововedges_ast— рёбра ASTedges_cfg— рёбра CFGmethods_with_files— методы, связанные с файлами
Импорт исходного кода¶
Шаг SourceContentStep импортирует полное содержимое исходного кода в поле nodes_file.content для навигации по коду и его анализа.
Принцип работы¶
- Считывает файлы из пути
source_path, указанного в конфигурации проекта - Заполняет поле
nodes_file.contentполным содержимым файлов - Автоматически нормализует пути к файлам для совместимости с
nodes_methodпри выполнении JOIN - Определяет язык программирования по расширению файла
Поддерживаемые расширения файлов¶
| Язык | Расширения |
|---|---|
| C/C++ | .c, .h, .cpp, .hpp, .cc, .cxx |
| Python | .py, .pyw |
| Java | .java |
| JavaScript/TypeScript | .js, .jsx, .ts, .tsx |
| Go | .go |
| Rust | .rs |
| PHP | .php |
| C# | .cs |
| Kotlin | .kt, .kts |
| 1C:Предприятие | .bsl, .os |
| Scala | .scala |
| SQL | .sql |
| Shell | .sh, .bash |
| Конфигурационные файлы | .yaml, .yml, .json, .xml, .toml, .ini |
Ограничение на размер файла¶
Файлы размером более 500 КБ пропускаются, чтобы поддерживать разумный объём базы данных. Это ограничение охватывает большинство исходных файлов, исключая при этом большие сгенерированные или бинарные файлы.
Нормализация путей¶
Пути к файлам в поле nodes_file.name автоматически нормализуются для соответствия формату nodes_method.filename. Типичные префиксы, такие как src/, удаляются, чтобы обеспечить прямые JOIN-запросы:
-- Получение исходного кода метода по номеру строки
SELECT
m.full_name,
m.line_number,
m.line_number_end,
f.content
FROM nodes_method m
JOIN nodes_file f ON REPLACE(m.filename, '/', '\') = REPLACE(f.name, '/', '\')
WHERE m.full_name = 'exec_simple_query';
Статистика импорта¶
После импорта доступна следующая статистика:
| Метрика | Описание |
|---|---|
source_files_imported |
Количество успешно импортированных файлов |
source_files_skipped_size |
Файлы, пропущенные из-за ограничения по размеру |
source_files_skipped_not_found |
Файлы, не найденные в указанном пути |
source_files_total |
Общее количество обработанных файлов |
Плагин домена¶
Для работы с новым проектом автоматически генерируется плагин.
Структура плагина¶
# src/domains/my_project/plugin.py
class MyProjectPlugin(DomainPlugin):
@property
def name(self) -> str:
return "my_project"
@property
def display_name(self) -> str:
return "My Project"
def _load_subsystems(self) -> Dict[str, SubsystemInfo]:
# Загружается из subsystems.yaml
...
def get_vulnerability_function_mappings(self) -> Dict[str, List[str]]:
return {
"buffer_overflow": ["strcpy", "memcpy", ...],
"sql_injection": [...],
...
}
Конфигурация: subsystems.yaml¶
subsystems:
core:
description: "Основная логика приложения"
key_functions:
- main
- init
- start
patterns:
- "src"
- "lib"
related_files: []
utils:
description: "Вспомогательные функции"
key_functions: []
patterns:
- "util"
- "helper"
Конфигурация: prompts.yaml¶
prompts:
onboarding:
system: |
Вы являетесь экспертом по My Project и помогаете разработчикам понять кодовую базу.
user_template: |
Помогите мне понять следующий аспект: {query}
security:
system: |
Вы являетесь экспертом по безопасности и анализируете код My Project (C).
user_template: |
Проанализируйте следующий код на наличие уязвимостей:
{code}
Активация плагина домена¶
После создания плагина добавьте его в конфигурацию:
# config.yaml
domains:
active: "my_project"
available:
- postgresql_v2
- my_project
Или программно:
from src.domains import DomainRegistry
DomainRegistry.activate("my_project")
Работа с большими репозиториями¶
Большие проекты на C/C++¶
Примечание: Большие проекты на C/C++ используют плагин домена
generic_cppдля анализа.
# Использовать неглубокое клонирование
python -m src.cli.import_commands full \
--repo https://github.com/postgres/postgres \
--shallow \
--depth 1
# Или выборочный импорт
python -m src.cli.import_commands full \
--repo https://github.com/postgres/postgres \
--include src/backend/executor \
--mode selective
# Увеличить объём памяти для GoCPG
python -m src.cli.import_commands full \
--repo https://github.com/postgres/postgres \
--memory 32
Рекомендации¶
- Используйте неглубокое клонирование, чтобы сэкономить место и время
- Выбирайте нужные каталоги с помощью параметра
--include - Исключайте тесты с помощью
--exclude test tests - Увеличьте объём памяти GoCPG для крупных проектов (16–32 ГБ)
Python API¶
from src.project_import import (
ProjectImportPipeline,
ProjectImportRequest,
SupportedLanguage,
ImportMode,
)
# Создание запроса
request = ProjectImportRequest(
repo_url="https://github.com/example/project",
branch="main",
shallow_clone=True,
language=SupportedLanguage.JAVA, # или None для автоматического определения
mode=ImportMode.FULL,
include_paths=["src/main"],
exclude_paths=["src/test"],
create_domain_plugin=True,
import_docs=True,
)
# Запуск конвейера
async def run_import():
def progress_callback(status):
print(f"Прогресс: {status.overall_progress}% - {status.current_step}")
pipeline = ProjectImportPipeline(progress_callback=progress_callback)
result = await pipeline.run(request)
print(f"CPG: {result.cpg_path}")
print(f"DuckDB: {result.duckdb_path}")
print(f"Язык: {result.detected_language}")
print(f"Оценка качества: {result.validation_report['quality_score']}")
import asyncio
asyncio.run(run_import())
Запуск отдельных шагов¶
from src.project_import.pipeline import ProjectImportPipeline
pipeline = ProjectImportPipeline()
# Контекст шага
context = {
"request": ProjectImportRequest(),
"source_path": Path("./workspace/project"),
"duckdb_path": "./workspace/project.duckdb",
}
# Выполнение шага валидации
result = await pipeline.run_step("validate", context)
print(result["validation_report"])
Устранение неполадок¶
Не найден модуль анализа GoCPG¶
RuntimeError: Frontend not found at expected paths
Решение: Проверьте переменную окружения GOCPG_PATH или укажите путь явно:
export GOCPG_PATH=/путь/к/gocpg
python -m src.cli.import_commands full --repo ...
Сбой процесса GoCPG¶
Ошибка: GoCPG завершается с ненулевым кодом возврата
Решение:
- Проверьте доступное дисковое пространство для файла DuckDB
- Убедитесь, что путь к исходному коду доступен: ls <source_path>
- Запустите с подробным логированием: gocpg parse --input=<path> --output=<db> --lang=c -v
- Увеличьте объём памяти при обработке большой кодовой базы: --memory 32
Язык не распознан¶
ValueError: No supported source files found
Решение: Укажите язык явно:
python -m src.cli.import_commands full --repo ... --language java
Ошибка проверки CPG¶
Validation errors: ['methods_exist: expected >= 1, got 0']
Решение: Проверьте следующее: 1. Правильный ли путь к исходному коду 2. Соответствует ли модуль анализа GoCPG языку исходного кода 3. Не исключаются ли файлы с помощью шаблонов
Конфигурация (config.yaml)¶
Настройки модуля project_import в файле config.yaml:
project_import:
gocpg:
# Путь к локальному бинарному файлу GoCPG (необязательно, если используется Docker)
binary_path: ${GOCPG_PATH:-gocpg/gocpg.exe}
# Таймаут парсинга в секундах
parse_timeout: 3600
# Таймаут обновления в секундах
update_timeout: 600
# Использовать Docker вместо локальной сборки GoCPG
use_docker: false
# Docker-образ для GoCPG
docker_image: "codegraph/gocpg:latest"
# Ограничение памяти (ГБ)
memory_gb: 16
# Каталог для файлов DuckDB
duckdb_path: ./data/projects
# Размер пакета для экспорта в DuckDB
batch_size: 10000
# Автоопределение инкрементального режима
auto_detect_incremental: true
# Шаблоны исключения по умолчанию
default_excludes:
- "node_modules"
- "venv"
- ".venv"
- "__pycache__"
- ".git"
- "test"
- "tests"
- "vendor"
- "third_party"
Архитектура компонентов¶
ProjectRegistry¶
Реестр проектов с поддержкой PostgreSQL. Принимает AsyncSession в конструкторе:
from sqlalchemy.ext.asyncio import AsyncSession
from src.project_import.registry import ProjectRegistry
# Используется с существующей асинхронной сессией SQLAlchemy
registry = ProjectRegistry(session)
# CRUD-операции
projects = await registry.list_projects()
project = await registry.get_project_by_name("my_project")
await registry.rename_project(project.id, "new_name")
await registry.delete_project(project.id, delete_files=True)
GoCPGClient¶
GoCPGClient предоставляет унифицированную асинхронную обёртку на Python для всех команд GoCPG с моделями результатов на Pydantic:
from src.services.gocpg import GoCPGClient
client = GoCPGClient() # автоопределение пути к бинарнику из config.yaml
result = await client.parse(input_path="/src", output_path="data/projects/postgres.duckdb", language="c")
result = await client.update(input_path="/src", output_path="data/projects/postgres.duckdb", force=True)
ci_result = await client.ci_update(input_path="/src", output_path="data/projects/postgres.duckdb", base_ref="origin/main")
stats = await client.stats()
См. src/services/gocpg/ — полный API клиента (31 асинхронный метод, 28 Pydantic-моделей).
См. также¶
- Документация по REST API — точки доступа HTTP API
- Справочник API — Python API
- Руководство по сценариям — сценарии анализа