2013-10-18 13 views
25

Próbuję napisać zadanie dla Capistrano 3, które polega na wykonaniu "instalacji kompozytora" w katalogu aktualnej wersji. Wygląda to mniej więcej tak:Wykonanie Capistrano 3 w katalogu

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 jest ustawiony w plikach postoju i produkcji - w moim przypadku do php /home/user/composer.phar

Z jakiegoś powodu ta komenda nie faktycznie uruchomić w katalogu bieżącego wydania, ale zamiast przebiega w katalogu nadrzędnego (zawierające aktualne, dzielone, komunikaty, itp)

i zagłębił się to nieco dalej i stwierdził, że kiedy zabrakło jednego polecenia słowo, np:

within release_path do 
    execute "pwd" 
end 

Działa dobrze, i uruchamia polecenie w bieżącym katalogu wydania. Ale ... kiedy uruchomić polecenie z pomieszczeń, jak:

within release_path do 
    execute "pwd && ls" 
end 

biegnie w katalogu nadrzędnego, a nie katalogu określonego przez blok within.

Czy ktoś może rzucić trochę światła na to? Dzięki!

Odpowiedz

25

Pachnie jak bug Cap 3.

Proponuję tylko gwarantując jesteś gdzie chcesz być z perspektywy powłoki:

execute "cd '#{release_path}'; #{fetch(:composer_command)} install" 
+3

Podniosłem problem - https://github.com/capistrano/capistrano/issues/719 Okazuje się, że jest to ograniczenie z SSHKit. Więc pójdę z twoim rozwiązaniem - starym capistrano 2 way, jak to było. –

+4

To nie jest błąd. Tak działa SSHKit. Zobacz inne odpowiedzi. – gagarine

+0

Skały, dzięki! –

7

Kilka porad:

1) Capistrano wykorzystuje SSHKit za wiele rzeczy, wśród których komenda wykonanie. W celu uproszczenia korzystania Composer można skonfigurować mapę polecenia (w deploy.rb lub production.rb itp), tu są 2 przykłady:

SSHKit.config.command_map[:composer] = "#{shared_path.join('composer.phar')}" 
SSHKit.config.command_map[:composer] = '/usr/bin/env composer.phar' 

Następnie można wykonać go tak:

execute :composer, :install 

2) Z perspektywy bezpieczeństwa dobrze jest wyłączyć ustawienie php allow_url_fopen, ale niestety Composer potrzebuje go włączyć. Można użyć tej sztuczki, aby pozostawić wyłączony globalnie:

SSHKit.config.command_map[:composer] = "/usr/bin/env php -d allow_url_fopen=On #{shared_path.join('composer.phar')}" 

Wyjazd iniscan więcej porad zabezpieczającego w ustawieniach PHP.

3) Kompozytor ma opcję -d, --working-dir, w której można wskazać katalog zawierający plik composer.json, aby uruchomić program Composer z dowolnego innego katalogu. To powinno rozwiązać problem:

execute :composer, '-d', release_path, :install 

4) Możesz spojrzeć na projekt capistrano-composer :)

+0

Nie wiem, czy jest to spowodowane aktualizacją Capistrano, czy moją konkretną sprawą kompilacji, ale musiałem nieco zmodyfikować twój drugi przykład: 'SSHKit.config.command_map [: composer] ="/[direct full ścieżka do] /composer.phar "' wewnątrz mojego deploy.rb. Potem dodanie "execute: composer", "install" w moim pliku .rake działało bez zarzutu. – karolus

4

Właściwie, korzystanie z funkcji within jest prawie poprawne.Dostarczyłeś mu cały ciąg jako polecenie, ale doc wskazuje, że powoduje to nierzetelne zachowanie (którego sam doświadczyłem).

Niech pierwszy argument execute być symbolem zamiast łańcucha (który zawiera spacje):

within release_path do 
    execute fetch(:composer_command).to_sym, "install" 
    execute :pwd 
    execute :ls 
end 
7

można zachować wszystkie subtelności within(), with(), default_env, itp, zachowując naturalny ciąg składnia:

within release_path do 
    execute *%w[ pip install -r requirements.txt ] 
end 
3

tylko dla odniesienia tutaj jest Capistrano Doc wyjaśniając dlaczego within {} nie działa z argumentów ze spacjami. Mam nadzieję, że to pomoże.

Powiązane problemy