Импорт новой кодовой базы¶
Руководство по импорту новых проектов в систему CodeGraph.
Примечание: В этом руководстве описывается создание новых данных CPG из исходного кода. Для использования существующих данных CPG просто настройте параметр
cpg.db_pathв файлеconfig.yaml, указав путь к вашему файлу DuckDB.
Содержание¶
- Обзор
- Поддерживаемые языки
- Использование CLI
- Полный конвейер (одна команда)
- Поддержка Docker
- Управление проектами
- Пошаговый импорт
- Список поддерживаемых языков
- Использование REST API
- Получить список поддерживаемых языков
- Запуск импорта (асинхронно)
- Проверка статуса импорта
- Список всех задач импорта
- Отмена импорта
- Запуск отдельного шага
- Импорт с использованием Docker
- Управление проектами
- WebSocket для отслеживания прогресса
- Параметры импорта
- Режимы импорта
- Опции клонирования
- Опции GoCPG
- Опции документации
- Результат импорта
- Структура результата (ProjectImportResult)
- Проверка CPG
- Оценка качества (0–100)
- Проверяемые метрики
- Импорт исходного кода
- Поддерживаемые расширения файлов
- Ограничение на размер файла
- Нормализация путей
- Статистика импорта
- Структура плагина
- Конфигурация: subsystems.yaml
- Конфигурация: prompts.yaml
- Активация плагина предметной области
- Работа с большими репозиториями
- Большие проекты на C/C++
- Рекомендации
- Python API
- Запуск отдельных шагов
- Устранение неполадок
- GoCPG Frontend не найден
- Сбой процесса GoCPG
- Язык не распознан
- Проверка CPG не пройдена
- Конфигурация (config.yaml)
- Архитектура компонентов
- ProjectRegistry
- LocalGoCPGRunner / DockerGoCPGRunner
- См. также
Обзор¶
Система поддерживает автоматический импорт кодовых баз на различных языках программирования. Процесс включает в себя:
- Клонирование — клонирование репозитория
- Определение языка — определение языка программирования
- Создание CPG — построение графа свойств кода (GoCPG записывает результат напрямую в DuckDB)
- Импорт исходного кода — импорт полного содержимого исходных файлов в DuckDB
- Проверка — проверка целостности CPG
- Импорт документации — индексирование документации в ChromaDB
- Создание плагина — генерация доменного плагина
Поддерживаемые языки¶
| Язык | Расширения файлов | Описание |
|---|---|---|
| C/C++ | .c, .h, .cpp, .hpp, .cc, .cxx |
Исходный код на C/C++ |
| C# | .cs |
Исходный код на C# |
| Go | .go |
Исходный код на Go |
| Java | .java |
Исходный код на Java |
| JavaScript/TypeScript | .js, .jsx, .ts, .tsx, .mjs |
JavaScript/TypeScript |
| Kotlin | .kt, .kts |
Исходный код на Kotlin |
| PHP | .php |
Исходный код на PHP |
| Python | .py, .pyw |
Исходный код на Python |
| 1C:Предприятие | .bsl, .os |
1C:Предприятие (BSL/SDBL) |
Использование 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 {#import-s-ispolzovaniem-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
# Активация проекта (установка в качестве текущего)
python -m src.cli.import_commands projects activate my_project
# Удаление проекта (только метаданные)
python -m src.cli.import_commands projects delete my_project
# Удаление проекта вместе с файлами (CPG, DuckDB)
python -m src.cli.import_commands projects delete my_project --delete-files
Проекты регистрируются в 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 также изолируются по проектам.
Пошаговый импорт¶
# 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": "Create CPG", "status": "in_progress", "progress": 45, "message": "Создание узлов CPG..."},
{"name": "Import Source Code", "status": "pending", "progress": 0},
{"name": "Validate CPG", "status": "pending", "progress": 0},
{"name": "Import Documentation", "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"
}
Управление проектами¶
Список проектов:
GET /api/v1/import/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/import/projects/{project_id}/activate
Удаление проекта:
DELETE /api/v1/import/projects/{project_id}?delete_files=true
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 # Файл CPG (GoCPG)
└── postgres.duckdb # База данных DuckDB (граф)
chromadb_storage/
└── 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_code_stats": {
"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_HOME или укажите путь явно:
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)
home: ${GOCPG_HOME}
# Использовать Docker вместо локальной сборки GoCPG
use_docker: false
# Docker-образ для GoCPG
docker_image: "codegraph/gocpg:latest"
# Ограничение памяти (ГБ)
memory_gb: 16
workspace:
# Каталог для клонированных репозиториев
clone_dir: "./workspace"
# Каталог для файлов CPG
cpg_dir: "./workspace"
# Каталог для файлов DuckDB
duckdb_dir: "./workspace"
defaults:
# Глубина по умолчанию для неглубокого клонирования
shallow_depth: 1
# Шаблоны исключения по умолчанию
exclude_patterns:
- "node_modules"
- "venv"
- ".venv"
- "__pycache__"
- ".git"
- "test"
- "tests"
- "vendor"
- "third_party"
Архитектура компонентов¶
ProjectRegistry¶
Реестр проектов в PostgreSQL:
from src.project_import import ProjectRegistry
async with ProjectRegistry() as registry:
# Список проектов
projects = await registry.list_projects()
# Активация проекта
await registry.set_active_project("my_project")
# Удаление проекта
await registry.delete_project("old_project", 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/myproject.duckdb", language="c")
result = await client.update(input_path="/src", output_path="data/projects/myproject.duckdb", force=True)
ci_result = await client.ci_update(input_path="/src", output_path="data/projects/myproject.duckdb", base_ref="origin/main")
stats = await client.stats()
См. src/services/gocpg/ — полный API клиента (17 асинхронных методов, 12 Pydantic-моделей).
LocalGoCPGRunner / DockerGoCPGRunner¶
Запускаторы для выполнения команд GoCPG:
# Локальное выполнение
from src.project_import import LocalGoCPGRunner
runner = LocalGoCPGRunner(gocpg_path="/path/to/gocpg")
# Выполнение в Docker
from src.project_import import DockerGoCPGRunner
runner = DockerGoCPGRunner(image="codegraph/gocpg:latest")
# Запуск парсинга
await runner.run_parse(source_path, output_db, language="python")
Смотрите также¶
- Документация по REST API - Точки доступа HTTP API
- Справочник API - Python API
- Руководство по сценариям - Сценарии анализа