# class Gem::RequestSet::GemDependencyAPI

A semi-compatible DSL for the `Bundler` Gemfile and Isolate gem dependencies files.

To work with both the `Bundler` Gemfile and Isolate formats this implementation takes some liberties to allow compatibility with each, most notably in `source`.

A basic gem dependencies file will look like the following:

    source 'https://rubygems.org'

    gem 'rails', '3.2.14a
    gem 'devise', '~> 2.1', '>= 2.1.3'
    gem 'cancan'
    gem 'airbrake'
    gem 'pg'

RubyGems recommends saving this as gem.deps.rb over Gemfile or Isolate.

To install the gems in this Gemfile use `gem install -g` to install it and create a lockfile. The lockfile will ensure that when you make changes to your gem dependencies file a minimum amount of change is made to the dependencies of your gems.

RubyGems can activate all the gems in your dependencies file at startup using the RUBYGEMS_GEMDEPS environment variable or through `Gem.use_gemdeps`. See `Gem.use_gemdeps` for details and warnings.

See `gem help install` and `gem help gem_dependencies` for further details.

### Attributes

dependencies[R]

The gems required by `gem` statements in the gem.deps.rb file

requires[R]

A `Hash` containing gem names and files to require from those gems.

### Public Class Methods

new(set, path) click to toggle source

Creates a new `GemDependencyAPI` that will add dependencies to the `Gem::RequestSet` `set` based on the dependency API description in `path`.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 196
    def initialize(set, path)
      @set = set
      @path = path

      @current_groups     = nil
      @current_platforms  = nil
      @current_repository = nil
      @dependencies       = {}
      @default_sources    = true
      @git_set            = @set.git_set
      @git_sources        = {}
      @installing         = false
      @requires           = Hash.new {|h, name| h[name] = [] }
      @vendor_set         = @set.vendor_set
      @source_set         = @set.source_set
      @gem_sources        = {}
      @without_groups     = []

      git_source :github do |repo_name|
        repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"

        "git://github.com/#{repo_name}.git"
      end

      git_source :bitbucket do |repo_name|
        repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"

        user, = repo_name.split "/", 2

        "https://#{user}@bitbucket.org/#{repo_name}.git"
      end
    end

### Public Instance Methods

git_source(name, &callback) click to toggle source

Defines a custom git source that uses `name` to expand git repositories for use in gems built from git repositories. You must provide a block that accepts a git repository name for expansion.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 606
    def git_source(name, &callback)
      @git_sources[name] = callback
    end

load() click to toggle source

Loads the gem dependency file and returns self.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 281
    def load
      instance_eval File.read(@path).tap(&Gem::UNTAINT), @path, 1

      self
    end

### Private Instance Methods

pin_gem_source(name, type = :default, source = nil) click to toggle source

Pins the gem `name` to the given `source`. Adding a gem with the same name from a different `source` will raise an exception.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 697
    def pin_gem_source(name, type = :default, source = nil)
      source_description =
        case type
        when :default then '(default)'
        when :path    then "path: #{source}"
        when :git     then "git: #{source}"
        when :source  then "source: #{source}"
        else               '(unknown)'
        end

      raise ArgumentError,
        "duplicate source #{source_description} for gem #{name}" if
          @gem_sources.fetch(name, source) != source

      @gem_sources[name] = source
    end

## Gem Dependencies DSL

↑ top

### Public Instance Methods

gem(name) click to toggle source
gem(name, *requirements)
gem(name, *requirements, options)

Specifies a gem dependency with the given `name` and `requirements`. You may also supply `options` following the `requirements`

`options` include:

require:

  RubyGems does not provide any autorequire features so requires in a gem dependencies file are recorded but ignored.

  In bundler the require: option overrides the file to require during `Bundler.require`. By default the name of the dependency is required in `Bundler`. A single file or an `Array` of files may be given.

  To disable requiring any file give `false`:

      gem 'rake', require: false

group:

  Place the dependencies in the given dependency group. A single group or an `Array` of groups may be given.

  See also `group`

platform:

  Only install the dependency on the given platform. A single platform or an `Array` of platforms may be given.

  See `platform` for a list of platforms available.

path:

  Install this dependency from an unpacked gem in the given directory.

      gem 'modified_gem', path: 'vendor/modified_gem'

git:

  Install this dependency from a git repository:

      gem 'private_gem', git: git@my.company.example:private_gem.git'

gist:

  Install this dependency from the gist ID:

      gem 'bang', gist: '1232884'

github:

  Install this dependency from a github git repository:

      gem 'private_gem', github: 'my_company/private_gem'

submodules:

  `Set` to `true` to include submodules when fetching the git repository for git:, gist: and github: dependencies.

ref:

  Use the given commit name or SHA for git:, gist: and github: dependencies.

branch:

  Use the given branch for git:, gist: and github: dependencies.

tag:

  Use the given tag for git:, gist: and github: dependencies.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 358
      def gem(name, *requirements)
        options = requirements.pop if requirements.last.kind_of?(Hash)
        options ||= {}

        options[:git] = @current_repository if @current_repository

        source_set = false

        source_set ||= gem_path       name, options
        source_set ||= gem_git        name, options
        source_set ||= gem_git_source name, options
        source_set ||= gem_source     name, options

        duplicate = @dependencies.include? name

        @dependencies[name] =
          if requirements.empty? and not source_set
            Gem::Requirement.default
          elsif source_set
            Gem::Requirement.source_set
          else
            Gem::Requirement.create requirements
          end

        return unless gem_platforms name, options

        groups = gem_group name, options

        return unless (groups & @without_groups).empty?

        pin_gem_source name, :default unless source_set

        gem_requires name, options

        if duplicate
          warn <<-WARNING
    Gem dependencies file #{@path} requires #{name} more than once.
          WARNING
        end

        @set.gem name, *requirements
      end

gemspec(options = {}) click to toggle source

Loads dependencies from a gemspec file.

`options` include:

name:

  The name portion of the gemspec file. Defaults to searching for any gemspec file in the current directory.

      gemspec name: 'my_gem'

path:

  The path the gemspec lives in. Defaults to the current directory:

      gemspec 'my_gem', path: 'gemspecs', name: 'my_gem'

development_group:

  The group to add development dependencies to. By default this is :development. Only one group may be specified.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 639
    def gemspec(options = {})
      name              = options.delete(:name) || '{,*}'
      path              = options.delete(:path) || '.'
      development_group = options.delete(:development_group) || :development

      spec = find_gemspec name, path

      groups = gem_group spec.name, {}

      self_dep = Gem::Dependency.new spec.name, spec.version

      add_dependencies groups, [self_dep]
      add_dependencies groups, spec.runtime_dependencies

      @dependencies[spec.name] = Gem::Requirement.source_set

      spec.dependencies.each do |dep|
        @dependencies[dep.name] = dep.requirement
      end

      groups << development_group

      add_dependencies groups, spec.development_dependencies

      @vendor_set.add_vendor_gem spec.name, path
      gem_requires spec.name, options
    end

git(repository) { || ... } click to toggle source

Block form for specifying gems from a git `repository`.

    git 'https://github.com/rails/rails.git' do
      gem 'activesupport'
      gem 'activerecord'
    end

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 592
    def git(repository)
      @current_repository = repository

      yield

    ensure
      @current_repository = nil
    end

group(*groups) { || ... } click to toggle source

Block form for placing a dependency in the given `groups`.

    group :development do
      gem 'debugger'
    end

    group :development, :test do
      gem 'minitest'
    end

Groups can be excluded at install time using `gem install -g –without development`. See `gem help install` and `gem help gem_dependencies` for further details.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 684
    def group(*groups)
      @current_groups = groups

      yield

    ensure
      @current_groups = nil
    end

platform(*platforms) { || ... } click to toggle source

Block form for restricting gems to a set of platforms.

The gem dependencies platform is different from `Gem::Platform`. A platform gem.deps.rb platform matches on the ruby engine, the ruby version and whether or not windows is allowed.

:ruby, :ruby_XY

  Matches non-windows, non-jruby implementations where X and Y can be used to match releases in the 1.8, 1.9, 2.0 or 2.1 series.

:mri, :mri_XY

  Matches non-windows C Ruby (Matz Ruby) or only the 1.8, 1.9, 2.0 or 2.1 series.

:mingw, :mingw_XY

  Matches 32 bit C Ruby on MinGW or only the 1.8, 1.9, 2.0 or 2.1 series.

:x64_mingw, :x64_mingw_XY

  Matches 64 bit C Ruby on MinGW or only the 1.8, 1.9, 2.0 or 2.1 series.

:mswin, :mswin_XY

  Matches 32 bit C Ruby on Microsoft Windows or only the 1.8, 1.9, 2.0 or 2.1 series.

:mswin64, :mswin64_XY

  Matches 64 bit C Ruby on Microsoft Windows or only the 1.8, 1.9, 2.0 or 2.1 series.

:jruby, :jruby_XY

  Matches JRuby or JRuby in 1.8 or 1.9 mode.

:maglev

  Matches Maglev

:rbx

  Matches non-windows Rubinius

NOTE: There is inconsistency in what environment a platform matches. You may need to read the source to know the exact details.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 759
    def platform(*platforms)
      @current_platforms = platforms

      yield

    ensure
      @current_platforms = nil
    end

Also aliased as: platforms
platforms(*platforms)

Block form for restricting gems to a particular set of platforms. See `platform`.

Alias for: platform
ruby(version, options = {}) click to toggle source

Restricts this gem dependencies file to the given ruby `version`.

You may also provide `engine:` and `engine_version:` options to restrict this gem dependencies file to a particular ruby engine and its engine version. This matching is performed by using the RUBY_ENGINE and RUBY_ENGINE_VERSION constants.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 786
    def ruby(version, options = {})
      engine         = options[:engine]
      engine_version = options[:engine_version]

      raise ArgumentError,
            'You must specify engine_version along with the Ruby engine' if
              engine and not engine_version

      return true if @installing

      unless RUBY_VERSION == version
        message = "Your Ruby version is #{RUBY_VERSION}, " +
                  "but your #{gem_deps_file} requires #{version}"

        raise Gem::RubyVersionMismatch, message
      end

      if engine and engine != Gem.ruby_engine
        message = "Your Ruby engine is #{Gem.ruby_engine}, " +
                  "but your #{gem_deps_file} requires #{engine}"

        raise Gem::RubyVersionMismatch, message
      end

      if engine_version
        if engine_version != RUBY_ENGINE_VERSION
          message =
            "Your Ruby engine version is #{Gem.ruby_engine} #{RUBY_ENGINE_VERSION}, " +
            "but your #{gem_deps_file} requires #{engine} #{engine_version}"

          raise Gem::RubyVersionMismatch, message
        end
      end

      return true
    end

source(url) click to toggle source

Sets `url` as a source for gems for this dependency API. RubyGems uses the default configured sources if no source was given. If a source is set only that source is used.

This method differs in behavior from Bundler:

- The `:gemcutter`, # `:rubygems` and `:rubyforge` sources are not supported as they are deprecated in bundler.

- The `prepend:` option is not supported. If you wish to order sources then list them in your preferred order.

    # File lib/rubygems/request_set/gem_dependency_api.rb, line 837
    def source(url)
      Gem.sources.clear if @default_sources

      @default_sources = false

      Gem.sources << url
    end