Подтвердить что ты не робот

Программно определить, установлен ли определенный камень, затем установить его, если нет

Это не похоже, что это было бы трудно.

Я хочу, чтобы ruby ​​ script выяснял, установлен ли в системе определенный камень (любая версия и/или определенная версия спецификации) (где бы gem list не посмотрел), а если нет,

Да, я знаю, что в некоторых случаях сборщик отлично справляется с этим. Поверьте мне, что у меня есть случай, когда по странным причинам я не хочу использовать bundler. Я действительно хочу программно опросить локальный репозиторий драгоценных камней.

Один из способов программной установки - это просто отключить gem install.

Но мне не удаётся найти надежный способ программного опроса, чтобы узнать, установлен ли конкретный камень, а не с оболочкой, а не с rubygem api, а не с чем-либо.

Мне это не хватает?

4b9b3361

Ответ 1

# The version requirements are optional.
# You can also specify multiple version requirements, just append more at the end
gem_name, *gem_ver_reqs = 'json', '~> 1.8.0'
gdep = Gem::Dependency.new(gem_name, *gem_ver_reqs)
# find latest that satisifies
found_gspec = gdep.matching_specs.max_by(&:version)
# instead of using Gem::Dependency, you can also do:
# Gem::Specification.find_all_by_name(gem_name, *gem_ver_reqs)

if found_gspec
  puts "Requirement '#{gdep}' already satisfied by #{found_gspec.name}-#{found_gspec.version}"
else
  puts "Requirement '#{gdep}' not satisfied; installing..."
  # reqs_string will be in the format: "> 1.0, < 1.2"
  reqs_string = gdep.requirements_list.join(', ')
  # multi-arg is safer, to avoid injection attacks
  system('gem', 'install', gem_name, '-v', reqs_string)
end

В более поздних версиях rubygems предоставляется API-интерфейс установщика, поэтому вместо обхода команды gem вы также можете использовать:

# using the same "gdep" variable as above
Gem.install gem_name, gdep.requirement

Однако я не уверен, поддерживает ли Gem.install ваш файл .gemrc.

Существует множество полезных методов для запроса ваших установленных драгоценных камней (см. rdocs). Некоторые из них могут быть полезны:

  • Gem::Specification.find_all_by_name
  • Gem::Requirement#satisfied_by?(gem_version_instance)
  • Gem::Specification#satisfies_requirement?(gem_dependency_instance)
  • Gem.loaded_specs - хеш драгоценных камней, которые вы действительно загрузили с помощью метода gem, или require

Ответ 2

Последний ответ был хорошим, но это немного более точно:

`gem install redis` unless `gem list`.lines.grep(/^redis \(.*\)/)

Совпадает только с драгоценным камнем с именем redis, а не с другими драгоценными камнями, такими как redis-native_hash или что-то еще.

Другим способом, который я видел, это сделать, чтобы попробовать камень.

begin
  require 'some_crazy_gem'
rescue LoadError
  `gem install some_crazy_gem`
  #...
end

Ответ 3

Убедитесь, что камень новее конкретной версии.

PROMPT> gem list nakamoto -i -v ">=1.2.3"
true

Ответ 4

Я понятия не имею, является ли это лучшей практикой или нет, но:

list = `gem list`
`gem install builder` unless list.include? "builder"

... работал у меня в irb.