Предыстория


Когда на руках появляется более одного рабочего устройства, то к тебе, %username%, приходит желание иметь одинаковую конфигурацию и тут, и там, и на работе, и дома. Когда я только-только начинал попытки синхронизировать файлы, мне было достаточно Dropbox и Yandex.disk. Особенно хорошо они помогали синхронизировать документы и историю джаббера, но как только я попытался приспособить их к .bashrc, .vimrc и им подобным, тут же повылезали различные сайд-эффекты. Например, с symlink'ами в обоих системах полнейшая беда, ± какая-то история есть только в дропбоксе, ну и писать скрипты управления зоопарком пришлось бы самому. Наверняка ведь что-то уже написано, правда?


История


На страничке https://dotfiles.github.io/ представлены чуть меньше сотни различных утилит, плагинов и подходов к управлению конфигурациями — от заточенных под отдельные программы до универсальных. Очень советую ознакомиться, вполне возможно, что Вы прекратите дальнейшее чтение и пойдёте выбирать себе что-нибудь более приемлемое.


Общий смысл философии сводится к тому, что конфиги лежат в репозитории %your_favorit_vcs% в определённом виде и оттуда расползаются по $HOME. Так как %default_vcs% сейчас это git, то его я и буду использовать далее.


Начинал я своё знакомство с dotfiles-in-git с утилитки под названием dotgit. Она начиналась как "простенькая и понятная на чистом bash". Но в момент, когда автор добавил туда шифрование с возможностью делать симлинки непосредственно на директории, и я попытался во всём этом разобраться (примерно начало 2017 года), у моей домашней папки случился огурец мозга с битыми линками и ручным восстановлением файлов из гита. В общем, был выделен один день на поиск альтернатив с возможностью тюнинга поведения и простой конфигурацией.


rcm


Итак, как уже было сказано, вариантов утилит существует, действительно, много. rcm был выбран по следующим причинам:


  • Чистый sh, даже не bash. Он не тянет за собой ни python, ни ruby, ничего другого
  • Позволяет настраивать поведение доставки конфигов
  • Наличие man-страниц
  • Кастомизация деплоя с помощью папок tag-* и host-*
  • Долгая поддержка, живой развивающийся проект
  • На момент использования и по сей день это не актуально, но поддерживаются {pre,post}-{up,down} хуки для обновления и очистки файлов конфигурации

Наиболее важным пунктом является, разумеется, документация, ибо без неё я бы не дошёл того, чтобы полностью настроить поведение деплоя под себя.


После установки менеджера будут доступны 4 команды:


  • lsrc — выводит список того, как будет выглядеть конфигурация после выполнения rcup
  • mkrc — добавляет файл в ~/.dotfiles (по умолчанию, можно изменить в ~/.rcrc) и затем устанавливает их обратно. Если необходимо нестандартное поведение, лучше сперва поправить ~/.rcrc, в противном случае могут быть неожиданные спецэффекты
  • rcdn — удаляет все файлы конфигурации, управляемые посредством rcm
  • rcup — устанавливает все файлы

Как таковой, файл ~/.rcrc — просто часть shell-скрипта, который подключается командой source при каждом вызове утилит rcm. Исходя из этого, его можно сделать модульным, со встроенной логикой. Согласно документации, его содержимое позволяет тонко управлять параметрами установки дотфайлов при помощи rcup, например:


  • поведение по умолчанию: на каждый файл внутри ~/.dotfiles создаётся симлинк в домашней папке без начальной точки (например, '/home/felixoid/.dotfiles/bashrc' -> '/home/felixoid/.bashrc', '/home/felixoid/.dotfiles/README.md' -> '/home/felixoid/.README.md')
  • папочка ~/.vim: является симлинком на папку /home/felixoid/.dotfiles/vim (опция SYMLINK_DIRS)
  • папочка ~/.some_secret_files: скопированная из /home/felixoid/.dotfiles/tag-dmz/some_secret_files (опция COPY_ALWAYS)
  • файл ~/.README.md на самом деле игнорируется (опция EXCLUDES)
  • файл '/home/felixoid/.zshenv' является симлинком на '/home/felixoid/.dotfiles/tag-zsh/zshenv' (параметр TAGS)
  • папка ~/bin также управляется при помощи rcm, её содержимое приезжает из /home/felixoid/.dotfiles/bin/ (параметр UNDOTTED)

Иногда может потребоваться упоминание одного и того же файла в нескольких опциях. Например, так должен выглядеть сниппет .rcrc, если всё содержимое ~/bin должно находиться в ~/.dotfiles/tag-bins/bin и копироваться as is:


COPY_ALWAYS="bin/*"
TAGS="bins"
UNDOTTED="bin"

Собственно, пример того, как можно организовать содержимое папки ~/.dotfiles, есть в репозитории с дотфайлами. Исчерпывающая информация содержится в документации, не стесняйтесь прочитать следующие man-страницы: lsrc(1), mkrc(1), rcrc(5) rcdn(1), rcm(7), rcup(1).


Несказанное и несделанное


Пока я набирал данный текст, ко мне пришли неплохие идеи о том, как можно организовать хранение чувствительных данных внутри публичного репозитория. Например, меня всегда волновал вопрос, имеет ли смысл и возможно ли делать бекапы ключей gpg и ssh? Как раз для этого могли бы пригодиться хуки: упаковывать их в tar, затем шифровать тем же симметричным gpg с последующей распаковкой. Возможно, этому я посвящу следующую заметку после реализации. Или, может быть, это очередной велосипед? И всё уже придумано? Добавьте в комментариях, если это на самом деле так.


Очень надеюсь, что данный материал вызовет заинтересованность и желание попробовать организовать управление конфигами в полуавтоматическом режиме!


И небольшой опросик:

Комментарии (7)


  1. Dreyk
    06.08.2018 12:57

    у меня просто git дотфайлов, файлов немного, сетаплю нечасто, поэтому симлинки делаю руками


    из плюсов: .bashrc у меня обычно не симлинкается, а на каждой машине свой, в который source'ится дотфайловский. та же история с .gitconfig — на каждой машине он свой, а внутри include


    1. felix0id Автор
      06.08.2018 13:38

      Понятно. Так ведь оно работает и в обратную сторону, глобальный .bashrc, который синкает ~/.workrc/*.sh, например. Ну и большинство утилит поддерживает уникальные для хостнейма дотфайлы в том числе


      1. Dreyk
        06.08.2018 13:53

        ну тут зависит от того, кому что надо. мне не нужен полный бекап каждого окружения — мне важно быстро засетапить новое рабочее место, а также держать в синке общие части: то есть, если я в каком-то месте узнал про новую плюшку — просто добавляю ее в общую базу


  1. antares_me
    06.08.2018 13:05

    Stow — мой выбор


    1. felix0id Автор
      06.08.2018 15:14

      почитал, как подобным управляют


      Не оверкил ли это? Опять же, сверху этого обвязка для каждого хоста? Или Вы вручную решаете, куда какой "пакет" ставить? Как с "обновить всё"?


      1. antares_me
        06.08.2018 17:56

        Обвязки возможно и есть, но я не пользуюсь ими.
        Stow ориентируется на файловую структуру.
        Допустим есть конфиг в папке под гитом
        ~/dotfiles/vim/.vim/vimrc
        Можно зайти в dotfiles и выполнить

        $> stow vim

        Вся внутрянка папки vim создастся в домашней директории, а на файлы создадутся симлинки.
        $> stow -R vim

        Пересоздаст симлинки, удалив битые и создав недостающие
        $> stow -D vim

        удалит симлинки и (если папки пусты) папки заводимые под конфиги. Если в папке лежит что-то, о чём stow не знает, то это и не удаляется.

        В итоге один репозиторий, а на конкретных машинах решаю что надо. Нужен Emacs команда с одним параметром. Нужен vim- с другим.


        1. felix0id Автор
          07.08.2018 10:46

          Понятно, понятно. Видимо, у меня уже автоматизация головного мозга и я всюду хочу минимум телодвижений =)