Class: Bundler::Dsl

Inherits:
Object
  • Object
show all
Includes:
RubyDsl
Defined in:
lib/bundler/dsl.rb

Direct Known Subclasses

Plugin::DSL

Defined Under Namespace

Classes: DSLError

Constant Summary collapse

VALID_PLATFORMS =
Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
VALID_KEYS =
%w[group groups git path glob name branch ref tag require submodules
platform platforms source install_if force_ruby_platform].freeze
GITHUB_PULL_REQUEST_URL =
%r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
GITLAB_MERGE_REQUEST_URL =
%r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RubyDsl

#normalize_ruby_file, #ruby

Constructor Details

#initializeDsl

Returns a new instance of Dsl.

[View source]

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/bundler/dsl.rb', line 27

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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object

Raises:

[View source]

225
226
227
# File 'lib/bundler/dsl.rb', line 225

def method_missing(name, *args)
  raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
end

Instance Attribute Details

#dependenciesObject

Returns the value of attribute dependencies.


25
26
27
# File 'lib/bundler/dsl.rb', line 25

def dependencies
  @dependencies
end

#gemfileObject (readonly)

Returns the value of attribute gemfile.


24
25
26
# File 'lib/bundler/dsl.rb', line 24

def gemfile
  @gemfile
end

#gemspecsObject (readonly)

Returns the value of attribute gemspecs.


24
25
26
# File 'lib/bundler/dsl.rb', line 24

def gemspecs
  @gemspecs
end

Class Method Details

.evaluate(gemfile, lockfile, unlock) ⇒ Object

[View source]

10
11
12
13
14
# File 'lib/bundler/dsl.rb', line 10

def self.evaluate(gemfile, lockfile, unlock)
  builder = new
  builder.eval_gemfile(gemfile)
  builder.to_definition(lockfile, unlock)
end

Instance Method Details

#check_primary_source_safetyObject

[View source]

229
230
231
232
# File 'lib/bundler/dsl.rb', line 229

def check_primary_source_safety
  check_path_source_safety
  check_rubygems_source_safety
end

#env(name) ⇒ Object

[View source]

213
214
215
216
217
218
219
# File 'lib/bundler/dsl.rb', line 213

def env(name)
  old = @env
  @env = name
  yield
ensure
  @env = old
end

#eval_gemfile(gemfile, contents = nil) ⇒ Object

[View source]

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/bundler/dsl.rb', line 44

def eval_gemfile(gemfile, contents = nil)
  with_gemfile(gemfile) do |current_gemfile|
    contents ||= Bundler.read_file(current_gemfile)
    instance_eval(contents, current_gemfile, 1)
  rescue GemfileEvalError => e
    message = "There was an error evaluating `#{File.basename current_gemfile}`: #{e.message}"
    raise DSLError.new(message, current_gemfile, e.backtrace, contents)
  rescue GemfileError, InvalidArgumentError, InvalidOption, DeprecatedError, ScriptError => e
    message = "There was an error parsing `#{File.basename current_gemfile}`: #{e.message}"
    raise DSLError.new(message, current_gemfile, e.backtrace, contents)
  rescue StandardError => e
    raise unless e.backtrace_locations.first.path == current_gemfile
    message = "There was an error parsing `#{File.basename current_gemfile}`: #{e.message}"
    raise DSLError.new(message, current_gemfile, e.backtrace, contents)
  end
end

#gem(name, *args) ⇒ Object

[View source]

95
96
97
98
99
100
101
102
# File 'lib/bundler/dsl.rb', line 95

def gem(name, *args)
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
  version = args || [">= 0"]

  normalize_options(name, version, options)

  add_dependency(name, version, options)
end

#gemspec(opts = nil) ⇒ Object

[View source]

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/bundler/dsl.rb', line 61

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 = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).filter_map {|g| Bundler.load_gemspec(g) }
  gemspecs.reject! {|s| s.name != name } if name
  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

    path path, "glob" => glob, "name" => spec.name do
      add_dependency spec.name
    end

    spec.development_dependencies.each do |dep|
      add_dependency dep.name, dep.requirement.as_list, "gemspec_dev_dep" => true, "group" => development_group
    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) ⇒ Object

[View source]

154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/bundler/dsl.rb', line 154

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) ⇒ Object

[View source]

128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/bundler/dsl.rb', line 128

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 = {}) ⇒ Object

[View source]

169
170
171
172
173
174
175
# File 'lib/bundler/dsl.rb', line 169

def github(repo, options = {})
  raise InvalidArgumentError, "GitHub sources require a block" unless block_given?
  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) ⇒ Object

[View source]

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/bundler/dsl.rb', line 182

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) ⇒ Object

[View source]

198
199
200
201
202
203
# File 'lib/bundler/dsl.rb', line 198

def install_if(*args)
  @install_conditionals.concat args
  yield
ensure
  args.each { @install_conditionals.pop }
end

#path(path, options = {}, &blk) ⇒ Object

[View source]

141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/bundler/dsl.rb', line 141

def path(path, options = {}, &blk)
  source_options = normalize_hash(options).merge(
    "path" => Pathname.new(path),
    "root_path" => gemfile_root,
    "gemspec" => gemspecs.find {|g| g.name == options["name"] }
  )

  source_options["global"] = true unless block_given?

  source = @sources.add_path_source(source_options)
  with_source(source, &blk)
end

#platforms(*platforms) ⇒ Object Also known as: platform

[View source]

205
206
207
208
209
210
# File 'lib/bundler/dsl.rb', line 205

def platforms(*platforms)
  @platforms.concat platforms
  yield
ensure
  platforms.each { @platforms.pop }
end

#plugin(*args) ⇒ Object

[View source]

221
222
223
# File 'lib/bundler/dsl.rb', line 221

def plugin(*args)
  # Pass on
end

#source(source, *args, &blk) ⇒ Object

[View source]

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/bundler/dsl.rb', line 104

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
    @sources.add_global_rubygems_remote(source)
  end
end

#to_definition(lockfile, unlock) ⇒ Object

[View source]

177
178
179
180
# File 'lib/bundler/dsl.rb', line 177

def to_definition(lockfile, unlock)
  check_primary_source_safety
  Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
end