shopify-bundler 1.10.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +96 -0
  5. data/.rubocop_todo.yml +177 -0
  6. data/.travis.yml +104 -0
  7. data/CHANGELOG.md +2131 -0
  8. data/CODE_OF_CONDUCT.md +42 -0
  9. data/CONTRIBUTING.md +32 -0
  10. data/DEVELOPMENT.md +118 -0
  11. data/ISSUES.md +96 -0
  12. data/LICENSE.md +23 -0
  13. data/README.md +40 -0
  14. data/Rakefile +309 -0
  15. data/bin/rake +14 -0
  16. data/bin/rspec +10 -0
  17. data/bin/rubocop +11 -0
  18. data/bundler.gemspec +34 -0
  19. data/exe/bundle +21 -0
  20. data/exe/bundle_ruby +60 -0
  21. data/exe/bundler +21 -0
  22. data/lib/bundler.rb +499 -0
  23. data/lib/bundler/capistrano.rb +16 -0
  24. data/lib/bundler/cli.rb +435 -0
  25. data/lib/bundler/cli/binstubs.rb +37 -0
  26. data/lib/bundler/cli/cache.rb +34 -0
  27. data/lib/bundler/cli/check.rb +37 -0
  28. data/lib/bundler/cli/clean.rb +25 -0
  29. data/lib/bundler/cli/common.rb +56 -0
  30. data/lib/bundler/cli/config.rb +88 -0
  31. data/lib/bundler/cli/console.rb +37 -0
  32. data/lib/bundler/cli/exec.rb +51 -0
  33. data/lib/bundler/cli/gem.rb +208 -0
  34. data/lib/bundler/cli/init.rb +32 -0
  35. data/lib/bundler/cli/inject.rb +32 -0
  36. data/lib/bundler/cli/install.rb +188 -0
  37. data/lib/bundler/cli/lock.rb +35 -0
  38. data/lib/bundler/cli/open.rb +22 -0
  39. data/lib/bundler/cli/outdated.rb +86 -0
  40. data/lib/bundler/cli/package.rb +45 -0
  41. data/lib/bundler/cli/platform.rb +42 -0
  42. data/lib/bundler/cli/show.rb +74 -0
  43. data/lib/bundler/cli/update.rb +72 -0
  44. data/lib/bundler/cli/viz.rb +26 -0
  45. data/lib/bundler/constants.rb +5 -0
  46. data/lib/bundler/current_ruby.rb +218 -0
  47. data/lib/bundler/definition.rb +675 -0
  48. data/lib/bundler/dep_proxy.rb +45 -0
  49. data/lib/bundler/dependency.rb +119 -0
  50. data/lib/bundler/deployment.rb +62 -0
  51. data/lib/bundler/deprecate.rb +17 -0
  52. data/lib/bundler/dsl.rb +478 -0
  53. data/lib/bundler/endpoint_specification.rb +100 -0
  54. data/lib/bundler/env.rb +82 -0
  55. data/lib/bundler/environment.rb +41 -0
  56. data/lib/bundler/fetcher.rb +288 -0
  57. data/lib/bundler/fetcher/base.rb +26 -0
  58. data/lib/bundler/fetcher/dependency.rb +88 -0
  59. data/lib/bundler/fetcher/downloader.rb +60 -0
  60. data/lib/bundler/fetcher/index.rb +32 -0
  61. data/lib/bundler/friendly_errors.rb +92 -0
  62. data/lib/bundler/gem_helper.rb +191 -0
  63. data/lib/bundler/gem_helpers.rb +26 -0
  64. data/lib/bundler/gem_installer.rb +9 -0
  65. data/lib/bundler/gem_path_manipulation.rb +8 -0
  66. data/lib/bundler/gem_tasks.rb +5 -0
  67. data/lib/bundler/graph.rb +173 -0
  68. data/lib/bundler/index.rb +199 -0
  69. data/lib/bundler/injector.rb +62 -0
  70. data/lib/bundler/inline.rb +58 -0
  71. data/lib/bundler/installer.rb +242 -0
  72. data/lib/bundler/installer/parallel_installer.rb +122 -0
  73. data/lib/bundler/installer/standalone.rb +48 -0
  74. data/lib/bundler/lazy_specification.rb +82 -0
  75. data/lib/bundler/lockfile_parser.rb +199 -0
  76. data/lib/bundler/match_platform.rb +13 -0
  77. data/lib/bundler/psyched_yaml.rb +26 -0
  78. data/lib/bundler/remote_specification.rb +82 -0
  79. data/lib/bundler/resolver.rb +350 -0
  80. data/lib/bundler/retry.rb +60 -0
  81. data/lib/bundler/ruby_dsl.rb +11 -0
  82. data/lib/bundler/ruby_version.rb +116 -0
  83. data/lib/bundler/rubygems_ext.rb +175 -0
  84. data/lib/bundler/rubygems_integration.rb +674 -0
  85. data/lib/bundler/runtime.rb +285 -0
  86. data/lib/bundler/settings.rb +263 -0
  87. data/lib/bundler/setup.rb +26 -0
  88. data/lib/bundler/shared_helpers.rb +176 -0
  89. data/lib/bundler/similarity_detector.rb +61 -0
  90. data/lib/bundler/source.rb +35 -0
  91. data/lib/bundler/source/git.rb +286 -0
  92. data/lib/bundler/source/git/git_proxy.rb +190 -0
  93. data/lib/bundler/source/path.rb +224 -0
  94. data/lib/bundler/source/path/installer.rb +43 -0
  95. data/lib/bundler/source/rubygems.rb +436 -0
  96. data/lib/bundler/source/rubygems/remote.rb +38 -0
  97. data/lib/bundler/source_list.rb +101 -0
  98. data/lib/bundler/spec_set.rb +156 -0
  99. data/lib/bundler/ssl_certs/.document +1 -0
  100. data/lib/bundler/ssl_certs/AddTrustExternalCARoot-2048.pem +25 -0
  101. data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +32 -0
  102. data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +14 -0
  103. data/lib/bundler/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +23 -0
  104. data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +28 -0
  105. data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +20 -0
  106. data/lib/bundler/ssl_certs/certificate_manager.rb +64 -0
  107. data/lib/bundler/stub_specification.rb +23 -0
  108. data/lib/bundler/templates/Executable +16 -0
  109. data/lib/bundler/templates/Executable.standalone +12 -0
  110. data/lib/bundler/templates/Gemfile +4 -0
  111. data/lib/bundler/templates/newgem/.travis.yml.tt +4 -0
  112. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +22 -0
  113. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  114. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  115. data/lib/bundler/templates/newgem/README.md.tt +41 -0
  116. data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
  117. data/lib/bundler/templates/newgem/bin/console.tt +14 -0
  118. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  119. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  120. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
  121. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  122. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  123. data/lib/bundler/templates/newgem/gitignore.tt +16 -0
  124. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +12 -0
  125. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  126. data/lib/bundler/templates/newgem/newgem.gemspec.tt +43 -0
  127. data/lib/bundler/templates/newgem/rspec.tt +2 -0
  128. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +11 -0
  129. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -0
  130. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
  131. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +4 -0
  132. data/lib/bundler/ui.rb +7 -0
  133. data/lib/bundler/ui/rg_proxy.rb +17 -0
  134. data/lib/bundler/ui/shell.rb +108 -0
  135. data/lib/bundler/ui/silent.rb +44 -0
  136. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +5 -0
  137. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +277 -0
  138. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +69 -0
  139. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +3 -0
  140. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +99 -0
  141. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +63 -0
  142. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +434 -0
  143. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +43 -0
  144. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +51 -0
  145. data/lib/bundler/vendor/net/http/faster.rb +26 -0
  146. data/lib/bundler/vendor/net/http/persistent.rb +1230 -0
  147. data/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb +128 -0
  148. data/lib/bundler/vendor/thor/lib/thor.rb +484 -0
  149. data/lib/bundler/vendor/thor/lib/thor/actions.rb +319 -0
  150. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  151. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +59 -0
  152. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
  153. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +135 -0
  154. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +316 -0
  155. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +107 -0
  156. data/lib/bundler/vendor/thor/lib/thor/base.rb +656 -0
  157. data/lib/bundler/vendor/thor/lib/thor/command.rb +133 -0
  158. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +77 -0
  159. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +10 -0
  160. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +98 -0
  161. data/lib/bundler/vendor/thor/lib/thor/error.rb +32 -0
  162. data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
  163. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +178 -0
  164. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  165. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +35 -0
  166. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  167. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  168. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +73 -0
  169. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  170. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +125 -0
  171. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +218 -0
  172. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
  173. data/lib/bundler/vendor/thor/lib/thor/runner.rb +322 -0
  174. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  175. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +421 -0
  176. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
  177. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
  178. data/lib/bundler/vendor/thor/lib/thor/util.rb +267 -0
  179. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  180. data/lib/bundler/vendored_molinillo.rb +2 -0
  181. data/lib/bundler/vendored_persistent.rb +11 -0
  182. data/lib/bundler/vendored_thor.rb +3 -0
  183. data/lib/bundler/version.rb +6 -0
  184. data/lib/bundler/vlad.rb +11 -0
  185. data/lib/bundler/worker.rb +72 -0
  186. data/man/bundle-config.ronn +187 -0
  187. data/man/bundle-exec.ronn +136 -0
  188. data/man/bundle-gem.ronn +77 -0
  189. data/man/bundle-install.ronn +398 -0
  190. data/man/bundle-package.ronn +66 -0
  191. data/man/bundle-platform.ronn +42 -0
  192. data/man/bundle-update.ronn +188 -0
  193. data/man/bundle.ronn +98 -0
  194. data/man/gemfile.5.ronn +495 -0
  195. data/man/index.txt +8 -0
  196. metadata +346 -0
@@ -0,0 +1,42 @@
1
+ module Bundler
2
+ class CLI::Platform
3
+ attr_reader :options
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def run
9
+ platforms, ruby_version = Bundler.ui.silence do
10
+ [Bundler.definition.platforms.map {|p| "* #{p}" },
11
+ Bundler.definition.ruby_version]
12
+ end
13
+ output = []
14
+
15
+ if options[:ruby]
16
+ if ruby_version
17
+ output << ruby_version
18
+ else
19
+ output << "No ruby version specified"
20
+ end
21
+ else
22
+ output << "Your platform is: #{RUBY_PLATFORM}"
23
+ output << "Your app has gems that work on these platforms:\n#{platforms.join("\n")}"
24
+
25
+ if ruby_version
26
+ output << "Your Gemfile specifies a Ruby version requirement:\n* #{ruby_version}"
27
+
28
+ begin
29
+ Bundler.definition.validate_ruby!
30
+ output << "Your current platform satisfies the Ruby version requirement."
31
+ rescue RubyVersionMismatch => e
32
+ output << e.message
33
+ end
34
+ else
35
+ output << "Your Gemfile does not specify a Ruby version requirement."
36
+ end
37
+ end
38
+
39
+ Bundler.ui.info output.join("\n\n")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ require "bundler/cli/common"
2
+
3
+ module Bundler
4
+ class CLI::Show
5
+ attr_reader :options, :gem_name, :latest_specs
6
+ def initialize(options, gem_name)
7
+ @options = options
8
+ @gem_name = gem_name
9
+ @verbose = options[:verbose] || options[:outdated]
10
+ @latest_specs = fetch_latest_specs if @verbose
11
+ end
12
+
13
+ def run
14
+ Bundler.ui.silence do
15
+ Bundler.definition.validate_ruby!
16
+ Bundler.load.lock
17
+ end
18
+
19
+ if gem_name
20
+ if gem_name == "bundler"
21
+ path = File.expand_path("../../../..", __FILE__)
22
+ else
23
+ spec = Bundler::CLI::Common.select_spec(gem_name, :regex_match)
24
+ return unless spec
25
+ path = spec.full_gem_path
26
+ unless File.directory?(path)
27
+ Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at:"
28
+ end
29
+ end
30
+ return Bundler.ui.info(path)
31
+ end
32
+
33
+ if options[:paths]
34
+ Bundler.load.specs.sort_by(&:name).map do |s|
35
+ Bundler.ui.info s.full_gem_path
36
+ end
37
+ else
38
+ Bundler.ui.info "Gems included by the bundle:"
39
+ Bundler.load.specs.sort_by(&:name).each do |s|
40
+ desc = " * #{s.name} (#{s.version}#{s.git_version})"
41
+ if @verbose
42
+ latest = latest_specs.find {|l| l.name == s.name }
43
+ Bundler.ui.info <<-END.gsub(/^ +/, "")
44
+ #{desc}
45
+ \tSummary: #{s.summary || "No description available."}
46
+ \tHomepage: #{s.homepage || "No website available."}
47
+ \tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"}
48
+ END
49
+ else
50
+ Bundler.ui.info desc
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def fetch_latest_specs
59
+ definition = Bundler.definition(true)
60
+ if options[:outdated]
61
+ Bundler.ui.info "Fetching remote specs for outdated check...\n\n"
62
+ Bundler.ui.silence { definition.resolve_remotely! }
63
+ else
64
+ definition.resolve_with_cache!
65
+ end
66
+ definition.specs
67
+ end
68
+
69
+ def outdated?(current, latest)
70
+ return false unless latest
71
+ Gem::Version.new(current.version) < Gem::Version.new(latest.version)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,72 @@
1
+ module Bundler
2
+ class CLI::Update
3
+ attr_reader :options, :gems
4
+ def initialize(options, gems)
5
+ @options = options
6
+ @gems = gems
7
+ end
8
+
9
+ def run
10
+ Bundler.ui.level = "error" if options[:quiet]
11
+
12
+ sources = Array(options[:source])
13
+ groups = Array(options[:group]).map(&:to_sym)
14
+
15
+ if gems.empty? && sources.empty? && groups.empty?
16
+ # We're doing a full update
17
+ Bundler.definition(true)
18
+ else
19
+ unless Bundler.default_lockfile.exist?
20
+ raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
21
+ "Run `bundle install` to update and install the bundled gems."
22
+ end
23
+ # cycle through the requested gems, just to make sure they exist
24
+ names = Bundler.locked_gems.specs.map(&:name)
25
+ gems.each do |g|
26
+ next if names.include?(g)
27
+ require "bundler/cli/common"
28
+ raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(g, names)
29
+ end
30
+
31
+ if groups.any?
32
+ specs = Bundler.definition.specs_for groups
33
+ gems.concat(specs.map(&:name))
34
+ end
35
+
36
+ Bundler.definition(:gems => gems, :sources => sources)
37
+ end
38
+
39
+ Bundler::Fetcher.disable_endpoint = options["full-index"]
40
+
41
+ opts = options.dup
42
+ opts["update"] = true
43
+ opts["local"] = options[:local]
44
+
45
+ Bundler.settings[:jobs] = opts["jobs"] if opts["jobs"]
46
+
47
+ # rubygems plugins sometimes hook into the gem install process
48
+ Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)
49
+
50
+ Bundler.definition.validate_ruby!
51
+ Installer.install Bundler.root, Bundler.definition, opts
52
+ Bundler.load.cache if Bundler.app_cache.exist?
53
+
54
+ if Bundler.settings[:clean] && Bundler.settings[:path]
55
+ require "bundler/cli/clean"
56
+ Bundler::CLI::Clean.new(options).run
57
+ end
58
+
59
+ Bundler.ui.confirm "Bundle updated!"
60
+ without_groups_messages
61
+ end
62
+
63
+ private
64
+
65
+ def without_groups_messages
66
+ if Bundler.settings.without.any?
67
+ require "bundler/cli/common"
68
+ Bundler.ui.confirm Bundler::CLI::Common.without_groups_message
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,26 @@
1
+ module Bundler
2
+ class CLI::Viz
3
+ attr_reader :options, :gem_name
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def run
9
+ require "graphviz"
10
+ output_file = File.expand_path(options[:file])
11
+ graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without])
12
+ graph.viz
13
+ rescue LoadError => e
14
+ Bundler.ui.error e.inspect
15
+ Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:"
16
+ Bundler.ui.warn "`gem install ruby-graphviz`"
17
+ rescue StandardError => e
18
+ if e.message =~ /GraphViz not installed or dot not in PATH/
19
+ Bundler.ui.error e.message
20
+ Bundler.ui.warn "Please install GraphViz. On a Mac with homebrew, you can run `brew install graphviz`."
21
+ else
22
+ raise
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module Bundler
2
+ WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
3
+ FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/
4
+ NULL = WINDOWS ? "NUL" : "/dev/null"
5
+ end
@@ -0,0 +1,218 @@
1
+ module Bundler
2
+ # Returns current version of Ruby
3
+ #
4
+ # @return [CurrentRuby] Current version of Ruby
5
+ def self.current_ruby
6
+ @current_ruby ||= CurrentRuby.new
7
+ end
8
+
9
+ class CurrentRuby
10
+ def on_18?
11
+ RUBY_VERSION =~ /^1\.8/
12
+ end
13
+
14
+ def on_19?
15
+ RUBY_VERSION =~ /^1\.9/
16
+ end
17
+
18
+ def on_20?
19
+ RUBY_VERSION =~ /^2\.0/
20
+ end
21
+
22
+ def on_21?
23
+ RUBY_VERSION =~ /^2\.1/
24
+ end
25
+
26
+ def on_22?
27
+ RUBY_VERSION =~ /^2\.2/
28
+ end
29
+
30
+ def on_23?
31
+ RUBY_VERSION =~ /^2\.3/
32
+ end
33
+
34
+ def on_2?
35
+ on_20? || on_21? || on_22? || on_23?
36
+ end
37
+
38
+ def ruby?
39
+ !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev")
40
+ end
41
+
42
+ def ruby_18?
43
+ ruby? && on_18?
44
+ end
45
+
46
+ def ruby_19?
47
+ ruby? && on_19?
48
+ end
49
+
50
+ def ruby_20?
51
+ ruby? && on_20?
52
+ end
53
+
54
+ def ruby_21?
55
+ ruby? && on_21?
56
+ end
57
+
58
+ def ruby_22?
59
+ ruby? && on_22?
60
+ end
61
+
62
+ def ruby_23?
63
+ ruby? && on_23?
64
+ end
65
+
66
+ def ruby_2?
67
+ ruby? && on_2?
68
+ end
69
+
70
+ def mri?
71
+ !mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby")
72
+ end
73
+
74
+ def mri_18?
75
+ mri? && on_18?
76
+ end
77
+
78
+ def mri_19?
79
+ mri? && on_19?
80
+ end
81
+
82
+ def mri_20?
83
+ mri? && on_20?
84
+ end
85
+
86
+ def mri_21?
87
+ mri? && on_21?
88
+ end
89
+
90
+ def mri_22?
91
+ mri? && on_22?
92
+ end
93
+
94
+ def mri_23?
95
+ mri? && on_23?
96
+ end
97
+
98
+ def rbx?
99
+ ruby? && defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
100
+ end
101
+
102
+ def jruby?
103
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
104
+ end
105
+
106
+ def jruby_18?
107
+ jruby? && on_18?
108
+ end
109
+
110
+ def jruby_19?
111
+ jruby? && on_19?
112
+ end
113
+
114
+ def maglev?
115
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
116
+ end
117
+
118
+ def mswin?
119
+ Bundler::WINDOWS
120
+ end
121
+
122
+ def mswin_18?
123
+ mswin? && on_18?
124
+ end
125
+
126
+ def mswin_19?
127
+ mswin? && on_19?
128
+ end
129
+
130
+ def mswin_20?
131
+ mswin? && on_20?
132
+ end
133
+
134
+ def mswin_21?
135
+ mswin? && on_21?
136
+ end
137
+
138
+ def mswin_22?
139
+ mswin? && on_22?
140
+ end
141
+
142
+ def mswin_23?
143
+ mswin? && on_23?
144
+ end
145
+
146
+ def mswin64?
147
+ Bundler::WINDOWS && Gem::Platform.local.os == "mswin64" && Gem::Platform.local.cpu == "x64"
148
+ end
149
+
150
+ def mswin64_19?
151
+ mswin64? && on_19?
152
+ end
153
+
154
+ def mswin64_20?
155
+ mswin64? && on_20?
156
+ end
157
+
158
+ def mswin64_21?
159
+ mswin64? && on_21?
160
+ end
161
+
162
+ def mswin64_22?
163
+ mswin64? && on_22?
164
+ end
165
+
166
+ def mswin64_23?
167
+ mswin64? && on_23?
168
+ end
169
+
170
+ def mingw?
171
+ Bundler::WINDOWS && Gem::Platform.local.os == "mingw32" && Gem::Platform.local.cpu != "x64"
172
+ end
173
+
174
+ def mingw_18?
175
+ mingw? && on_18?
176
+ end
177
+
178
+ def mingw_19?
179
+ mingw? && on_19?
180
+ end
181
+
182
+ def mingw_20?
183
+ mingw? && on_20?
184
+ end
185
+
186
+ def mingw_21?
187
+ mingw? && on_21?
188
+ end
189
+
190
+ def mingw_22?
191
+ mingw? && on_22?
192
+ end
193
+
194
+ def mingw_23?
195
+ mingw? && on_23?
196
+ end
197
+
198
+ def x64_mingw?
199
+ Bundler::WINDOWS && Gem::Platform.local.os == "mingw32" && Gem::Platform.local.cpu == "x64"
200
+ end
201
+
202
+ def x64_mingw_20?
203
+ x64_mingw? && on_20?
204
+ end
205
+
206
+ def x64_mingw_21?
207
+ x64_mingw? && on_21?
208
+ end
209
+
210
+ def x64_mingw_22?
211
+ x64_mingw? && on_22?
212
+ end
213
+
214
+ def x64_mingw_23?
215
+ x64_mingw? && on_23?
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,675 @@
1
+ require "bundler/lockfile_parser"
2
+ require "digest/sha1"
3
+ require "set"
4
+
5
+ module Bundler
6
+ class Definition
7
+ include GemHelpers
8
+
9
+ attr_reader :dependencies, :platforms, :ruby_version, :locked_deps
10
+
11
+ # Given a gemfile and lockfile creates a Bundler definition
12
+ #
13
+ # @param gemfile [Pathname] Path to Gemfile
14
+ # @param lockfile [Pathname,nil] Path to Gemfile.lock
15
+ # @param unlock [Hash, Boolean, nil] Gems that have been requested
16
+ # to be updated or true if all gems should be updated
17
+ # @return [Bundler::Definition]
18
+ def self.build(gemfile, lockfile, unlock)
19
+ unlock ||= {}
20
+ gemfile = Pathname.new(gemfile).expand_path
21
+
22
+ unless gemfile.file?
23
+ raise GemfileNotFound, "#{gemfile} not found"
24
+ end
25
+
26
+ Dsl.evaluate(gemfile, lockfile, unlock)
27
+ end
28
+
29
+ #
30
+ # How does the new system work?
31
+ #
32
+ # * Load information from Gemfile and Lockfile
33
+ # * Invalidate stale locked specs
34
+ # * All specs from stale source are stale
35
+ # * All specs that are reachable only through a stale
36
+ # dependency are stale.
37
+ # * If all fresh dependencies are satisfied by the locked
38
+ # specs, then we can try to resolve locally.
39
+ #
40
+ # @param lockfile [Pathname] Path to Gemfile.lock
41
+ # @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile
42
+ # @param sources [Bundler::SourceList]
43
+ # @param unlock [Hash, Boolean, nil] Gems that have been requested
44
+ # to be updated or true if all gems should be updated
45
+ # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
46
+ # @param optional_groups [Array(String)] A list of optional groups
47
+ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [])
48
+ @unlocking = unlock == true || !unlock.empty?
49
+
50
+ @dependencies = dependencies
51
+ @sources = sources
52
+ @unlock = unlock
53
+ @optional_groups = optional_groups
54
+ @remote = false
55
+ @specs = nil
56
+ @ruby_version = ruby_version
57
+
58
+ @lockfile_contents = ""
59
+ @locked_bundler_version = nil
60
+
61
+ if lockfile && File.exist?(lockfile)
62
+ @lockfile_contents = Bundler.read_file(lockfile)
63
+ locked = LockfileParser.new(@lockfile_contents)
64
+ @platforms = locked.platforms
65
+ @locked_bundler_version = locked.bundler_version
66
+
67
+ if unlock != true
68
+ @locked_deps = locked.dependencies
69
+ @locked_specs = SpecSet.new(locked.specs)
70
+ @locked_sources = locked.sources
71
+ else
72
+ @unlock = {}
73
+ @locked_deps = []
74
+ @locked_specs = SpecSet.new([])
75
+ @locked_sources = []
76
+ end
77
+ else
78
+ @unlock = {}
79
+ @platforms = []
80
+ @locked_deps = []
81
+ @locked_specs = SpecSet.new([])
82
+ @locked_sources = []
83
+ end
84
+
85
+ @unlock[:gems] ||= []
86
+ @unlock[:sources] ||= []
87
+
88
+ current_platform = Bundler.rubygems.platforms.map {|p| generic(p) }.compact.last
89
+ @new_platform = !@platforms.include?(current_platform)
90
+ @platforms |= [current_platform]
91
+
92
+ @path_changes = converge_paths
93
+ eager_unlock = expand_dependencies(@unlock[:gems])
94
+ @unlock[:gems] = @locked_specs.for(eager_unlock).map(&:name)
95
+
96
+ @source_changes = converge_sources
97
+ @dependency_changes = converge_dependencies
98
+ @local_changes = converge_locals
99
+
100
+ fixup_dependency_types!
101
+ end
102
+
103
+ def fixup_dependency_types!
104
+ # XXX This is a temporary workaround for a bug when using rubygems 1.8.15
105
+ # where Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
106
+ # doesn't carry a notion of the dependency type, if you use
107
+ # add_development_dependency in a gemspec that's loaded with the gemspec
108
+ # directive, the lockfile dependencies and resolved dependencies end up
109
+ # with a mismatch on #type.
110
+ # Test coverage to catch a regression on this is in gemspec_spec.rb
111
+ @dependencies.each do |d|
112
+ if ld = @locked_deps.find {|l| l.name == d.name }
113
+ ld.instance_variable_set(:@type, d.type)
114
+ end
115
+ end
116
+ end
117
+
118
+ def resolve_with_cache!
119
+ raise "Specs already loaded" if @specs
120
+ sources.cached!
121
+ specs
122
+ end
123
+
124
+ def resolve_remotely!
125
+ raise "Specs already loaded" if @specs
126
+ @remote = true
127
+ sources.remote!
128
+ specs
129
+ end
130
+
131
+ # For given dependency list returns a SpecSet with Gemspec of all the required
132
+ # dependencies.
133
+ # 1. The method first resolves the dependencies specified in Gemfile
134
+ # 2. After that it tries and fetches gemspec of resolved dependencies
135
+ #
136
+ # @return [Bundler::SpecSet]
137
+ def specs
138
+ @specs ||= begin
139
+ specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
140
+
141
+ unless specs["bundler"].any?
142
+ local = Bundler.settings[:frozen] ? rubygems_index : index
143
+ bundler = local.search(Gem::Dependency.new("bundler", VERSION)).last
144
+ specs["bundler"] = bundler if bundler
145
+ end
146
+
147
+ specs
148
+ end
149
+ end
150
+
151
+ def new_specs
152
+ specs - @locked_specs
153
+ end
154
+
155
+ def removed_specs
156
+ @locked_specs - specs
157
+ end
158
+
159
+ def new_platform?
160
+ @new_platform
161
+ end
162
+
163
+ def missing_specs
164
+ missing = []
165
+ resolve.materialize(requested_dependencies, missing)
166
+ missing
167
+ end
168
+
169
+ def requested_specs
170
+ @requested_specs ||= begin
171
+ groups = requested_groups
172
+ groups.map!(&:to_sym)
173
+ specs_for(groups)
174
+ end
175
+ end
176
+
177
+ def current_dependencies
178
+ dependencies.reject {|d| !d.should_include? }
179
+ end
180
+
181
+ def specs_for(groups)
182
+ deps = dependencies.select {|d| (d.groups & groups).any? }
183
+ deps.delete_if {|d| !d.should_include? }
184
+ specs.for(expand_dependencies(deps))
185
+ end
186
+
187
+ # Resolve all the dependencies specified in Gemfile. It ensures that
188
+ # dependencies that have been already resolved via locked file and are fresh
189
+ # are reused when resolving dependencies
190
+ #
191
+ # @return [SpecSet] resolved dependencies
192
+ def resolve
193
+ @resolve ||= begin
194
+ last_resolve = converge_locked_specs
195
+ if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?)
196
+ last_resolve
197
+ else
198
+ # Run a resolve against the locally available gems
199
+ last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
200
+ end
201
+ end
202
+ end
203
+
204
+ def index
205
+ @index ||= Index.build do |idx|
206
+ dependency_names = @dependencies.map(&:name)
207
+
208
+ sources.all_sources.each do |source|
209
+ source.dependency_names = dependency_names.dup
210
+ idx.add_source source.specs
211
+ dependency_names -= pinned_spec_names(source.specs)
212
+ dependency_names.push(*source.unmet_deps).uniq!
213
+ end
214
+ end
215
+ end
216
+
217
+ # used when frozen is enabled so we can find the bundler
218
+ # spec, even if (say) a git gem is not checked out.
219
+ def rubygems_index
220
+ @rubygems_index ||= Index.build do |idx|
221
+ sources.rubygems_sources.each do |rubygems|
222
+ idx.add_source rubygems.specs
223
+ end
224
+ end
225
+ end
226
+
227
+ def has_rubygems_remotes?
228
+ sources.rubygems_sources.any? {|s| s.remotes.any? }
229
+ end
230
+
231
+ def has_local_dependencies?
232
+ !sources.path_sources.empty? || !sources.git_sources.empty?
233
+ end
234
+
235
+ def spec_git_paths
236
+ sources.git_sources.map {|s| s.path.to_s }
237
+ end
238
+
239
+ def groups
240
+ dependencies.map(&:groups).flatten.uniq
241
+ end
242
+
243
+ def lock(file, preserve_bundled_with = false)
244
+ contents = to_lock
245
+
246
+ # Convert to \r\n if the existing lock has them
247
+ # i.e., Windows with `git config core.autocrlf=true`
248
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
249
+
250
+ if @locked_bundler_version
251
+ locked_major = @locked_bundler_version.segments.first
252
+ current_major = Gem::Version.create(Bundler::VERSION).segments.first
253
+
254
+ if updating_major = locked_major < current_major
255
+ Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
256
+ "after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
257
+ end
258
+ end
259
+
260
+ preserve_bundled_with ||= !updating_major && (Bundler.settings[:frozen] || !@unlocking)
261
+ return if lockfiles_equal?(@lockfile_contents, contents, preserve_bundled_with)
262
+
263
+ if Bundler.settings[:frozen]
264
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
265
+ return
266
+ end
267
+
268
+ SharedHelpers.filesystem_access(file) do |p|
269
+ File.open(p, "wb") {|f| f.puts(contents) }
270
+ end
271
+ end
272
+
273
+ # Returns the version of Bundler that is creating or has created
274
+ # Gemfile.lock. Used in #to_lock.
275
+ def lock_version
276
+ if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
277
+ new_version = Bundler::VERSION
278
+ end
279
+
280
+ new_version || @locked_bundler_version || Bundler::VERSION
281
+ end
282
+
283
+ def to_lock
284
+ out = ""
285
+
286
+ sources.lock_sources.each do |source|
287
+ # Add the source header
288
+ out << source.to_lock
289
+ # Find all specs for this source
290
+ resolve.
291
+ select {|s| source.can_lock?(s) }.
292
+ # This needs to be sorted by full name so that
293
+ # gems with the same name, but different platform
294
+ # are ordered consistently
295
+ sort_by(&:full_name).
296
+ each do |spec|
297
+ next if spec.name == "bundler"
298
+ out << spec.to_lock
299
+ end
300
+ out << "\n"
301
+ end
302
+
303
+ out << "PLATFORMS\n"
304
+
305
+ platforms.map(&:to_s).sort.each do |p|
306
+ out << " #{p}\n"
307
+ end
308
+
309
+ out << "\n"
310
+ out << "DEPENDENCIES\n"
311
+
312
+ handled = []
313
+ dependencies.sort_by(&:to_s).each do |dep|
314
+ next if handled.include?(dep.name)
315
+ out << dep.to_lock
316
+ handled << dep.name
317
+ end
318
+
319
+ # Record the version of Bundler that was used to create the lockfile
320
+ out << "\nBUNDLED WITH\n"
321
+ out << " #{lock_version}\n"
322
+
323
+ out
324
+ end
325
+
326
+ def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
327
+ msg = "You are trying to install in deployment mode after changing\n" \
328
+ "your Gemfile. Run `bundle install` elsewhere and add the\n" \
329
+ "updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
330
+
331
+ unless explicit_flag
332
+ msg += "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
333
+ "freeze \nby running `bundle install --no-deployment`."
334
+ end
335
+
336
+ added = []
337
+ deleted = []
338
+ changed = []
339
+
340
+ gemfile_sources = sources.lock_sources
341
+ if @locked_sources != gemfile_sources
342
+ new_sources = gemfile_sources - @locked_sources
343
+ deleted_sources = @locked_sources - gemfile_sources
344
+
345
+ if new_sources.any?
346
+ added.concat new_sources.map {|source| "* source: #{source}" }
347
+ end
348
+
349
+ if deleted_sources.any?
350
+ deleted.concat deleted_sources.map {|source| "* source: #{source}" }
351
+ end
352
+ end
353
+
354
+ new_deps = @dependencies - @locked_deps
355
+ deleted_deps = @locked_deps - @dependencies
356
+
357
+ if new_deps.any?
358
+ added.concat new_deps.map {|d| "* #{pretty_dep(d)}" }
359
+ end
360
+
361
+ if deleted_deps.any?
362
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
363
+ end
364
+
365
+ both_sources = Hash.new {|h, k| h[k] = [] }
366
+ @dependencies.each {|d| both_sources[d.name][0] = d }
367
+ @locked_deps.each {|d| both_sources[d.name][1] = d.source }
368
+
369
+ both_sources.each do |name, (dep, lock_source)|
370
+ if (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
371
+ gemfile_source_name = (dep && dep.source) || "no specified source"
372
+ lockfile_source_name = lock_source || "no specified source"
373
+ changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
374
+ end
375
+ end
376
+
377
+ msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
378
+ msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
379
+ msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
380
+ msg << "\n"
381
+
382
+ raise ProductionError, msg if added.any? || deleted.any? || changed.any?
383
+ end
384
+
385
+ def validate_ruby!
386
+ return unless ruby_version
387
+
388
+ if diff = ruby_version.diff(Bundler.ruby_version)
389
+ problem, expected, actual = diff
390
+
391
+ msg = case problem
392
+ when :engine
393
+ "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
394
+ when :version
395
+ "Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
396
+ when :engine_version
397
+ "Your #{Bundler.ruby_version.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
398
+ when :patchlevel
399
+ if !expected.is_a?(String)
400
+ "The Ruby patchlevel in your Gemfile must be a string"
401
+ else
402
+ "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}"
403
+ end
404
+ end
405
+
406
+ raise RubyVersionMismatch, msg
407
+ end
408
+ end
409
+
410
+ attr_reader :sources
411
+ private :sources
412
+
413
+ private
414
+
415
+ def nothing_changed?
416
+ !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
417
+ end
418
+
419
+ def pretty_dep(dep, source = false)
420
+ msg = "#{dep.name}"
421
+ msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
422
+ msg << " from the `#{dep.source}` source" if source && dep.source
423
+ msg
424
+ end
425
+
426
+ # Check if the specs of the given source changed
427
+ # according to the locked source. A block should be
428
+ # in order to specify how the locked version of
429
+ # the source should be found.
430
+ def specs_changed?(source, &block)
431
+ locked = @locked_sources.find(&block)
432
+
433
+ if locked
434
+ unlocking = @locked_specs.any? do |locked_spec|
435
+ locked_spec.source.class == locked.class && locked_spec.source != locked
436
+ end
437
+ end
438
+
439
+ !locked || unlocking || dependencies_for_source_changed?(locked) || source.specs != locked.specs
440
+ end
441
+
442
+ def dependencies_for_source_changed?(source)
443
+ deps_for_source = @dependencies.select {|s| s.source == source }
444
+ locked_deps_for_source = @locked_deps.select {|s| s.source == source }
445
+
446
+ deps_for_source != locked_deps_for_source
447
+ end
448
+
449
+ # Get all locals and override their matching sources.
450
+ # Return true if any of the locals changed (for example,
451
+ # they point to a new revision) or depend on new specs.
452
+ def converge_locals
453
+ locals = []
454
+
455
+ Bundler.settings.local_overrides.map do |k, v|
456
+ spec = @dependencies.find {|s| s.name == k }
457
+ source = spec && spec.source
458
+ if source && source.respond_to?(:local_override!)
459
+ source.unlock! if @unlock[:gems].include?(spec.name)
460
+ locals << [source, source.local_override!(v)]
461
+ end
462
+ end
463
+
464
+ locals.any? do |source, changed|
465
+ changed || specs_changed?(source) {|o| source.class == o.class && source.uri == o.uri }
466
+ end
467
+ end
468
+
469
+ def converge_paths
470
+ sources.path_sources.any? do |source|
471
+ specs_changed?(source) do |ls|
472
+ ls.class == source.class && ls.path == source.path
473
+ end
474
+ end
475
+ end
476
+
477
+ def converge_sources
478
+ changes = false
479
+
480
+ # Get the Rubygems sources from the Gemfile.lock
481
+ locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
482
+ # Get the Rubygems remotes from the Gemfile
483
+ actual_remotes = sources.rubygems_remotes
484
+
485
+ # If there is a Rubygems source in both
486
+ if !locked_gem_sources.empty? && !actual_remotes.empty?
487
+ locked_gem_sources.each do |locked_gem|
488
+ # Merge the remotes from the Gemfile into the Gemfile.lock
489
+ changes |= locked_gem.replace_remotes(actual_remotes)
490
+ end
491
+ end
492
+
493
+ # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
494
+ # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
495
+ # source in the Gemfile.lock, use the one from the Gemfile.
496
+ changes |= sources.replace_sources!(@locked_sources)
497
+
498
+ sources.all_sources.each do |source|
499
+ # If the source is unlockable and the current command allows an unlock of
500
+ # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
501
+ # gem), unlock it. For git sources, this means to unlock the revision, which
502
+ # will cause the `ref` used to be the most recent for the branch (or master) if
503
+ # an explicit `ref` is not used.
504
+ if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
505
+ source.unlock!
506
+ changes = true
507
+ end
508
+ end
509
+
510
+ changes
511
+ end
512
+
513
+ def converge_dependencies
514
+ (@dependencies + @locked_deps).each do |dep|
515
+ if dep.source
516
+ dep.source = sources.get(dep.source)
517
+ end
518
+ end
519
+ Set.new(@dependencies) != Set.new(@locked_deps)
520
+ end
521
+
522
+ # Remove elements from the locked specs that are expired. This will most
523
+ # commonly happen if the Gemfile has changed since the lockfile was last
524
+ # generated
525
+ def converge_locked_specs
526
+ deps = []
527
+
528
+ # Build a list of dependencies that are the same in the Gemfile
529
+ # and Gemfile.lock. If the Gemfile modified a dependency, but
530
+ # the gem in the Gemfile.lock still satisfies it, this is fine
531
+ # too.
532
+ locked_deps_hash = @locked_deps.inject({}) do |hsh, dep|
533
+ hsh[dep] = dep
534
+ hsh
535
+ end
536
+ @dependencies.each do |dep|
537
+ locked_dep = locked_deps_hash[dep]
538
+
539
+ if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
540
+ deps << dep
541
+ elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
542
+ @locked_specs.each do |s|
543
+ @unlock[:gems] << s.name if s.source == dep.source
544
+ end
545
+
546
+ dep.source.unlock! if dep.source.respond_to?(:unlock!)
547
+ dep.source.specs.each {|s| @unlock[:gems] << s.name }
548
+ end
549
+ end
550
+
551
+ converged = []
552
+ @locked_specs.each do |s|
553
+ # Replace the locked dependency's source with the equivalent source from the Gemfile
554
+ dep = @dependencies.find {|d| s.satisfies?(d) }
555
+ s.source = (dep && dep.source) || sources.get(s.source)
556
+
557
+ # Don't add a spec to the list if its source is expired. For example,
558
+ # if you change a Git gem to Rubygems.
559
+ next if s.source.nil? || @unlock[:sources].include?(s.source.name)
560
+
561
+ # XXX This is a backwards-compatibility fix to preserve the ability to
562
+ # unlock a single gem by passing its name via `--source`. See issue #3759
563
+ next if s.source.nil? || @unlock[:sources].include?(s.name)
564
+
565
+ # If the spec is from a path source and it doesn't exist anymore
566
+ # then we just unlock it.
567
+
568
+ # Path sources have special logic
569
+ if s.source.instance_of?(Source::Path)
570
+ other = s.source.specs[s].first
571
+
572
+ # If the spec is no longer in the path source, unlock it. This
573
+ # commonly happens if the version changed in the gemspec
574
+ next unless other
575
+
576
+ deps2 = other.dependencies.select {|d| d.type != :development }
577
+ # If the dependencies of the path source have changed, unlock it
578
+ next unless s.dependencies.sort == deps2.sort
579
+ end
580
+
581
+ converged << s
582
+ end
583
+
584
+ resolve = SpecSet.new(converged)
585
+ resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems])
586
+ diff = @locked_specs.to_a - resolve.to_a
587
+
588
+ # Now, we unlock any sources that do not have anymore gems pinned to it
589
+ sources.all_sources.each do |source|
590
+ next unless source.respond_to?(:unlock!)
591
+
592
+ unless resolve.any? {|s| s.source == source }
593
+ source.unlock! if !diff.empty? && diff.any? {|s| s.source == source }
594
+ end
595
+ end
596
+
597
+ resolve
598
+ end
599
+
600
+ def in_locked_deps?(dep, locked_dep)
601
+ # Because the lockfile can't link a dep to a specific remote, we need to
602
+ # treat sources as equivalent anytime the locked dep has all the remotes
603
+ # that the Gemfile dep does.
604
+ locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
605
+ end
606
+
607
+ def satisfies_locked_spec?(dep)
608
+ @locked_specs.any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
609
+ end
610
+
611
+ def expanded_dependencies
612
+ @expanded_dependencies ||= expand_dependencies(dependencies, @remote)
613
+ end
614
+
615
+ def expand_dependencies(dependencies, remote = false)
616
+ deps = []
617
+ dependencies.each do |dep|
618
+ dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
619
+ next unless remote || dep.current_platform?
620
+ dep.gem_platforms(@platforms).each do |p|
621
+ deps << DepProxy.new(dep, p) if remote || p == generic(Gem::Platform.local)
622
+ end
623
+ end
624
+ deps
625
+ end
626
+
627
+ def requested_dependencies
628
+ groups = requested_groups
629
+ groups.map!(&:to_sym)
630
+ dependencies.reject {|d| !d.should_include? || (d.groups & groups).empty? }
631
+ end
632
+
633
+ def source_requirements
634
+ # Load all specs from remote sources
635
+ index
636
+
637
+ # Record the specs available in each gem's source, so that those
638
+ # specs will be available later when the resolver knows where to
639
+ # look for that gemspec (or its dependencies)
640
+ source_requirements = {}
641
+ dependencies.each do |dep|
642
+ next unless dep.source
643
+ source_requirements[dep.name] = dep.source.specs
644
+ end
645
+ source_requirements
646
+ end
647
+
648
+ def pinned_spec_names(specs)
649
+ names = []
650
+ specs.each do |s|
651
+ # TODO: when two sources without blocks is an error, we can change
652
+ # this check to !s.source.is_a?(Source::LocalRubygems). For now,
653
+ # we need to ask every Rubygems for every gem name.
654
+ if s.source.is_a?(Source::Git) || s.source.is_a?(Source::Path)
655
+ names << s.name
656
+ end
657
+ end
658
+ names.uniq!
659
+ names
660
+ end
661
+
662
+ def requested_groups
663
+ self.groups - Bundler.settings.without - @optional_groups + Bundler.settings.with
664
+ end
665
+
666
+ def lockfiles_equal?(current, proposed, preserve_bundled_with)
667
+ if preserve_bundled_with
668
+ pattern = /\n\n#{LockfileParser::BUNDLED}\n\s+#{Gem::Version::VERSION_PATTERN}\n/
669
+ current.sub(pattern, "\n") == proposed.sub(pattern, "\n")
670
+ else
671
+ current == proposed
672
+ end
673
+ end
674
+ end
675
+ end