2011-01-04 10 views
6

ten sposób wykryć git w Ruby:Platforma niezależny sposób wykrywania, jeśli jest zainstalowany git

`which git 2>/dev/null` and $?.success? 

Jednak to nie jest cross-platform. Nie działa na systemach innych niż systemy uniksowe lub bez komendy which (chociaż nie jestem pewien, co to jest).

Potrzebuję sposób wykryć git, który spełnia następujące warunki:

  1. działa niezawodnie cross-platform, nawet na Windows
  2. nie robi nic wyjściowego $ stdout lub stderr $
  3. niewielka ilość kodu

Aktualizacja: rozwiązanie jest aby całkowicie nie używać which i przekierować wyjście do NUL w systemie Windows.

require 'rbconfig' 
void = RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw/ ? 'NUL' : '/dev/null' 
system "git --version >>#{void} 2>&1" 

W system dowodzenia Zwraca TRUE w przypadku sukcesu, FALSE w przypadku porażki, oszczędzając nam wycieczkę do $?.success? które jest potrzebne do korzystania odwrócone, pojedyncze apostrofy.

+0

Może http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby/ 2108757 # 2108757 może pomóc? – VonC

+0

Przebaczam moją potencjalną głupotę, ale nie "która" pisze na stdout? –

+0

@Steven: oczywiście, ale w swojej własnej podpowiedzi, i widzisz, że użyłem backticków, które przechwytują to wyjście w wartości zwrotnej, którą następnie odrzucam. Jeśli 'który' napisał coś do STDERR, ruby ​​przekazałby to do $ stderr programu głównego (coś, czego nie chcę się wydarzyć), więc użyłem' 2>/dev/null' aby to obsłużyć. – mislav

Odpowiedz

4

W systemie Windows nie ma czegoś takiego jak /dev/null.

Jedno podejście bierzemy w różnych projektach jest zdefiniowanie NULL podstawie RbConfig::CONFIG['host_os']

NULL = RbConfig::CONFIG['host_os'] =~ /mingw|mswin/ ? 'NUL' : '/dev/null' 

Następnie używać, aby przekierować zarówno STDOUT i stderr do niego.

Jak dla których zrobiłem trywialny odniesienia na my blog

Ale jeśli chcesz tylko sprawdzić obecność git, a nie lokalizację, nie trzeba robić, która za pomocą prostego połączenia systemu i sprawdzenie wyniku $? wystarczy.

Nadzieja to pomaga

+0

Kiedy nazywam 'git', a następnie sprawdzam' $ ?. success? ', Wynik jest zawsze prawdziwy, nawet jeśli git nie jest zainstalowany. (Ruby 1.9.2, i686-pc-mingw32 na Win XP) – mislav

+1

https://gist.github.com/765328 –

+0

BTW użył tej techniki z kompilatorem rake, aby wykryć gmake/make na różnych platformach: https: // github.com/luislavena/rake-compiler/blob/master/lib/rake/extensiontask.rb#L352-354 –

0

Być może działa na JRuby i korzystania JGit może być jedną z opcji, aby przejść naprawdę niezależny od platformy.

+0

, ale "co" nie będzie działać w systemie Windows. Probl. nie jest przenośnością ruby. – zengr

+0

@zengr: Pomysł polegałby na tym, aby w ogóle nie używać natywnej implementacji git, ale JGit, czystej implementacji git w Javie. –

+0

, ale co jeśli użytkownik końcowy używa git (a nie jgit), pozostanie niewykryty, a aplikacja OPs zainstaluje jgit WITH git, który był już na komputerze. – zengr

1

ten to rozwiązanie, które pozwala uniknąć wykrycia wykrycia plików wykonywalnych i jest w stanie wiarygodnie wykryć, gdzie znajduje się plik wykonywalny. Jest to alternatywa dla which.

def which cmd 
    exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] 
    ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| 
    exts.each { |ext| 
     exe = "#{path}/#{cmd}#{ext}" 
     return exe if File.executable? exe 
    } 
    end 
    return nil 
end 

Zastosowanie:

# Mac OS X 
where 'ruby' 
#=> /opt/local/Cellar/ruby-enterprise-edition/2010.02/bin/ruby 

# Windows 
where 'ruby' 
#=> C:\Program Files\Ruby192\bin/ruby.exe