J'essaie d'écrire une tâche pour Capistrano 3 qui implique d'exécuter une "installation du compositeur" dans le répertoire de la version actuelle. Cela ressemble à ceci:
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
est défini dans les fichiers de transfert et de production - dans mon cas particulier sur php /home/user/composer.phar
Pour une raison quelconque, cette commande ne s'exécute pas réellement dans le répertoire de la version actuelle, mais s'exécute à la place dans le répertoire parent (contenant les versions actuelles, partagées, etc.)
J'ai approfondi un peu plus loin et j'ai constaté que lorsque j'exécutais une seule commande Word, comme:
within release_path do
execute "pwd"
end
Cela fonctionne très bien et exécute la commande dans le répertoire de version actuel. Mais ... lorsque j'exécute une commande avec des espaces, comme:
within release_path do
execute "pwd && ls"
end
Il s'exécute dans le répertoire parent et non dans le répertoire défini par le bloc within
.
Quelqu'un peut-il nous éclairer à ce sujet? Merci!
Ça sent comme un bogue de Cap 3.
Je suggère simplement de garantir que vous êtes là où vous voulez être du point de vue de Shell:
execute "cd '#{release_path}'; #{fetch(:composer_command)} install"
Vous pouvez conserver toutes les subtilités de within()
, with()
, default_env
, etc., tout en conservant la syntaxe de chaîne naturelle:
within release_path do
execute *%w[ pip install -r requirements.txt ]
end
Quelques conseils:
1) Capistrano utilise SSHKit pour beaucoup de choses, parmi lesquelles l'exécution de commandes. Afin de simplifier l'utilisation de Composer, vous pouvez configurer la mappe de commande (dans deploy.rb
ou production.rb
, etc.), voici 2 exemples:
SSHKit.config.command_map[:composer] = "#{shared_path.join('composer.phar')}"
SSHKit.config.command_map[:composer] = '/usr/bin/env composer.phar'
Ensuite, vous pouvez l'exécuter comme suit:
execute :composer, :install
2) Du point de vue de la sécurité, il est sage de désactiver le paramètre php allow_url_fopen
, mais malheureusement Composer a besoin qu'il soit activé pour fonctionner. Vous pouvez utiliser cette astuce pour le désactiver globalement:
SSHKit.config.command_map[:composer] = "/usr/bin/env php -d allow_url_fopen=On #{shared_path.join('composer.phar')}"
Consultez iniscan pour plus de conseils de sécurité sur les paramètres php.
3) Composer a une option -d, --working-dir
, que vous pouvez pointer vers le répertoire contenant le composer.json
fichier pour exécuter Composer à partir de tout autre répertoire. Cela devrait résoudre votre problème:
execute :composer, '-d', release_path, :install
4) Vous voudrez peut-être jeter un œil au projet capistrano-composer :)
En fait, votre utilisation de la fonction within
est presque correcte. Vous lui avez fourni une chaîne entière en tant que commande, mais le doc souligne que cela se traduit par un comportement peu fiable (que j'ai moi-même expérimenté).
Soit le premier argument de execute
un symbole au lieu d'une chaîne (qui contient des espaces):
within release_path do
execute fetch(:composer_command).to_sym, "install"
execute :pwd
execute :ls
end
juste pour référence ici est le Capistrano Doc expliquant pourquoi within {}
ne fonctionne pas avec les arguments avec des espaces. J'espère que ça aide.