32

我正在尝试为 Capistrano 3 编写一个任务,该任务涉及在当前版本的目录中执行“composer install”。它看起来像这样:

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块设置的目录。

有人可以对此有所了解吗?谢谢!

4

5 回答 5

33

闻起来像 Cap 3 的虫子。

我建议从 shell 的角度保证你在你想去的地方:

execute "cd '#{release_path}'; #{fetch(:composer_command)} install"
于 2013-10-18T21:19:53.167 回答
11

您可以保留, , 等的所有细节within(),同时仍保持自然字符串语法:with()default_env

within release_path do
  execute *%w[ pip install -r requirements.txt ]
end
于 2014-07-07T00:44:14.463 回答
7

几个提示:

1) Capistrano 使用SSHKit做很多事情,其中​​包括命令执行。为了简化使用 Composer,您可以配置命令映射(在deploy.rborproduction.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项目:)

于 2014-01-11T21:04:19.203 回答
5

实际上,您对该within功能的使用几乎是正确的。您已将整个字符串作为命令提供给它,但文档指出这会导致不可靠的行为(我自己经历过)。

让第一个参数execute是一个符号而不是一个字符串(包含空格):

within release_path do
    execute fetch(:composer_command).to_sym, "install"
    execute :pwd
    execute :ls
end
于 2014-06-26T22:41:42.387 回答
3

仅供参考的是Capistrano Doc ,解释了为什么within {}不能使用带有空格的参数。我希望这有帮助。

于 2015-09-10T10:26:37.303 回答