Uploaded image for project: 'Dev - Nexus Repo'
  1. Dev - Nexus Repo
  2. NEXUS-17477

Unable to install hosted gem which has multiple version requirements


    • Bug
    • Resolution: Fixed
    • Major
    • 3.21.0
    • 3.6.2, 3.12.1, 3.16.1
    • RubyGems
    • 3


      Bug description

      If a ruby gem is hosted on Sonatype Nexus 3 Rubygems repository

      and that ruby gem contains multiple version requirements for a dependency in its gemspec

      and the project which uses the ruby gem does not have a Gemfile.lock

      Then bundler will fail to install the project gems with the following message:

      jp440p:testproject $ bundle install --path .bundle
      Fetching gem metadata from http://localhost:8081/repository/gems-test/...
      Fetching gem metadata from https://rubygems.org/..............
      Fetching gem metadata from http://localhost:8081/repository/gems-test/..
      Resolving dependencies...
      Fetching concurrent-ruby 1.0.5
      Fetching minitest 5.11.3
      Fetching thread_safe 0.3.6
      Installing minitest 5.11.3
      Installing concurrent-ruby 1.0.5
      Installing thread_safe 0.3.6
      Using bundler 1.16.2
      Fetching tzinfo 1.2.5
      Fetching i18n 1.0.1
      Installing tzinfo 1.2.5
      Installing i18n 1.0.1
      Fetching activesupport 5.2.0
      Installing activesupport 5.2.0
      Fetching test-gem-requirement-bug 0.1.0
      Downloading test-gem-requirement-bug-0.1.0 revealed dependencies not in the API or the lockfile (activesupport (< 5.2, >= 5.0)).
      Either installing with `--full-index` or running `bundle update test-gem-requirement-bug` should fix the problem.
      In Gemfile:


      We noticed this bug on our production ruby gem repositories (hosted on Sonatype Nexus3 v3.6.2) then I reproduced with the latest version of SNRM : v3.12.1


      This issue has been reported on bundler github (see https://github.com/bundler/bundler/issues/6048 ). The original bug report mentions Sonatype Nexus but was closed without having been properly investigated.


      Reproducing the bug


      Nexus Setup


      I installed an instance of Sonatype Nexus3 using docker like this:

      docker run --name nexus3 -d -v /data/nexus-data:/nexus-data -p 8081:8081 -e INSTALL4J_ADD_VM_PARAMS="-Xms1536M -Xmx1536M -XX:MaxDirectMemorySize=2g" sonatype/nexus3:3.12.1

      Once the instance has booted, I open http://localhost:8081 with browser, log to nexus using default credentials (admin/admin123), then I create a hosted rubygems repository which I name "gems-test".

      The URL of the gems-test repository on the local nexus is http://localhost:8081/repository/gems-test/


      Test ruby gem


      I generated a sample ruby gem using the `bundle gem test-gem-requirement-bug` command on my workstation.


      I edited the generate gem to supply the following gemspec:

      lib = File.expand_path("../lib", __FILE__)
      $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
      require "test/gem/requirement/bug/version"
      Gem::Specification.new do |spec|
        spec.name          = "test-gem-requirement-bug"
        spec.version       = Test::Gem::Requirement::Bug::VERSION
        spec.authors       = ["Julien Pervillé"]
        spec.email         = ["julien.perville@perfect-memory.com"]
        spec.summary       = %q{Attempts to reproduce a bug with gem requirement parsing}
        spec.homepage      = 'https://rubygems.org'
        # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
        # to allow pushing to a single host or delete this section to allow pushing to any host.
        if spec.respond_to?(:metadata)
          spec.metadata["allowed_push_host"] = "https://rubygems.org"
          raise "RubyGems 2.0 or newer is required to protect against " \
            "public gem pushes."
        # Specify which files should be added to the gem when it is released.
        # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
        spec.files         = Dir.chdir(File.expand_path('..', __FILE__)) do
          `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
        spec.bindir        = "exe"
        spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
        spec.require_paths = ["lib"]
        spec.add_runtime_dependency "activesupport", ">= 5.0", "< 5.2"


      Note the multiple version requirement on the activesupport dependency above.


      Then I `gem build *gemspec` to produce the gem.


      Then I upload the produced gem to Nexus using the upload interface at http://localhost:8081/#browse/upload:gems-test


      If everything was successful the ruby gem should be listed in the "browse" view of the gems-test repository (URL http://localhost:8081/#browse/browse:gems-test )

      Test ruby project


      I create a sample ruby project on my workstation, which uses the "test-gem-requirement-bug" gem.


      mkdir testproject
      cd testproject
      cat <<EOF > Gemfile
      source 'https://rubygems.org'
      source 'http://localhost:8081/repository/gems-test/' do
        gem 'test-gem-requirement-bug', '~> 0.1.0'


      Then, still in the testproject directory, I run:

      bundle install --path .bundle


      To install the project dependencies.


      The "bundle install" command fails with the trace at the top of project.




      Note that running "bundle install --path .bundle --full-index" succeeds to install the gem and its dependencies (even if it is inefficient).







            mmartz Michael Martz
            jperville Julien Pervillé
            Michael Prescott Michael Prescott
            NXRM - Neo
            8 Vote for this issue
            14 Start watching this issue