system/scripts/EXAMPLES.md

Примеры использования audit_imports.py

Базовое использование

1. Запустить аудит

python3 system/scripts/audit_imports.py

Выведет сводку и детали найденных проблем.

2. Использовать wrapper скрипт

# Справка
bash system/scripts/audit_imports_quick.sh help

# Полный аудит
bash system/scripts/audit_imports_quick.sh run

# Только ошибки
bash system/scripts/audit_imports_quick.sh errors

# Только неиспользуемые импорты
bash system/scripts/audit_imports_quick.sh unused

# Статистика по модулям
bash system/scripts/audit_imports_quick.sh stats

# Файлы с наибольшим количеством ошибок
bash system/scripts/audit_imports_quick.sh files

# Поиск ошибок для конкретного модуля
bash system/scripts/audit_imports_quick.sh module telegram

Анализ CSV отчёта

1. Подсчитать ошибки по типам

echo "Ошибки по типам:"
cut -d, -f1 audit_imports_report.csv | tail -n +2 | sort | uniq -c | sort -rn

# Вывод:
#   1704 ERROR_MODULE_NOT_FOUND
#   1154 WARNING_UNUSED
#      0 WARNING_DEPRECATED
#      0 ERROR_SYNTAX

2. Найти все ошибки в конкретном файле

# Ошибки в файле infra/@messenger.service/run.py
grep "infra/@messenger.service/run.py" audit_imports_report.csv

# Вывод:
# ERROR_MODULE_NOT_FOUND,infra/@messenger.service/run.py,28,src.bot_service,...
# ERROR_MODULE_NOT_FOUND,infra/@messenger.service/run.py,29,src.webhook_server,...
# ...

3. Найти все ошибки для конкретного модуля

# Ошибки с модулем 'telegram'
grep ",telegram" audit_imports_report.csv | head -20

# Вывод файлов с ошибками 'telegram':
grep ",telegram" audit_imports_report.csv | cut -d, -f2 | sort -u

4. Статистика ошибок по файлам (топ 20)

# Файлы с наибольшим количеством ошибок
grep "ERROR_" audit_imports_report.csv | \
  cut -d, -f2 | sort | uniq -c | sort -rn | head -20

# Вывод:
#      47 projects/org/lideravto/app/mp1/solution/app/main.py
#      35 infra/@messenger.service/src/bot_service.py
#      28 projects/org/pirotehnika/app/mp1/solution/app/models.py

5. Найти файлы с неиспользуемыми импортами

# Файлы с неиспользуемыми импортами (топ 15)
grep "WARNING_UNUSED" audit_imports_report.csv | \
  cut -d, -f2 | sort | uniq -c | sort -rn | head -15

Интеграция в Python проекты

1. Использовать в pytest

# conftest.py
import subprocess
import pytest

def test_imports_audit():
    """Проверить импорты при запуске тестов"""
    result = subprocess.run(
        ["python3", "system/scripts/audit_imports.py"],
        capture_output=True
    )
    assert result.returncode == 0, "Import audit failed"

2. Использовать в pre-commit hook

# .git/hooks/pre-commit
#!/bin/bash
set -e

echo "Running import audit..."
python3 system/scripts/audit_imports.py

if [ $? -ne 0 ]; then
    echo "❌ Fix import errors before committing"
    exit 1
fi

echo "✅ Import audit passed"

3. Интеграция с Makefile

.PHONY: audit audit-errors audit-stats

audit:
    python3 system/scripts/audit_imports.py

audit-errors:
    bash system/scripts/audit_imports_quick.sh errors

audit-stats:
    bash system/scripts/audit_imports_quick.sh stats

audit-unused:
    bash system/scripts/audit_imports_quick.sh unused

Использование:

make audit          # полный аудит
make audit-errors   # только ошибки
make audit-stats    # статистика
make audit-unused   # неиспользуемые импорты

Анализ и исправление проблем

1. Найти и исправить неиспользуемые импорты

# Найти файл с неиспользуемым импортом
grep "WARNING_UNUSED" audit_imports_report.csv | head -1
# WARNING_UNUSED,infra/@mail.service/check_mail.py,12,datetime.datetime,...

# Отредактировать файл и удалить строку 12:
# -from datetime import datetime
# +# datetime not used

# Перепроверить
python3 system/scripts/audit_imports.py | grep check_mail.py

2. Исправить структуру пакетов (относительные импорты)

# Проблема: infra/@messenger.service имеет относительные импорты
# Решение: Добавить __init__.py файлы

mkdir -p infra/@messenger.service/src/{adapters,bot,webhook}
touch infra/@messenger.service/__init__.py
touch infra/@messenger.service/src/__init__.py
touch infra/@messenger.service/src/adapters/__init__.py

# Обновить импорты:
# Было:
# from .base import BaseAdapter
# Стало:
# from ..adapters.base import BaseAdapter
# или лучше:
# from src.adapters.base import BaseAdapter

# Перепроверить
python3 system/scripts/audit_imports.py | grep messenger

3. Установить недостающие пакеты

# Найти недостающий пакет
bash system/scripts/audit_imports_quick.sh module telegram
# Результат: telegram, telegram.ext требуются

# Установить пакет
pip install python-telegram-bot

# Добавить в requirements.txt
echo "python-telegram-bot>=20.0" >> requirements.txt

# Перепроверить
python3 system/scripts/audit_imports.py | grep telegram

Продвинутые примеры

1. Создать отчёт об ошибках в формате JSON

import csv
import json

# Прочитать CSV отчёт
errors = []
with open('system/scripts/audit_imports_report.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        if row['TYPE'].startswith('ERROR_'):
            errors.append(row)

# Экспортировать в JSON
with open('import_errors.json', 'w') as f:
    json.dump(errors, f, indent=2)

print(f"Экспортировано {len(errors)} ошибок в import_errors.json")

2. Найти циклические импорты вручную

# Простой анализ циклических импортов
import ast
from collections import defaultdict

deps = defaultdict(set)

# Проанализировать файлы и собрать граф зависимостей
# (детали в ImportAuditor.find_circular_dependencies)

# Найти циклы (DFS алгоритм)
def find_cycles(graph):
    visited = set()
    rec_stack = set()
    cycles = []

    def dfs(node, path):
        visited.add(node)
        rec_stack.add(node)
        path.append(node)

        for neighbor in graph.get(node, []):
            if neighbor not in visited:
                dfs(neighbor, path[:])
            elif neighbor in rec_stack:
                cycle = path[path.index(neighbor):] + [neighbor]
                cycles.append(cycle)

        rec_stack.remove(node)

    for node in graph:
        if node not in visited:
            dfs(node, [])

    return cycles

3. Генерировать граф зависимостей

# Используя graphviz (если установлен)
pip install graphviz

# Создать граф из CSV отчёта
python3 << 'PYTHON'
import csv

edges = set()
with open('system/scripts/audit_imports_report.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        if row['TYPE'] == 'ERROR_MODULE_NOT_FOUND':
            file = row['FILE'].split('/')[0]  # directory
            module = row['MODULE'].split('.')[0]  # first part
            edges.add((file, module))

# Вывести в формате DOT
print("digraph imports {")
for src, dst in sorted(edges)[:50]:  # первые 50
    print(f'  "{src}" -> "{dst}";')
print("}")
PYTHON

# Сохранить в файл и открыть
# dot -Tsvg imports.dot -o imports.svg
# # открыть imports.svg

Мониторинг качества кода

Интеграция с GitHub Actions

# .github/workflows/import-audit.yml
name: Import Audit

on: [push, pull_request]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Run import audit
        run: python3 system/scripts/audit_imports.py

      - name: Upload report
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: import-audit-report
          path: system/scripts/audit_imports_report.csv

Troubleshooting

Проблема: "ModuleNotFoundError"

# Проверить что файл существует
ls -la library/connectors/api/ozon/__init__.py

# Добавить __init__.py если нет
touch library/connectors/api/ozon/__init__.py

# Проверить PYTHONPATH
echo $PYTHONPATH

# Добавить в переменную если нужно
export PYTHONPATH=/opt/claude-workspace:$PYTHONPATH

Проблема: "Permission denied"

# Дать права на исполнение
chmod +x system/scripts/audit_imports.py
chmod +x system/scripts/audit_imports_quick.sh

# Проверить владельца
ls -la system/scripts/audit_imports.py

Проблема: Слишком много ошибок

# Разбить на части - проверить только library
python3 << 'PYTHON'
from pathlib import Path
import sys
sys.path.insert(0, '/opt/claude-workspace')

from system.scripts.audit_imports import ImportAuditor

workspace = Path('/opt/claude-workspace')
auditor = ImportAuditor(workspace)
auditor.run(['library'])  # только library
PYTHON

═════════════════════════════════════════════════════════════════════════════════