2013-03-20 8 views
10

Czy istnieje sposób sprawdzenia, czy mam najnowszą wersję klejnotu z programu Ruby? To znaczy, czy jest jakiś sposób programowo wykonać bundle outdated #{gemname}?Sprawdź wersję klejnotu z wiązarką od wewnątrz Ruby

Próbowałem spojrzeć na kod źródłowy bundler'a, ale nie mogłem znaleźć prostego sposobu. Obecnie robię to, co jest delikatne, powolne i tak nieeleganckie:

IO.popen(%w{/usr/bin/env bundle outdated gemname}) do |proc| 
    output = proc.readlines.join("\n") 
    return output.include?("Your bundle is up to date!") 
end 
+0

Dziękuję, wiele odpowiedzi potwierdza moje odkrycia: nie ma na to API. Wybrałem jeden oparty na tym, że zapewnia działający fragment kodu, aby osiągnąć to zadanie. – Pablo

+0

Myślę, że wybrana odpowiedź ma kilka błędów. Istnieje "exit 1", który zakończyłby wykonywanie twojego programu. Czy udało ci się uruchomić ten kod? Podczas próby wypróbowania wystąpił błąd. – Emil

+0

Po prostu wprowadzili 'exit 1' pomiędzy wersjami 1.2.x i 1.3.x, więc teraz wymaga trochę łatania małp do pracy. –

Odpowiedz

6

dla uniknięcia wykonania zewnętrzne:

Dla Bundler 1.2.x

require 'bundler/cli' 

# intercepting $stdout into a StringIO 
old_stdout, $stdout = $stdout, StringIO.new 

# running the same code run in the 'bundler outdated' utility 
Bundler::CLI.new.outdated('rails') 

# storing the output 
output = $stdout.string 

# restoring $stdout 
$stdout = old_stdout 

Na Bundler 1.3.x

require 'bundler/cli' 
require 'bundler/friendly_errors' 

# let's cheat the CLI class with fake exit method 
module Bundler 
    class CLI 
    desc 'exit', 'fake exit' # this is required by Thor 
    def exit(*); end   # simply do nothing 
    end 
end 

# intercepting $stdout into a StringIO 
old_stdout, $stdout = $stdout, StringIO.new 

# running the same code run in the 'bundler outdated' utility 
Bundler.with_friendly_errors { Bundler::CLI.start(['outdated', 'rails']) } 

# storing the output 
output = $stdout.string 

# restoring $stdout 
$stdout = old_stdout  
+0

Wystąpił błąd podczas uruchamiania tego. Również 'nieaktualny' ma podstępne' exit 1'. Nie sądzę, żeby to działało w ten sposób. – Emil

+0

Hmm. Prawdziwe. Działa z bundler 1.2.3 i zrywa z 1.3.5. –

+0

Opublikowałem aktualizację workng z 1.3.5 –

0

bundle check listy kamienie, które są obecnie na bieżąco, można z niego korzystać.

+0

Moje pytanie dotyczy uruchamiania go z poziomu Ruby, programowo. – Pablo

3

Nie ma programowego sposobu użycia polecenia outdated w bundler, ponieważ kod znajduje się w pliku Thor CLI, który drukuje dane wyjściowe do użytkownika. Testy bundlerów również wysyłają polecenie do systemu i sprawdzają dane wyjściowe (Link to outdated tests).

Powinno być dość proste napisanie własnej metody odwzorowania, co robi metoda outdated w cli.rb. Zobacz podświetlony kod tutaj: Link to outdated method in Bundler source. Usuń wiersze z Bundler.ui i return true/false na podstawie wartości out_count

Aktualizacji: Mam ekstrakcji „wiązka przestarzały” do wielokrotnego użytku metodą bez wyjścia konsoli i wyjść. Możesz znaleźć sedno tutaj: link to gist. Przetestowałem to na pakiecie 1.3 i wygląda na to, że działa.

+0

Niestety, będzie to jedyny prawdziwy sposób na programowanie. Jestem zaskoczony, jak kiepsko napisany jest Bundler. W ogóle nie ma oddzielenia obaw; kod interfejsu użytkownika jest całkowicie spleciony z logiką kontroli wersji. To smutne patrzeć. –

+0

@JimStewart, jestem prawie pewien, że zaakceptują wkład z kilkoma punktami odniesienia. –

0

Hmmm, brzmi jak może chcesz bundle show lub gem env

0

Kiepski, to wygląda zaskakująco trudne.

Istnieje kilka openissues w Bundler gdzie oficjalna linia wydaje się być:

W tym momencie, nie jest to udokumentowane rubin API. Jest to jednak coś, co jest na naszej liście.

Przeglądając kod źródłowy Bundler cli.rb, to dość oczywiste, że to będzie trudne do połączenia z rubinu lub odtworzenia kodu w rozsądny sposób.

Metody wywoływania z interfejsu CLI będą trudne, ponieważ zostaną posypane calls to exit.

Odtwarzanie kodu również nie wygląda zabawnie, ponieważ jest tam dość dużo logiki bundlerów.

Powodzenia!

0

sprawdzenie kodu źródłowego kodu źródłowego najnowszy Bundler

mogłem wymyślić tego

https://github.com/carlhuda/bundler/blob/master/lib/bundler/cli.rb#L398

$ irb 
1.9.3p327 :001 > require 'bundler' 
=> true 
1.9.3p327 :002 > def outdated_gems(gem_name,options={}) 
1.9.3p327 :003?> options[:source] ||= 'https://rubygems.org' 
1.9.3p327 :004?> sources = Array(options[:source]) 
1.9.3p327 :005?> current_spec= Bundler.load.specs[gem_name].first 
1.9.3p327 :006?> raise "not found in Gemfile" if current_spec.nil? 
1.9.3p327 :007?> definition = Bundler.definition(:gems => [gem_name], :sources => sources) 
1.9.3p327 :008?> options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely! 
1.9.3p327 :009?>  active_spec = definition.index[gem_name].sort_by { |b| b.version } 
1.9.3p327 :010?> if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1 
1.9.3p327 :011?>    active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? } 
1.9.3p327 :012?>   end 
1.9.3p327 :013?>  active_spec = active_spec.last 
1.9.3p327 :014?>  raise "Error" if active_spec.nil? 
1.9.3p327 :015?> outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version) 
1.9.3p327 :016?> {:outdated=>outdated,:current_spec_version=>current_spec.version.to_s,:latest_version=>active_spec.version.to_s} 
1.9.3p327 :017?> end 
=> nil 
1.9.3p327 :018 > 
1.9.3p327 :019 > 
1.9.3p327 :020 > 
1.9.3p327 :021 > 
1.9.3p327 :022 > outdated_gems('rake') 
=> {:outdated=>true, :current_spec_version=>"10.0.3", :latest_version=>"10.0.4"} 

to nie może pracować z wcześniejszej wersji Bundler.

Powiązane problemy