In Files

  • bundler/dsl.rb
  • bundler/friendly_errors.rb

Class/Module Index [+]

Quicksearch

Bundler::Dsl

Attributes

dependencies[RW]
gemspecs[R]

Public Class Methods

evaluate(gemfile, lockfile, unlock) click to toggle source
 
               # File bundler/dsl.rb, line 10
def self.evaluate(gemfile, lockfile, unlock)
  builder = new
  builder.eval_gemfile(gemfile)
  builder.to_definition(lockfile, unlock)
end
            
new() click to toggle source
 
               # File bundler/dsl.rb, line 24
def initialize
  @source               = nil
  @sources              = SourceList.new
  @git_sources          = {}
  @dependencies         = []
  @groups               = []
  @install_conditionals = []
  @optional_groups      = []
  @platforms            = []
  @env                  = nil
  @ruby_version         = nil
  @gemspecs             = []
  @gemfile              = nil
  @gemfiles             = []
  add_git_sources
end
            

Public Instance Methods

env(name) click to toggle source
 
               # File bundler/dsl.rb, line 268
def env(name)
  old = @env
  @env = name
  yield
ensure
  @env = old
end
            
eval_gemfile(gemfile, contents = nil) click to toggle source
 
               # File bundler/dsl.rb, line 41
def eval_gemfile(gemfile, contents = nil)
  expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile && @gemfile.parent)
  original_gemfile = @gemfile
  @gemfile = expanded_gemfile_path
  @gemfiles << expanded_gemfile_path
  contents ||= Bundler.read_file(@gemfile.to_s)
  instance_eval(contents.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
rescue Exception => e # rubocop:disable Lint/RescueException
  message = "There was an error "          "#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} "          "`#{File.basename gemfile.to_s}`: #{e.message}"

  raise DSLError.new(message, gemfile, e.backtrace, contents)
ensure
  @gemfile = original_gemfile
end
            
gem(name, *args) click to toggle source
 
               # File bundler/dsl.rb, line 94
def gem(name, *args)
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
  options["gemfile"] = @gemfile
  version = args || [">= 0"]

  normalize_options(name, version, options)

  dep = Dependency.new(name, version, options)

  # if there's already a dependency with this name we try to prefer one
  if current = @dependencies.find {|d| d.name == dep.name }
    deleted_dep = @dependencies.delete(current) if current.type == :development

    if current.requirement != dep.requirement
      unless deleted_dep
        return if dep.type == :development

        update_prompt = ""

        if File.basename(@gemfile) == Injector::INJECTED_GEMS
          if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
            update_prompt = ". Gem already added"
          else
            update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"

            update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
          end
        end

        raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n"                              "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})"                               "#{update_prompt}"
      end

    else
      Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n"                            "You should probably keep only one of them.\n"                            "Remove any duplicate entries and specify the gem only once.\n"                            "While it's not a problem now, it could cause errors if you change the version of one of them later."
    end

    if current.source != dep.source
      unless deleted_dep
        return if dep.type == :development
        raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n"                              "You specified that #{dep.name} (#{dep.requirement}) should come from "                              "#{current.source || "an unspecified source"} and #{dep.source}\n"
      end
    end
  end

  @dependencies << dep
end
            
gemspec(opts = nil) click to toggle source
 
               # File bundler/dsl.rb, line 58
def gemspec(opts = nil)
  opts ||= {}
  path              = opts[:path] || "."
  glob              = opts[:glob]
  name              = opts[:name]
  development_group = opts[:development_group] || :development
  expanded_path     = gemfile_root.join(path)

  gemspecs = Dir[File.join(expanded_path, "{,*}.gemspec")].map {|g| Bundler.load_gemspec(g) }.compact
  gemspecs.reject! {|s| s.name != name } if name
  Index.sort_specs(gemspecs)
  specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }

  case specs_by_name_and_version.size
  when 1
    specs = specs_by_name_and_version.values.first
    spec = specs.find {|s| s.match_platform(Bundler.local_platform) } || specs.first

    @gemspecs << spec

    gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
    gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms

    group(development_group) do
      spec.development_dependencies.each do |dep|
        gem dep.name, *(dep.requirement.as_list + [:type => :development])
      end
    end
  when 0
    raise InvalidOption, "There are no gemspecs at #{expanded_path}"
  else
    raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. "            "Please use the :name option to specify which one should be used"
  end
end
            
git(uri, options = {}, &blk) click to toggle source
 
               # File bundler/dsl.rb, line 209
def git(uri, options = {}, &blk)
  unless block_given?
    msg = "You can no longer specify a git source by itself. Instead, \n"                "either use the :git option on a gem, or specify the gems that \n"                "bundler should find in the git source by passing a block to \n"                "the git method, like: \n\n"                "  git 'git://github.com/rails/rails.git' do\n"                "    gem 'rails'\n"                "  end"
    raise DeprecatedError, msg
  end

  with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
end
            
git_source(name, &block) click to toggle source
 
               # File bundler/dsl.rb, line 173
def git_source(name, &block)
  unless block_given?
    raise InvalidOption, "You need to pass a block to #git_source"
  end

  if valid_keys.include?(name.to_s)
    raise InvalidOption, "You cannot use #{name} as a git source. It "            "is a reserved key. Reserved keys are: #{valid_keys.join(", ")}"
  end

  @git_sources[name.to_s] = block
end
            
github(repo, options = {}) click to toggle source
 
               # File bundler/dsl.rb, line 224
def github(repo, options = {})
  raise ArgumentError, "GitHub sources require a block" unless block_given?
  raise DeprecatedError, "The #github method has been removed" if Bundler.feature_flag.skip_default_git_sources?
  github_uri  = @git_sources["github"].call(repo)
  git_options = normalize_hash(options).merge("uri" => github_uri)
  git_source  = @sources.add_git_source(git_options)
  with_source(git_source) { yield }
end
            
group(*args, &blk) click to toggle source
 
               # File bundler/dsl.rb, line 237
def group(*args, &blk)
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
  normalize_group_options(options, args)

  @groups.concat args

  if options["optional"]
    optional_groups = args - @optional_groups
    @optional_groups.concat optional_groups
  end

  yield
ensure
  args.each { @groups.pop }
end
            
install_if(*args) click to toggle source
 
               # File bundler/dsl.rb, line 253
def install_if(*args)
  @install_conditionals.concat args
  yield
ensure
  args.each { @install_conditionals.pop }
end
            
method_missing(name, *args) click to toggle source
 
               # File bundler/dsl.rb, line 280
def method_missing(name, *args)
  raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
end
            
path(path, options = {}, &blk) click to toggle source
 
               # File bundler/dsl.rb, line 186
def path(path, options = {}, &blk)
  unless block_given?
    msg = "You can no longer specify a path source by itself. Instead, \n"                "either use the :path option on a gem, or specify the gems that \n"                "bundler should find in the path source by passing a block to \n"                "the path method, like: \n\n"                "    path 'dir/containing/rails' do\n"                "      gem 'rails'\n"                "    end\n\n"

    raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
    SharedHelpers.major_deprecation(2, msg.strip)
  end

  source_options = normalize_hash(options).merge(
    "path" => Pathname.new(path),
    "root_path" => gemfile_root,
    "gemspec" => gemspecs.find {|g| g.name == options["name"] }
  )
  source = @sources.add_path_source(source_options)
  with_source(source, &blk)
end
            
platform(*platforms) click to toggle source
Alias for: platforms
platforms(*platforms) click to toggle source
 
               # File bundler/dsl.rb, line 260
def platforms(*platforms)
  @platforms.concat platforms
  yield
ensure
  platforms.each { @platforms.pop }
end
            
Also aliased as: platform
plugin(*args) click to toggle source
 
               # File bundler/dsl.rb, line 276
def plugin(*args)
  # Pass on
end
            
source(source, *args, &blk) click to toggle source
 
               # File bundler/dsl.rb, line 148
def source(source, *args, &blk)
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
  options = normalize_hash(options)
  source = normalize_source(source)

  if options.key?("type")
    options["type"] = options["type"].to_s
    unless Plugin.source?(options["type"])
      raise InvalidOption, "No plugin sources available for #{options["type"]}"
    end

    unless block_given?
      raise InvalidOption, "You need to pass a block to #source with :type option"
    end

    source_opts = options.merge("uri" => source)
    with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
  elsif block_given?
    with_source(@sources.add_rubygems_source("remotes" => source), &blk)
  else
    check_primary_source_safety(@sources)
    @sources.global_rubygems_source = source
  end
end
            
to_definition(lockfile, unlock) click to toggle source
 
               # File bundler/dsl.rb, line 233
def to_definition(lockfile, unlock)
  Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
end