Homebrew Bundle, brew bundle и Brewfile
Homebrew Bundle запускается командой brew bundle.
Для предоставления декларативного интерфейса установки и обновления пакетов с помощью Homebrew и запуска служб с помощью brew services используются Brewfile.
Вместо того чтобы указывать команды brew, которые нужно выполнить, можно указать состояние, которого нужно достичь.
См. также раздел brew bundle в man brew или brew bundle --help.
Основные сведения об использовании
brew bundle
Простой Brewfile может содержать формулу:
brew "ruby"
При запуске brew bundle install (или просто brew bundle), инструкции будут взяты из Brewfile для выполнения brew install ruby и установки Ruby, если он ещё не установлен.
$ brew bundle Installing ruby `brew bundle` complete! 1 Brewfile dependency now installed.
Если пакет устарел, будет выполнена команда brew upgrade ruby. Если он уже установлен, ничего не произойдёт.
$ brew bundle install Using ruby `brew bundle` complete! 1 Brewfile dependency now installed.
brew bundle check
Проверить, приведёт ли brew bundle install к каким-либо действиям, можно с помощью команды:
$ brew bundle check The Brewfile's dependencies are satisfied.
Это поведение можно использовать в скриптах следующим образом:
brew bundle check || brew bundle install
Если команда завершается с ошибкой без --verbose, выполните brew bundle check --verbose, чтобы вывести список неудовлетворённых зависимостей.
Типы
Помимо поддержки формул (brew "..."), brew bundle также можно использовать с cask-пакетами, tap-репозиториями, приложениями из Mac App Store, пакетами WinGet в WSL, расширениями VSCode, пакетами Go и Cargo, инструментами uv, пакетами Flatpak и плагинами krew для kubectl, а также для запуска фоновых служб с помощью brew services.
tap "apple/apple" brew "apple/apple/game-porting-toolkit" brew "postgresql@16", restart_service: true cask "firefox" mas "Refined GitHub", id: 1519867270 winget "Steam", id: "Valve.Steam" winget "PowerToys", id: "XP89DCGQ3K6VLD", source: "msstore" vscode "editorconfig.editorconfig" go "github.com/charmbracelet/crush" cargo "ripgrep" uv "mkdocs" krew "ctx" flatpak "com.visualstudio.code" flatpak "org.godotengine.Godot", remote: "flathub-beta", url: "https://dl.flathub.org/beta-repo/" flatpak "io.github.dvlv.boxbuddyrs", remote: "flathub-beta"
Установка WinGet выполняется с отключённым взаимодействием с установщиком. Если WinGet сообщает о необходимости повышения привилегий, brew bundle повторяет попытку через контроль учётных записей Windows (UAC).
Выполните brew bundle ещё раз, чтобы получить следующий вывод:
$ brew bundle Using apple/apple Using apple/apple/game-porting-toolkit Using postgresql@16 Using firefox Using Refined GitHub Using editorconfig.editorconfig Using github.com/charmbracelet/crush Using ripgrep Using mkdocs `brew bundle` complete! 9 Brewfile dependencies now installed.
Проекты
Добавление Brewfile в репозиторий проекта (как это можно сделать с package.json, Gemfile или requirements.txt) — удобный способ описать зависимости проекта для среды разработки.
Это позволяет предложить пользователям выполнить одну команду, чтобы установить все зависимости проекта и запустить необходимые службы.
Поскольку Homebrew поддерживает macOS, Linux и WSL, с помощью одной команды можно настроить зависимости проекта в трёх операционных системах, а также в службах непрерывной интеграции, таких как GitHub Actions (где Homebrew по умолчанию установлен в macOS и легко устанавливается в Linux с помощью Homebrew/actions/setup-homebrew).
См. пример «Scripts To Rule Them All» от GitHub script/bootstrap, в котором показано, как использовать Brewfile и brew bundle для установки зависимостей проекта с помощью Homebrew.
brew bundle dump
Brewfile также можно использовать для сохранения всех поддерживаемых пакетов в одном файле. brew bundle dump — это команда Homebrew для создания снимка установленного состояния: она записывает поддерживаемые установленные формулы, cask-пакеты, tap-репозитории и другие типы пакетов в Brewfile.
Для этого можно использовать brew bundle dump --global --force, чтобы записать данные, например, в ~/.Brewfile (проверьте man brew, чтобы узнать точный путь, используемый в вашей конфигурации):
brew bundle dump --global --force
По умолчанию сгенерированный Brewfile также содержит описания каждого пакета:
brew bundle dump --global --force
может добавить что-то вроде следующего:
# Powerful, clean, object-oriented scripting language brew "ruby"
Затем можно восстановить все эти пакеты (и по умолчанию обновить их) с помощью команды:
brew bundle --global
Можно хранить несколько снимков, записывая их в разные Brewfile с помощью --file, добавлять их в систему контроля версий и сравнивать стандартными инструментами diff. Чтобы привести текущее установленное состояние в большее соответствие со снимком, после его установки выполните brew bundle cleanup --force --file=/path/to/Brewfile, чтобы удалить поддерживаемые зависимости, не указанные в этом Brewfile.
Дополнительные сведения об использовании
brew bundle cleanup
Если вы использовали brew bundle dump, чтобы сохранить список всего используемого программного обеспечения, можно быстро удалить всё остальное командой:
$ brew bundle cleanup --global --force Uninstalling gcc... (1,914 files, 459.8MB) Uninstalled 1 formula
brew bundle list
Чтобы получить список всех формул в вашем Brewfile, выполните команду:
$ brew bundle list apple/apple/game-porting-toolkit postgresql@16
Списки других типов можно получить, например, так:
$ brew bundle list --cask firefox
brew bundle edit
Чтобы открыть Brewfile в текстовом редакторе, выполните команду:
$ brew bundle edit Editing /some/project/Brewfile
brew bundle add и brew bundle remove
Добавлять и удалять записи в Brewfile можно с помощью команд brew bundle add и brew bundle remove:
brew bundle add wget brew bundle remove wget
brew bundle exec
brew bundle exec позволяет запускать команду в среде, настроенной с учётом вашего Brewfile.
Например, если у вас есть Brewfile вида:
brew "node"
Это гарантирует, что вы всегда запускаете правильный node:
$ brew bundle exec which node /opt/homebrew/opt/node/bin/node
Это особенно полезно при сборке программного обеспечения, зависящего от других программ в вашем Brewfile. brew bundle exec настроит все необходимые пути для обнаружения всего программного обеспечения в вашем Brewfile, независимо от того, подключено ли оно через символьные ссылки, является ли оно keg-only или нет. Это позволяет избежать проблем, связанных с конфигурацией PATH отдельного пользователя или компьютера.
Если вы хотите не запускать явно brew bundle check или brew bundle install перед brew bundle exec, можно использовать:
brew bundle exec --check brew bundle exec --install
Чтобы запускать все службы из вашего Brewfile только на время выполнения brew bundle exec, используйте:
brew bundle exec --services
Обратите внимание: внутри brew bundle exec, brew bundle sh и brew bundle env для удобства обнаружения переменной окружения HOMEBREW_INSIDE_BUNDLE присваивается значение 1.
brew bundle sh
brew bundle sh похож на brew bundle exec, но запускает выбранную вами интерактивную оболочку, например brew sh:
$ brew bundle sh brew bundle $ which node /opt/homebrew/opt/node/bin/node
В основе этой команды лежит тот же механизм, что и у brew bundle exec, поэтому применяются те же аргументы (например, --check, --install, --services).
brew bundle env
brew bundle env выводит все переменные окружения в формате, который можно добавить в оболочку.
$ brew bundle env | grep node
export PATH="/opt/homebrew/opt/node/bin:${PATH:-}" Это можно использовать вместе с eval, чтобы преобразовать текущую среду оболочки в brew bundle exec или brew bundle sh:
$ eval "$(brew bundle env)"
$ echo "${PATH}" | grep node
/opt/homebrew/opt/node/bin:/opt/homebrew/bin:/usr/bin:/bin В основе этой команды также лежит тот же механизм, что и у brew bundle exec, поэтому применяются те же аргументы (например, --check, --install).
brew bundle upgrade и HOMEBREW_BUNDLE_NO_UPGRADE=1
По умолчанию brew bundle пытается обновить всё программное обеспечение. Это поведение можно отключить, передав --no-upgrade или задав export HOMEBREW_BUNDLE_NO_UPGRADE=1 в окружении.
Это лишь пропускает brew upgrade. Команда не фиксирует версии и не поддерживает файлы блокировки.
В этом случае всё можно обновить командой:
brew bundle upgrade
или выборочные формулы, например, так:
brew bundle --upgrade-formulae ruby
Расширенные возможности Brewfile
Brewfile поддерживают множество других небольших возможностей.
Brewfile интерпретируются как Ruby, поэтому в них можно использовать логику Ruby.
Однако обратите внимание, что некоторые фрагменты кода могут приводить к разным результатам или поведению на разных компьютерах.
Вместо того чтобы перечислять все возможности Brewfile по отдельности, приведём пример с комментариями, демонстрирующий некоторые полезные варианты использования:
# Run `brew tap` with a custom URL
tap "user/tap-repository", "https://user@bitbucket.org/user/homebrew-tap-repository.git"
# Set arguments passed to all `brew install --cask` commands for `cask "..."`
# In this example, pass `--appdir=~/Applications` and `--require_sha`
cask_args appdir: "~/Applications", require_sha: true
# Pass options to non-Homebrew/core formulae e.g. `brew install denji/nginx/nginx-full --with-rmtp`
# This also runs `brew link --overwrite nginx-full` and `brew services restart nginx-full` afterwards.
brew "denji/nginx/nginx-full", link: :overwrite, args: ["with-rmtp"], restart_service: :always
# Runs `brew install mysql@5.6`, `brew services restart mysql@5.6` only if it was installed or upgraded,
# `brew link mysql@5.6` and `brew unlink mysql` (if `mysql` is installed)
brew "mysql@5.6", restart_service: :changed, link: true, conflicts_with: ["mysql"]
# Runs `brew install postgresql@16` and then runs a postinstall command if `postgresql@16` was installed or upgraded.
brew "postgresql@16",
postinstall: "${HOMEBREW_PREFIX}/opt/postgresql@16/bin/postgres -D ${HOMEBREW_PREFIX}/var/postgresql@16"
# Runs `brew install ruby` and, afterwards, writes the installed version to the '.ruby-version` file.
brew "ruby", version_file: ".ruby-version"
# Trusts the tap, formula or cask so Homebrew loads it when tap trust is required.
# This works on `tap`, `brew` and `cask` entries.
tap "user/repository", trusted: true
brew "user/repository/formula", trusted: true
cask "user/repository/cask", trusted: true
# Trusts only named formulae, casks or commands from a tap.
tap "user/repository", trusted: {
formula: "formula",
casks: ["cask"],
commands: ["command"],
}
# Runs `brew install gnupg` or `brew install glibc` only on the specified OS.
# Note: `brew bundle list` will not output `gnupg` on Linux or `glibc` on macOS` in this case:
# the Ruby logic means they are "hidden" on other platforms.
brew "gnupg" if OS.mac?
brew "glibc" if OS.linux?
# Runs `brew install --cask --appdir=~/my-apps/Applications`
cask "firefox", args: { appdir: "~/my-apps/Applications" }
# Runs `brew upgrade opera` to upgrade an auto-updated or unversioned Opera cask
# to the latest version even if already installed.
# This is used to force an upgrade in software that would typically update itself.
cask "opera", greedy: true
# Runs `brew install --cask java` only if '/usr/libexec/java_home --failfast` fails (i.e there is no Java)
# Note: `brew bundle list` will not output `java` if this `system` command succeeds and
# this `system` command will be run even on `brew bundle check`, not just `brew bundle install`.
cask "java" unless system "/usr/libexec/java_home", "--failfast"
# Runs `brew install --cask` and runs the command if the Google Cloud cask was installed or upgraded.
cask "google-cloud-sdk", postinstall: "${HOMEBREW_PREFIX}/bin/gcloud components update"
# Sets an environment variable to be used e.g. inside `brew bundle exec` or `system` commands in the `Brewfile`.
# Note: HOMEBREW_PREFIX/bin is _not_ in the `PATH` by default so you can set it this way.
ENV["SOME_ENV_VAR"] = "some_value" version_file
В записях формул поддерживается version_file:, позволяющий записать установленную версию формулы в файл после того, как brew bundle install обработает эту формулу. Это полезно, когда проекту нужно, чтобы Homebrew установил среду выполнения и поддерживал стандартный файл версии, например .ruby-version, в актуальном состоянии.
brew "ruby", version_file: ".ruby-version"
trusted
Записи tap, brew и cask поддерживают trusted: true для декларативного предоставления доверия неофициальному tap-репозиторию, формуле или cask-пакету. Homebrew доверяет записи до её установки, поэтому она загружается даже в том случае, если для этого требуется доверие к tap-репозиторию.
tap "user/repository", trusted: true brew "user/repository/formula", trusted: true cask "user/repository/cask", trusted: true
Записи tap-репозиториев также могут предоставлять доверие отдельным формулам, cask-пакетам и командам из этого tap-репозитория, не предоставляя доверие всему tap-репозиторию:
tap "user/repository", trusted: {
formula: "formula",
formulae: ["another-formula"],
cask: "cask",
casks: ["another-cask"],
command: "command",
commands: ["another-command"],
} Можно использовать как ключи в единственном, так и во множественном числе. Значения — это имена элементов в данном tap-репозитории, поэтому formula: "foo" для tap "user/repository" предоставляет доверие к user/repository/foo как к формуле.
Как и в случае с brew trust, предпочтительнее предоставлять доверие нужной формуле, cask-пакету или команде, а не всему tap-репозиторию. brew bundle dump записывает trusted: true для доверенных записей brew, cask и записей целых tap-репозиториев. Для доверенных формул, cask-пакетов и команд из tap-репозитория, которые иначе не попадают в сохранённый Brewfile, записываются хеши доверия на уровне tap-репозитория.
При запуске brew bundle cleanup --force файл доверия Homebrew сбрасывается до значений, указанных в Brewfile, а записи о доверии, не указанные там, удаляются.
Версии
Homebrew — это менеджер пакетов с непрерывным выпуском обновлений, поэтому он не поддерживает установку произвольных старых версий программного обеспечения.
В brew bundle нет и не будет понятия «файла блокировки Brewfile», который можно использовать для фиксации версий, как, например, в package-lock.json или Gemfile.lock.
Чтобы запретить brew bundle обновлять установленные зависимости, передайте --no-upgrade или задайте export HOMEBREW_BUNDLE_NO_UPGRADE=1.
О компромиссах и альтернативных вариантах см. в разделе Фиксация установленных формул на определённых версиях.
Добавление поддержки новых пакетов
В настоящее время brew bundle поддерживает Homebrew, Homebrew Cask, Mac App Store, пакеты WinGet в WSL, Visual Studio Code (а также его форки и варианты), пакеты Go и Cargo, инструменты uv, пакеты Flatpak и плагины krew для kubectl.
Мы приветствуем вклад в поддержку установщиков, средств проверки и создания дампов для других пакетов, но они должны:
- устанавливать программное обеспечение без участия пользователя
- проверять, установлено ли программное обеспечение
- создавать дамп установленного программного обеспечения в формате, который можно сохранить в
Brewfile - не требовать
sudoдля установки (cask-пакеты — исключение) - быть чрезвычайно широко распространёнными
© 2009–present Homebrew contributors
Licensed under the BSD 2-Clause License.
https://docs.brew.sh/Brew-Bundle-and-Brewfile