Зависимость Ruby Gemspec: возможна ли зависимость от ветки git?

Возможна ли зависимость от ветки git внутри mygem.gemspec?

Я думаю что-то похожее на следующее:

gem.add_runtime_dependency 'oauth2', :git => '[email protected]:lgs/oauth2.git'

... но это не работает.


person Luca G. Soave    schedule 27.06.2011    source источник
comment
У меня такая же проблема, за исключением того, что мне нужна зависимость от пути, а не зависимость от git. Нет ли способа обойти это как-то? Может быть, вставить какой-нибудь хакерский код Ruby куда-нибудь в gemspec?   -  person Ajedi32    schedule 06.01.2014


Ответы (5)


Это невозможно, и, вероятно, никогда не будет, потому что для RubyGems было бы довольно тяжело разрешить разработчикам гема требовать, чтобы у пользователей была установлена ​​определенная система контроля версий для доступа к гему. Gems должны быть автономными с минимальным количеством зависимостей, чтобы люди могли использовать их в как можно более широком спектре приложений.

Если вы хотите сделать это для своих собственных внутренних проектов, я бы посоветовал использовать Bundler, который достаточно хорошо это поддерживает.

person gtd    schedule 27.06.2011
comment
... да, но как я могу это сделать? - person Luca G. Soave; 28.06.2011
comment
Я связываю гем (omniauth), который на самом деле повторно связывает многие другие, такие как фарадей и oauth2, которые оба указывают на старый фарадей (0.6.1). Я пытался отделить эту вложенную зависимость... - person Luca G. Soave; 28.06.2011
comment
Вы делаете это так же, как вы предложили, но в Gemfile. Если явного требования к oauth2 нет, добавьте его (gem 'oauth2', :git =› '....') и установите пакет. - person gtd; 28.06.2011
comment
Кроме того, вам нужно использовать правильный URL-адрес, а не синтаксис ssh. например. git://github.com/rails/exception_notification - person gtd; 28.06.2011
comment
Отлично работает! Я потерялся, спасибо за разъяснение, я очень ценю. - person Luca G. Soave; 28.06.2011
comment
Но что, если ваш гем будет позже включен в другой гем (например, foobar_gem)? Когда foobar_gem хочет разрешить зависимости в вашем геме, не будет ли он искать исключительно в файле gemspec? - person eremzeit; 04.05.2012
comment
Вы когда-нибудь нашли решение этой проблемы, у меня точно такая же проблема? - person msaspence; 27.02.2013
comment
@eremzeit Поскольку Bundler просматривает ваши файлы Gemfile и файлы зависимостей .gemspec, добавление локальной или git-ссылки на Gem в вашем Gemfile сообщит сборщику, где его найти, даже если на него ссылается другой gem. Вам просто нужно убедиться, что у вас есть совместимые спецификации версии. - person jwadsack; 22.11.2014
comment
@eremzeit и msaspence - поскольку у вас так много голосов, я чувствую себя обязанным ответить. Для этого нет решения, потому что вы делаете это неправильно. Это нормально — зависеть от репозитория git для одного приложения, использующего Bundler, совершенно неправильно, чтобы выпущенный гем зависел от GitHub или любого другого репозитория исходного кода. Если вы выпускаете гем, все его зависимости также должны быть выпущены как гем. Заставить формальный пакет, такой как gem, полагаться на неопубликованный исходный код, значит ставить телегу впереди лошади. Пожалуйста, не пытайтесь это сделать. - person gtd; 26.12.2014
comment
@gtd Создание драгоценного камня и выпуск драгоценного камня на rubygems - это две разные вещи. Вполне возможно, что частный неопубликованный гем имеет собственные частные зависимости. Мне кажется, это нормально. RubyGems, похоже, не подходит для этого варианта использования, но я не уверен, что это неправильно. Там просто не так много, чтобы поддержать это. Я ошибся? - person Stephen Crosby; 04.05.2016
comment
@StephenCrosby, когда я сказал RubyGems, я имел в виду менеджер пакетов, а не rubygems.org, частные драгоценные камни все еще публикуются (на частном сервере). Опять же, я не знаю, как сделать это более понятным: если вы хотите получить произвольные ветки из-под контроля версий, используйте Bundler, он поддерживает этот рабочий процесс. Делая это в RubyGems, вы полностью отказываетесь от формального объявления номеров выпусков и зависимостей, поскольку нет постоянства исходной ветки репозитория. Кроме того, я не уверен, что люди надеются получить от этого, но я уверяю вас, что это не будет поддерживаться. - person gtd; 07.05.2016
comment
@StephenCrosby Я был именно в такой ситуации с моими личными драгоценными камнями, размещенными на Github. Я разрабатывал драгоценный камень B, который зависел от частного драгоценного камня A. Я смог добиться всего, добавив gem 'A', git: '[email protected]:myorganization/A.git' в Gemfile драгоценного камня B, не его .gemspec - person Matt; 01.02.2017
comment
@Matt Я тоже так делаю. Bundler поддерживает «сгенерированные» драгоценные камни, а спецификации драгоценных камней Rubygems — нет. Bundler не смотрит на Gemfiles внутри зависимостей gem. Он использует gemspec, который не поддерживает драгоценные камни. Это означает, что если вы заботитесь об управлении версиями ваших gitted-гемов, вы должны назвать все зависимости вашего gitted-приложения на самом высоком уровне (в Gemfile вашего приложения). Вы не получаете помощи от Bundler или Rubygems в управлении транзитивными, «сгенерированными» зависимостями драгоценных камней изнутри зависимых драгоценных камней. - person Stephen Crosby; 02.02.2017
comment
Ребят, у меня почему-то не работает добавление гема в Gemfile B. Драгоценный камень A даже не отображается в bundle install. Что мне не хватает? - person Nakilon; 26.10.2017
comment
Он просто игнорирует Gemfile — я вижу это, добавляя fail вверху, и ничего не происходит. - person Nakilon; 26.10.2017

ИЗМЕНИТЬ

По словам комментатора, это уже не так. Предыдущая информация сохранена для исторического контекста.

Дублирование ссылки на драгоценный камень в Gemfile и .gemspec теперь вызывает предупреждающее сообщение в Bundler, поэтому этот ответ больше не соответствует действительности.

Устаревшая информация

Эта статья Иехуды Кац прояснил для меня подобную путаницу. В нем говорится, что для использования только в разработке лучше всего добавить материал git в gemfile, но этот упаковщик по-прежнему будет использовать информацию о зависимости/версии из gemspec (мне это кажется волшебным, но я доверяю Yehuda).

person heartpunk    schedule 28.07.2013
comment
Что в этом такого волшебного? Bundler читает только из Gemfile, за исключением того, что если вы поместите туда gemspec, он также будет читать из gemspec. Итак, когда вы запускаете bundle install, я предполагаю (но не проверял), что происходит то, что Bundler устанавливает гем, указанный в Gemfile. Поскольку Bundler уже установил его, этот драгоценный камень доступен для драгоценного камня require, независимо от того факта, что он не был получен из репозитория драгоценных камней. Никакой магии, просто Бандлер работает как обычно. - person Marnen Laibow-Koser; 26.01.2014
comment
Дублирование ссылки на драгоценный камень в Gemfile и .gemspec теперь вызывает предупреждающее сообщение в Bundler, поэтому этот ответ больше не соответствует действительности... - person Andy Jones; 02.12.2015

Я как раз тоже пытался разобраться с этой проблемой. И я только что придумал следующее решение (которое я не уверен, публикуете ли вы свой драгоценный камень или имеете права на распространение этого драгоценного камня oauth2).

В вашем геме, для которого требуется гем oauth2, запустите это.

git submodule add [email protected]:lgs/oauth2.git lib/oauth2

Если вам требуется другая ветвь, чем по умолчанию

cd lib/oauth2 && git checkout <branchname_or_ref>
cd .. && git add lib/oauth2
git commit -m "adding outh2 submodule"

В вашей спецификации gemspec добавьте это выше требуемой строки версии.

$:.push File.expand_path('../lib/oauth2/lib', __FILE__)

Также вам нужно будет добавить все зависимости времени выполнения драгоценного камня oauth2 в ваш gemspec. Я еще не нашел способ обойти это.

Это то, что я сделал, и это работает для нас, потому что наш драгоценный камень требуется через git, поэтому я не уверен, будет ли это работать для опубликованного драгоценного камня rubygems.

person kwbock    schedule 14.04.2015
comment
Добавление зависимости в качестве подмодуля является правильным решением, если вы создали оба гема и оба находятся в активной разработке. - person Benjineer; 30.07.2016
comment
Важно отметить, что если вы сделаете это, вам может понадобиться использовать: gem 'my_gem', git: '[email protected]:me/myrepo', submodules: true в вашем хост-приложении, если вы устанавливаете из github. - person Joe Edgar; 08.07.2020

Я нашел обходной путь довольно прямолинейным:

Допустим, вы участвуете в проекте P и хотите использовать самодельный драгоценный камень tools, который сам использует драгоценный камень ОС oauth2.

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

Однако вы можете указать нужную версию в Gemfile вашего проекта P, и это будет версия, используемая tools во время выполнения:

gem 'oauth2', github: 'lgs/oauth2'

Вот мой пример из жизни.

person Ulysse BN    schedule 19.09.2019

Я столкнулся с подобной проблемой, и вот что я нашел. Вы не можете добавить ветку git напрямую для какого-либо другого драгоценного камня, однако вы можете добиться этого другим способом. Вы можете определить частный гем со ссылкой на репозиторий и именем ветки в гемфайле вашего пользовательского гем, т.е.

gem 'gem_name', '>=0.1.1', git: 'repository_link ', branch: 'brnach_name'

и запустить bundle install

Теперь вы можете указать его в файле gemspec, не нужно добавлять версию, так как он уже будет выбран из Gemfile.lock.

spec.add_runtime_dependency 'sms_service'

Примечание. Убедитесь, что gemspec находится внизу Gemfile. Таким образом, он сначала установит необходимые драгоценные камни, а затем добавит их в качестве зависимости к вашему драгоценному камню.

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'sms_service', '>=0.1.1', git: 'repository link', branch: 'branch_name'

gemspec
person Mr.Muhammad Ramzan    schedule 16.06.2021