Ответ 1
Пахнет как ошибка Cap 3.
Я предлагаю просто гарантировать, что вы находитесь там, где хотите быть в ракурсе:
execute "cd '#{release_path}'; #{fetch(:composer_command)} install"
Я пытаюсь написать задачу для Capistrano 3, которая предполагает выполнение "установки композитора" в каталоге текущей версии. Это выглядит примерно так:
namespace :composer do
desc 'Install dependencies with Composer'
task :install do
on roles(:web) do
within release_path do
execute "#{fetch(:composer_command)} install"
end
end
end
end
composer_command
задается в промежуточных и производственных файлах - в моем конкретном случае - php /home/user/composer.phar
По какой-то причине эта команда фактически не запускается в текущей папке выпуска, но вместо этого выполняется в родительском каталоге (содержащем текущий, общий, выпуск и т.д.)
Я углубился в это немного дальше и обнаружил, что когда я запускал одну команду слов, например:
within release_path do
execute "pwd"
end
Он отлично работает и запускает команду в текущей директории выпуска. Но..., когда я запускаю команду с пробелами, например:
within release_path do
execute "pwd && ls"
end
Он запускается в родительском каталоге, а не в каталоге, установленном блоком within
.
Может кто-то пролить свет на это? Спасибо!
Пахнет как ошибка Cap 3.
Я предлагаю просто гарантировать, что вы находитесь там, где хотите быть в ракурсе:
execute "cd '#{release_path}'; #{fetch(:composer_command)} install"
Несколько советов:
1) Capistrano использует SSHKit для многих вещей, среди которых исполнение команды. Чтобы упростить использование Composer, вы можете настроить карту команд (в deploy.rb
или production.rb
и т.д.), Вот 2 примера:
SSHKit.config.command_map[:composer] = "#{shared_path.join('composer.phar')}"
SSHKit.config.command_map[:composer] = '/usr/bin/env composer.phar'
Затем вы можете выполнить его так:
execute :composer, :install
2) С точки зрения безопасности разумно отключить настройку php allow_url_fopen
, но, к сожалению, Composer нуждается в ее активации. Вы можете использовать этот трюк, чтобы он был отключен глобально:
SSHKit.config.command_map[:composer] = "/usr/bin/env php -d allow_url_fopen=On #{shared_path.join('composer.phar')}"
Ознакомьтесь с iniscan, чтобы узнать больше о настройках php.
3) У Composer есть опция -d, --working-dir
, которую вы можете указать в каталог, содержащий файл composer.json
, чтобы запустить Composer из любого другого каталога. Это должно решить вашу проблему:
execute :composer, '-d', release_path, :install
4) Вы можете взглянуть на проект capistrano-composer:)
Вы можете сохранить все тонкости within()
, with()
, default_env
и т.д., сохраняя при этом естественный синтаксис строки:
within release_path do
execute *%w[ pip install -r requirements.txt ]
end
Собственно, использование функции within
почти корректно. Вы предоставили ему целую строку в качестве команды, но док указывает, что это приводит к ненадежному поведению (которое я испытал сам).
Пусть первый аргумент execute
будет символом вместо строки (содержащей пробелы):
within release_path do
execute fetch(:composer_command).to_sym, "install"
execute :pwd
execute :ls
end
для справки здесь Capistrano Doc, объясняющий, почему within {}
не работает с аргументами с пробелом. Надеюсь, это поможет.