Думаю многим известна ситуация, когда собственный изобретенный велосипед нигде потом не используется. Поэтому я долго не решался опубликовать эту разработку, пока не обратил внимание, что таскаю его из проекта в проект. И так, одним из неотъемлемых элементов современной разработки являются так называемые таск раннеры – это Grunt/Gulp для nodejs, Rake для Ruby, Make для C/C++ и т.п. А для главного инструмента разработчика – консоли – ничего подобного нет. Точнее есть, но, как это обычно бывает, не совсем то. В результате изысканий, на свет появился инструмент Bake – таскраннер написанный на bash с поддержкой модульной структуры.


Основные особенности:


  • Таски в виде функции.
  • Поддержка аргументов.
  • Модули.

Назначение


Bake хорошо подходит для автоматизации рутинных действий, например запуск/перезапуск необходимых сервисов, очистка кеша, создание структуры директорий, выполнение команд по ssh/sftp (например для загрузки конфигурационных данных с установкой корректных прав доступа).


Инструмент крайне прост в использовании все что нужно — добавить функции-таски в bake.sh и можно вызывать их из командной строки:


bake [OPTIONS] <TASK> [TASK_ARGS]

Bake-файл


Таски хранятся в файле bake.sh. Bake будет искать этот файл в текущей директории, если его нет, то в вышестоящей, вплоть до корня системы. Директория, в которой находится bake.sh является корнем проекта и присваивается переменной $PWD. Соответственно все таски выполняются относительно корня, а не текущей директории, которая хранится в переменной $CWD.


Таски


Задания являются функциями, название которых начинающаяся с task:. Пример:


task:greet() {
    echo "Hello World"
}

Вызываем из консоли:


bake greet # -> Hello World

Внимание! Дефисы в имени таска заменяются на подчеркивания таск task:hello_world может быть вызван командами bake hello-world и bake hello_world.


Аргументы


Аргументы следующие за названием таска передаются в функцию:


task:greet() {
    echo "Hello $1"
}

bake greet World # -> Hello World

Модули


Bake позволяет разделять код на модули и подключать их по мере необходимости. Модули хранятся в директории bake_modules в виде скриптов, например ssh.sh. Подключаются модули с помощью команды bake:module <name>. Пример:


bake:module ssh # include "bake_modules/ssh.sh"
bake:module mysql # include "bake_modules/mysql.sh"

Так же как и Node.js, Bake ищет модули по восходящему пути в директориях bake_modules вплоть до корня системы. Например, если текущий путь проекта /home/user/projects/my-app, то модуль будет последовательно искаться в директориях:


/home/user/projects/my-app/bake_modules
/home/user/projects/bake_modules
/home/user/bake_modules
/home/bake_modules
/bake_modules

Установка


  • Deb-пакет для ubuntu:
    wget https://github.com/rumkin/bake/releases/download/v0.12.5/bake_0.12-5.deb
    sudo dpkg -i bake_012-5.deb
  • Установить из исходного кода на github:
        git clone https://github.com/rumkin/bake
        sudo cp bake/bake.sh /usr/bin/bake

Ссылки


Поделиться с друзьями
-->

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


  1. akzhan
    14.03.2017 23:24

    Хорошо бы поддержать еще ~/.bake/bake.sh и ~/bake/bake_modules.


    1. rumkin
      15.03.2017 01:06
      +1

      Обязательно добавлю в ближайших версиях.


  1. DmitrySokolov
    14.03.2017 23:42
    +2

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


    1. rumkin
      15.03.2017 01:43

      Спасибо за отклик. Bake нужен для автоматизации рутинных действий. В частности я использую в корневой папке проектов для быстрого скачивания проектов с гитхаба:


      bake hub drakkar

      Скачает с гитхаба мой репозиторий rumkin/drakkar.


      А команда bake init npt скачает шаблон репозитория rumkin/npt и переинициализирует git.


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


      1. DmitrySokolov
        15.03.2017 03:48
        +1

        Эти задачи (как ниже уже написали) можно решить, через скрипты из $HOME/bin.


        Свои алиасы под каждый проект, возможно, бывают полезны.


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


        Есть такой вот пример, чтоб были очевидны преимущества bake?


  1. aamonster
    14.03.2017 23:46
    +1

    Ничего не понимаю ©
    Таски имеют зависимости? Проверяется, построены ли они и не надо ли их перестроить? Если нет — то зачем это всё и при чём тут make/rake/… (которые вовсе не являются "таск раннерами", это системы сборки, первоочередная задача которых — проверка зависимостей)?
    Если да — то почему нельзя просто пользоваться make? (Потенциально — меньше порождений процессов, но вряд ли вы упёрлись в производительность, раз можете себе позволить bash)


    1. saboteur_kiev
      15.03.2017 00:44
      +2

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

      bash вполне поддерживает alias, и свой include (. / source), чтобы можно было сделать любые ваши таски в виде функций или алиасов.

      Есть давно сложившийся, ну не стандарт, но обычай создавать $HOME/bin и кидать туда свои скрипты, остается только добавить их в PATH.

      Чем принципиально bake важен/отличается?


      1. rumkin
        15.03.2017 01:37
        +2

        alias и source добавляют код в глобальную область видимости, т.е. для каждого проекта не получится получить свою изолированную среду.


        Обычно $HOME/bin по-умолчанию в $PATH добавляется, а все скрипты будут выполняться из текущей директории, а не из директории проекта. При этом Bake позволяет писать уникальный набор скриптов для конкретного проекта, а так же переиспользовать код в случае необходимости: например Bake поможет проверить все ли необходимые компоненты установлены в системе. При этом вы можете поместить bake.sh в репозиторий, а скрипты из $PATH/bin – нет.


        1. saboteur_kiev
          15.03.2017 03:09
          +2

          Почему я не могу писать уникальный набор скриптов для конкретного проекта и деплоить его в $HOME/bin?

          Каким образом Bake проверяет все ли компоненты установлены? Это же просто набор bash скриптов, которые неважно откуда я запущу?

          Другими словами, в статье написано как сделать helloworld на bake, но совершенно не описан что такое bake, и как он это делает. Хотя бы принцип. Все что вы написали мне — это элементарно реализуется на bash и не понятно, чем именно bake удобнее своего велосипеда.


          1. stas404
            15.03.2017 05:34
            +1

            не понятно, чем именно bake удобнее своего велосипеда.
            «bake» — это почти, как «bike». Но только «bake».


          1. VolCh
            15.03.2017 08:24
            +2

            Почему я не могу писать уникальный набор скриптов для конкретного проекта и деплоить его в $HOME/bin?

            Проектов много, а $HOME/bin — один, так что надо стараться, что бы набор были уникальным для каждого проекта, а не простые build.sh, deploy.sh и т. п., да и зачем выносить в глобальные области то, что специфично для проекта?


            Тут скорее уместный вопрос — чем лучше bake обычного набора скриптов в корне проекта или его каталога bin. Очевидно не нужно находиться в корне


            1. rumkin
              15.03.2017 12:23

              Проектов много, а $HOME/bin — один, так что надо стараться, что бы набор были уникальным для каждого проекта, а не простые build.sh, deploy.sh и т. п., да и зачем выносить в глобальные области то, что специфично для проекта?

              Именно. Спасибо.


              bake удобен тем что код вызывается из любой директивы проекта. При этом он вносит определенную упорядоченность. Как я уже писал выше, я использую bake как для запуска скриптов внутри проекта, так и для управления проектами. Т.е. если в директории есть bake.sh вы сразу понимаете, что указанные внутри команды необходимы для управления именно из этой директории, а ./bin не дает такого понимания, если находится за пределами проекта.


    1. rumkin
      15.03.2017 01:28
      +1

      Нет, bake – это именно таск раннер. Собственно rake так же используется как таск раннер, о чем написано в Википедии. По-моему, каждый из инструментов выполняет набор задач свойственных для языка, для которого он был разработан, т.е. для c/c++ – это сборка, для nodejs компиляция less/jsx/babel и деплой. Bake нужен для того чтобы автоматизировать рутину с помощью скриптов написанных на bash, например загрузку файлов по sftp или при создании бекапов данных во время разработки и т.п.


  1. ggo
    15.03.2017 09:32

    Идея потенциально интересна не как автоматизация своих рутинных действий, а как набор популярных публично доступных плагинов, устанавливаемых одной командой, и выполняющих что-то полезное для многих. Как раз то что делает rake.


    1. RUQ
      15.03.2017 09:45
      +1

      Типа Ansible?


      1. n0madic
        15.03.2017 10:56

        И былоб неплохо обеспечить удаленный запуск модулей по ssh, причем без предварительной установки самого bake на удаленном сервере


        1. rumkin
          15.03.2017 12:02

          Специально для этого есть модули ssh, sftp и rsync.


          1. n0madic
            15.03.2017 12:10
            +2

            я имел ввиду встроенный функционал типа:


            bake ssh имя_сервера имя_таска


            1. rumkin
              17.03.2017 21:27

              Интересная возможность, но нетривиальная с точки зрения использования голого bash'a.


  1. delvin-fil
    15.03.2017 15:09

    Да ну? То есть набор конспективных правил записанный в крон уже не устраивает?
    Вхождение на серверы ftp/ssh по alias тоже?
    Я даже и не знаю…


  1. prefrontalCortex
    15.03.2017 15:44

    Интересный инструмент.
    А есть возможность модифицировать окружение? Например, у меня в корне Python-проекта есть файлик env.sh со всякими приватными переменными (пароли, ключи и проч.), и каждый раз при начале работы над проектом я вынужден писать что-то типа


    source env.sh
    source .env/bin/activate

    Было бы круто, если бы я вместо этого мог просто сказать что-то вроде bake startdev.


    1. rumkin
      15.03.2017 15:54

      Есть, но пока не самое удачное решение, поэтому я его не описал. Можно использовать флаг -e для указания файла конфигурации например bake -e etc deploy подключит файл bake_etc.sh.


      1. VolCh
        15.03.2017 16:05
        +1

        Вообще сейчас много где используется файл .env по умолчанию, причём в нём исключительно переменные можно задать.


        1. rumkin
          15.03.2017 16:14

          Да, я сейчас думаю о таком варианте, но нужно прозрачно хранить разные конфигурации.


    1. rumkin
      15.03.2017 16:49
      +1

      Реализовал в версии 0.13 переключение между вариантами окружения. Описание в readme.


      1. prefrontalCortex
        17.03.2017 19:32

        Круто, спасибо!


  1. L0NGMAN
    16.03.2017 13:01

    @rumkin Есть у нас примерно такой же проект Tasker: https://github.com/thecotne/tasker
    Может заинтересует и даже сможем объединить функционал :)


  1. mukolaich
    20.03.2017 16:06
    +2

    В целом инструмент достаточно понятен и прост — это очень хорошая тулза для систематизации и автоматизации действий на рабочей машине.
    Например, задача — переключить окружение разработчика с php 7.0 на php 7.1. Это можно делать по старинке — написать bash скрипт, положите его в $PATH, и вызывать конкретно его. Или написать таску в bake.
    Если задача одна — все хорошо. Если их несколько — появляются проблемы, например:
    — как запомнить название всех баш скриптов
    — как дистрибьютить и версионировать много баш скриптов
    — как заморозить или откатить текущий набор баш скриптов
    Все эти задачи успешно решает bake.

    Еще примеры использования:
    — пересборка проекта (grunt, composer, phinx)
    — переключение окружений
    — перезапуск чего-угодно (nginx, fpm, tomcat)
    — кастомная автоматизация того, что вы используете

    В общем, спасибо за отличный инструмент!


    1. rumkin
      20.03.2017 17:15

      Комментарий, которого не хватало! Добавлю в следующий пресс-релиз с вашего позволения.


  1. rumkin
    20.03.2017 17:15

    [deleted]