javascript

Зачем я написал очередной велосипед для работы с директориями (спойлер: не совсем велосипед)

  • среда, 23 июля 2025 г. в 00:00:06
https://habr.com/ru/articles/930076/

Проблема: плагины, которые живут внутри чужих папок

Поскольку исходный код проекта является проприетарным, для наглядности я буду использовать синтетический пример, который точно отражает суть проблемы.

Представьте:

Ядро (/core) с сотнями файлов в сложной структуре:

/core
├── /config
│   ├── app.yaml
│   └── routes/
├── /src
│   ├── /utils
│   │   ├── logger.py
│   │   └── network/
│   └── main.py
└── /templates
    ├── base.html
    └── /admin

Плагин, который раскидывает свои файлы прямо в подпапки ядра:

/plugin
├── /config/routes/new_handlers.yaml  # лезет в /core/config/routes/
├── /src/utils/logger.py              # переопределяет ядерный logger
└── /templates/admin/dashboard.html   # добавляет шаблоны
  • Кастомизации, которые точечно меняют файлы ядра (например, core/src/utils/network/http.py).

Что пошло не так?

  1. Ручной мердж:

    • Копируете new_handlers.yaml → забываете добавить его в .gitignore ядра → git status показывает кучу "лишних" файлов.

    • Обновили ядро? Теперь нужно вручную проверять, не перезаписали ли ваши плагины важные файлы.

  2. Гигантские .gitignore для плагинов по сути все файлы ядра
    IDE начинает тормозить из-за постоянного сканирования.

  3. Сборка через make:

    • Рабочая директория собирается "на лету", но:

      • IDE не видит связи между plugin/src/utils/logger.py и core/src/utils/logger.py

      • При пересборке слетают дебаг-брейкпоинты или оставленный отладочный код,

      • Фиксить изменения приходится в трёх разных репозиториях.

Проблемы:

  • Временные затраты — 15+ минут на ручное копирование

  • Ошибки — случайные перезаписи, потерянные файлы

  • Сложность контроля — непонятно, какие файлы плагинов переписывают файлы ядра.

Существующие решения (и почему они не подошли)

Инструмент

Проблема

git-submodules

Сложность управления, конфликты при перезаписи файлов

rsync

Нет привязки к origin-директориям

копирование через make

Хрупкость

Пример:
Если в git-submodules плагин перезаписал core/src/utils/logger.py, то:

  • При обновлении ядра изменения потеряются,

  • Нет механизма "вернуть файл в плагин".

Как работает dmp

1. Трекинг файлов

dmp запоминает происхождение каждого файла в .dmp/config

{
  "remotes": {
    "core": "/dev/core",
    "plugin": "/dev/plugin1",
    "plugin_2": "/dev/plugin2"
  },
  "file_owners": {
    "src/core/exampleFile.py": "core",
    "src/core/exampleFile2.py": "plugin",
    "src/core/exampleFile3.py": "plugin_2",
    ...

2. Разрешение конфликтов

  • Вручную: dmp track add [file] [remote]указываем кто будет владельцем файла в рабочей директории (с какой директорией будет синхронизироваться рабочая директория)

  • частичное обновление(рабочей директории)dmp pull plugin [file] подтягивает конкретный файл из директории в git.

  • Отслеживание изменения: dmp status список файлов отличающихся в рабочей директории и в директориях репозиториев.
    dmp check-new список файлов не асоциированых ни с одной директорией репозиториев(плагины ядро).

3. Работа с IDE

  • Симлинки не используются → PyCharm/VSCode корректно видят классы.

  • .dmpignore исключает временные файлы (аналог .gitignore).

Пример: типичный workflow

# 1. Инициализация
dmp init /prod
cd /prod

# 2. Подключаем репозитории
dmp remote add core ~/git/core 
dmp remote add plugin ~/git/plugin 

# 3. Сканируем отслеживаемые дирректории 
dmp track add-all core
dmp track add-all plugin

# 3. копируем файлы в раочую дирректорию
dmp pull core
dmp pull plugin # выведи список конфликтов (файлов содержание рабочей директории отличается от директории репозитория)

# 4. копируем файлы в раочую дирректорию(переписываем изменения в рабочей директории) файлы планина перепишут файлы ядра
dmp pull plugin --force


# 5. Правим файлы плагина
vim /prod/src/utils/logger.py

# 6. Выводит список файлов отличающихся от файлов внутри директории для всех директорий или для конкретной
dmp status [plugin]

# 7. отправляем изменений в директорию с репозиторием
dmp push plugin

Философия

Это костыль, но:

  • Решает конкретную проблему без переделки workflow,

  • Не требует прав в CI/CD,

  • Позволяет сохранить разделение кода на репозитории.

Вопрос к аудитории:
Как вы решаете проблему вложенных плагинов?

🔗 Ссылка на проектgithub.com/SidorkinAlex/dmp