bundler_package_git 1.1.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. data/.gitignore +22 -0
  2. data/.rvmrc +1 -0
  3. data/CHANGELOG.md +659 -0
  4. data/ISSUES.md +47 -0
  5. data/LICENSE +23 -0
  6. data/README.md +29 -0
  7. data/Rakefile +167 -0
  8. data/UPGRADING.md +103 -0
  9. data/bin/bundle +22 -0
  10. data/bundler.gemspec +30 -0
  11. data/lib/bundler.rb +283 -0
  12. data/lib/bundler/capistrano.rb +11 -0
  13. data/lib/bundler/cli.rb +490 -0
  14. data/lib/bundler/definition.rb +429 -0
  15. data/lib/bundler/dependency.rb +130 -0
  16. data/lib/bundler/deployment.rb +53 -0
  17. data/lib/bundler/dsl.rb +243 -0
  18. data/lib/bundler/environment.rb +47 -0
  19. data/lib/bundler/fetcher.rb +101 -0
  20. data/lib/bundler/gem_helper.rb +146 -0
  21. data/lib/bundler/graph.rb +130 -0
  22. data/lib/bundler/index.rb +131 -0
  23. data/lib/bundler/installer.rb +117 -0
  24. data/lib/bundler/lazy_specification.rb +71 -0
  25. data/lib/bundler/lockfile_parser.rb +108 -0
  26. data/lib/bundler/remote_specification.rb +57 -0
  27. data/lib/bundler/resolver.rb +470 -0
  28. data/lib/bundler/rubygems_ext.rb +226 -0
  29. data/lib/bundler/runtime.rb +201 -0
  30. data/lib/bundler/settings.rb +117 -0
  31. data/lib/bundler/setup.rb +16 -0
  32. data/lib/bundler/shared_helpers.rb +167 -0
  33. data/lib/bundler/source.rb +675 -0
  34. data/lib/bundler/spec_set.rb +134 -0
  35. data/lib/bundler/templates/Executable +16 -0
  36. data/lib/bundler/templates/Gemfile +4 -0
  37. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  38. data/lib/bundler/templates/newgem/Rakefile.tt +2 -0
  39. data/lib/bundler/templates/newgem/bin/newgem.tt +3 -0
  40. data/lib/bundler/templates/newgem/gitignore.tt +4 -0
  41. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -0
  42. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  43. data/lib/bundler/templates/newgem/newgem.gemspec.tt +21 -0
  44. data/lib/bundler/ui.rb +73 -0
  45. data/lib/bundler/vendor/net/http/faster.rb +27 -0
  46. data/lib/bundler/vendor/net/http/persistent.rb +464 -0
  47. data/lib/bundler/vendor/thor.rb +319 -0
  48. data/lib/bundler/vendor/thor/actions.rb +297 -0
  49. data/lib/bundler/vendor/thor/actions/create_file.rb +105 -0
  50. data/lib/bundler/vendor/thor/actions/directory.rb +93 -0
  51. data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
  52. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +229 -0
  53. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +104 -0
  54. data/lib/bundler/vendor/thor/base.rb +556 -0
  55. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
  56. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  57. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
  58. data/lib/bundler/vendor/thor/error.rb +30 -0
  59. data/lib/bundler/vendor/thor/invocation.rb +168 -0
  60. data/lib/bundler/vendor/thor/parser.rb +4 -0
  61. data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
  62. data/lib/bundler/vendor/thor/parser/arguments.rb +161 -0
  63. data/lib/bundler/vendor/thor/parser/option.rb +120 -0
  64. data/lib/bundler/vendor/thor/parser/options.rb +174 -0
  65. data/lib/bundler/vendor/thor/shell.rb +88 -0
  66. data/lib/bundler/vendor/thor/shell/basic.rb +275 -0
  67. data/lib/bundler/vendor/thor/shell/color.rb +108 -0
  68. data/lib/bundler/vendor/thor/shell/html.rb +121 -0
  69. data/lib/bundler/vendor/thor/task.rb +114 -0
  70. data/lib/bundler/vendor/thor/util.rb +229 -0
  71. data/lib/bundler/vendor/thor/version.rb +3 -0
  72. data/lib/bundler/version.rb +6 -0
  73. data/lib/bundler/vlad.rb +9 -0
  74. data/man/bundle-config.ronn +90 -0
  75. data/man/bundle-exec.ronn +111 -0
  76. data/man/bundle-install.ronn +314 -0
  77. data/man/bundle-package.ronn +59 -0
  78. data/man/bundle-update.ronn +176 -0
  79. data/man/bundle.ronn +80 -0
  80. data/man/gemfile.5.ronn +279 -0
  81. data/man/index.txt +6 -0
  82. data/spec/cache/gems_spec.rb +219 -0
  83. data/spec/cache/git_spec.rb +9 -0
  84. data/spec/cache/path_spec.rb +27 -0
  85. data/spec/cache/platform_spec.rb +57 -0
  86. data/spec/install/deploy_spec.rb +197 -0
  87. data/spec/install/deprecated_spec.rb +37 -0
  88. data/spec/install/gems/c_ext_spec.rb +48 -0
  89. data/spec/install/gems/dependency_api_spec.rb +85 -0
  90. data/spec/install/gems/env_spec.rb +107 -0
  91. data/spec/install/gems/flex_spec.rb +313 -0
  92. data/spec/install/gems/groups_spec.rb +245 -0
  93. data/spec/install/gems/packed_spec.rb +84 -0
  94. data/spec/install/gems/platform_spec.rb +208 -0
  95. data/spec/install/gems/resolving_spec.rb +72 -0
  96. data/spec/install/gems/simple_case_spec.rb +715 -0
  97. data/spec/install/gems/standalone_spec.rb +162 -0
  98. data/spec/install/gems/sudo_spec.rb +73 -0
  99. data/spec/install/gems/win32_spec.rb +26 -0
  100. data/spec/install/gemspec_spec.rb +108 -0
  101. data/spec/install/git_spec.rb +571 -0
  102. data/spec/install/invalid_spec.rb +17 -0
  103. data/spec/install/path_spec.rb +353 -0
  104. data/spec/install/upgrade_spec.rb +26 -0
  105. data/spec/lock/git_spec.rb +35 -0
  106. data/spec/lock/lockfile_spec.rb +683 -0
  107. data/spec/other/check_spec.rb +221 -0
  108. data/spec/other/clean_spec.rb +202 -0
  109. data/spec/other/config_spec.rb +40 -0
  110. data/spec/other/console_spec.rb +54 -0
  111. data/spec/other/exec_spec.rb +241 -0
  112. data/spec/other/ext_spec.rb +16 -0
  113. data/spec/other/gem_helper_spec.rb +128 -0
  114. data/spec/other/help_spec.rb +38 -0
  115. data/spec/other/init_spec.rb +40 -0
  116. data/spec/other/newgem_spec.rb +24 -0
  117. data/spec/other/open_spec.rb +35 -0
  118. data/spec/other/show_spec.rb +82 -0
  119. data/spec/pack/gems_spec.rb +54 -0
  120. data/spec/quality_spec.rb +58 -0
  121. data/spec/resolver/basic_spec.rb +20 -0
  122. data/spec/resolver/platform_spec.rb +82 -0
  123. data/spec/runtime/executable_spec.rb +110 -0
  124. data/spec/runtime/load_spec.rb +107 -0
  125. data/spec/runtime/platform_spec.rb +90 -0
  126. data/spec/runtime/require_spec.rb +231 -0
  127. data/spec/runtime/setup_spec.rb +688 -0
  128. data/spec/runtime/with_clean_env_spec.rb +15 -0
  129. data/spec/spec_helper.rb +85 -0
  130. data/spec/support/artifice/endpoint.rb +50 -0
  131. data/spec/support/artifice/endpoint_fallback.rb +22 -0
  132. data/spec/support/artifice/endpoint_marshal_fail.rb +11 -0
  133. data/spec/support/artifice/endpoint_redirect.rb +11 -0
  134. data/spec/support/builders.rb +574 -0
  135. data/spec/support/fakeweb/rack-1.0.0.marshal +2 -0
  136. data/spec/support/fakeweb/windows.rb +23 -0
  137. data/spec/support/helpers.rb +246 -0
  138. data/spec/support/indexes.rb +112 -0
  139. data/spec/support/matchers.rb +89 -0
  140. data/spec/support/path.rb +73 -0
  141. data/spec/support/platforms.rb +53 -0
  142. data/spec/support/ruby_ext.rb +20 -0
  143. data/spec/support/rubygems_ext.rb +35 -0
  144. data/spec/support/rubygems_hax/platform.rb +11 -0
  145. data/spec/support/sudo.rb +21 -0
  146. data/spec/update/gems_spec.rb +121 -0
  147. data/spec/update/git_spec.rb +196 -0
  148. data/spec/update/source_spec.rb +51 -0
  149. metadata +294 -0
@@ -0,0 +1,226 @@
1
+ require 'pathname'
2
+
3
+ if defined?(Gem::QuickLoader)
4
+ # Gem Prelude makes me a sad panda :'(
5
+ Gem::QuickLoader.load_full_rubygems_library
6
+ end
7
+
8
+ require 'rubygems'
9
+ require 'rubygems/specification'
10
+
11
+ module Gem
12
+ @loaded_stacks = Hash.new { |h,k| h[k] = [] }
13
+
14
+ class Specification
15
+ attr_accessor :source, :location, :relative_loaded_from
16
+
17
+ alias_method :rg_full_gem_path, :full_gem_path
18
+ alias_method :rg_loaded_from, :loaded_from
19
+
20
+ def full_gem_path
21
+ source.respond_to?(:path) ?
22
+ Pathname.new(loaded_from).dirname.expand_path.to_s :
23
+ rg_full_gem_path
24
+ end
25
+
26
+ def loaded_from
27
+ relative_loaded_from ?
28
+ source.path.join(relative_loaded_from).to_s :
29
+ rg_loaded_from
30
+ end
31
+
32
+ def load_paths
33
+ require_paths.map do |require_path|
34
+ if require_path.include?(full_gem_path)
35
+ require_path
36
+ else
37
+ File.join(full_gem_path, require_path)
38
+ end
39
+ end
40
+ end
41
+
42
+ def groups
43
+ @groups ||= []
44
+ end
45
+
46
+ def git_version
47
+ if @loaded_from && File.exist?(File.join(full_gem_path, ".git"))
48
+ sha = Dir.chdir(full_gem_path){ `git rev-parse HEAD`.strip }
49
+ " #{sha[0..6]}"
50
+ end
51
+ end
52
+
53
+ def to_gemfile(path = nil)
54
+ gemfile = "source :gemcutter\n"
55
+ gemfile << dependencies_to_gemfile(nondevelopment_dependencies)
56
+ unless development_dependencies.empty?
57
+ gemfile << "\n"
58
+ gemfile << dependencies_to_gemfile(development_dependencies, :development)
59
+ end
60
+ gemfile
61
+ end
62
+
63
+ def nondevelopment_dependencies
64
+ dependencies - development_dependencies
65
+ end
66
+
67
+ def add_bundler_dependencies(*groups)
68
+ Bundler.ui.warn "#add_bundler_dependencies is deprecated and will " \
69
+ "be removed in Bundler 1.0. Instead, please use the #gemspec method " \
70
+ "in your Gemfile, which will pull in any dependencies specified in " \
71
+ "your gemspec"
72
+
73
+ groups = [:default] if groups.empty?
74
+ Bundler.definition.dependencies.each do |dep|
75
+ if dep.groups.include?(:development)
76
+ self.add_development_dependency(dep.name, dep.requirement.to_s)
77
+ elsif (dep.groups & groups).any?
78
+ self.add_dependency(dep.name, dep.requirement.to_s)
79
+ end
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def dependencies_to_gemfile(dependencies, group = nil)
86
+ gemfile = ''
87
+ if dependencies.any?
88
+ gemfile << "group :#{group} do\n" if group
89
+ dependencies.each do |dependency|
90
+ gemfile << ' ' if group
91
+ gemfile << %|gem "#{dependency.name}"|
92
+ req = dependency.requirements_list.first
93
+ gemfile << %|, "#{req}"| if req
94
+ gemfile << "\n"
95
+ end
96
+ gemfile << "end\n" if group
97
+ end
98
+ gemfile
99
+ end
100
+
101
+ end
102
+
103
+ class Dependency
104
+ attr_accessor :source, :groups
105
+
106
+ alias eql? ==
107
+
108
+ def encode_with(coder)
109
+ to_yaml_properties.each do |ivar|
110
+ coder[ivar.to_s.sub(/^@/, '')] = instance_variable_get(ivar)
111
+ end
112
+ end
113
+
114
+ def to_yaml_properties
115
+ instance_variables.reject { |p| ["@source", "@groups"].include?(p.to_s) }
116
+ end
117
+
118
+ def to_lock
119
+ out = " #{name}"
120
+ unless requirement == Gem::Requirement.default
121
+ out << " (#{requirement.to_s})"
122
+ end
123
+ out
124
+ end
125
+
126
+ def matches_spec?(spec)
127
+ # name can be a Regexp, so use ===
128
+ return false unless name === spec.name
129
+ return true if requirement.none?
130
+
131
+ requirement.satisfied_by?(spec.version)
132
+ end unless allocate.respond_to?(:matches_spec?)
133
+ end
134
+
135
+ class Requirement
136
+ def none?
137
+ @none ||= (to_s == ">= 0")
138
+ end unless allocate.respond_to?(:none?)
139
+ end
140
+
141
+ class Platform
142
+ JAVA = Gem::Platform.new('java')
143
+ MSWIN = Gem::Platform.new('mswin32')
144
+ MINGW = Gem::Platform.new('x86-mingw32')
145
+
146
+ def hash
147
+ @cpu.hash ^ @os.hash ^ @version.hash
148
+ end
149
+
150
+ alias eql? ==
151
+ end
152
+ end
153
+
154
+ module Bundler
155
+ class DepProxy
156
+
157
+ attr_reader :required_by, :__platform, :dep
158
+
159
+ def initialize(dep, platform)
160
+ @dep, @__platform, @required_by = dep, platform, []
161
+ end
162
+
163
+ def hash
164
+ @hash ||= dep.hash
165
+ end
166
+
167
+ def ==(o)
168
+ dep == o.dep && __platform == o.__platform
169
+ end
170
+
171
+ alias eql? ==
172
+
173
+ def type
174
+ @dep.type
175
+ end
176
+
177
+ def to_s
178
+ @dep.to_s
179
+ end
180
+
181
+ private
182
+
183
+ def method_missing(*args)
184
+ @dep.send(*args)
185
+ end
186
+
187
+ end
188
+
189
+ module GemHelpers
190
+
191
+ GENERIC_CACHE = {}
192
+ GENERICS = [
193
+ Gem::Platform::JAVA,
194
+ Gem::Platform::MSWIN,
195
+ Gem::Platform::MINGW,
196
+ Gem::Platform::RUBY
197
+ ]
198
+
199
+ def generic(p)
200
+ return p if p == Gem::Platform::RUBY
201
+
202
+ GENERIC_CACHE[p] ||= begin
203
+ found = GENERICS.find do |p2|
204
+ p2.is_a?(Gem::Platform) && p.os == p2.os
205
+ end
206
+ found || Gem::Platform::RUBY
207
+ end
208
+ end
209
+ end
210
+
211
+ module MatchPlatform
212
+ include GemHelpers
213
+
214
+ def match_platform(p)
215
+ Gem::Platform::RUBY == platform or
216
+ platform.nil? or p == platform or
217
+ generic(Gem::Platform.new(platform)) == p
218
+ end
219
+ end
220
+ end
221
+
222
+ module Gem
223
+ class Specification
224
+ include Bundler::MatchPlatform
225
+ end
226
+ end
@@ -0,0 +1,201 @@
1
+ require "digest/sha1"
2
+
3
+ module Bundler
4
+ class Runtime < Environment
5
+ include SharedHelpers
6
+
7
+ def setup(*groups)
8
+ # Has to happen first
9
+ clean_load_path
10
+
11
+ specs = groups.any? ? @definition.specs_for(groups) : requested_specs
12
+
13
+ setup_environment
14
+ cripple_rubygems(specs)
15
+
16
+ # Activate the specs
17
+ specs.each do |spec|
18
+ unless spec.loaded_from
19
+ raise GemNotFound, "#{spec.full_name} is missing. Run `bundle` to get it."
20
+ end
21
+
22
+ if activated_spec = Gem.loaded_specs[spec.name] and activated_spec.version != spec.version
23
+ e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
24
+ "but your Gemfile requires #{spec.name} #{spec.version}. Consider using bundle exec."
25
+ e.name = spec.name
26
+ if e.respond_to?(:requirement=)
27
+ e.requirement = Gem::Requirement.new(spec.version.to_s)
28
+ else
29
+ e.version_requirement = Gem::Requirement.new(spec.version.to_s)
30
+ end
31
+ raise e
32
+ end
33
+
34
+ Gem.loaded_specs[spec.name] = spec
35
+ load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)}
36
+ $LOAD_PATH.unshift(*load_paths)
37
+ end
38
+
39
+ lock
40
+
41
+ self
42
+ end
43
+
44
+ REGEXPS = [
45
+ /^no such file to load -- (.+)$/i,
46
+ /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
47
+ /^Missing API definition file in (.+)$/i,
48
+ /^cannot load such file -- (.+)$/i,
49
+ ]
50
+
51
+ def require(*groups)
52
+ groups.map! { |g| g.to_sym }
53
+ groups = [:default] if groups.empty?
54
+
55
+ @definition.dependencies.each do |dep|
56
+ # Skip the dependency if it is not in any of the requested
57
+ # groups
58
+ next unless ((dep.groups & groups).any? && dep.current_platform?)
59
+
60
+ required_file = nil
61
+
62
+ begin
63
+ # Loop through all the specified autorequires for the
64
+ # dependency. If there are none, use the dependency's name
65
+ # as the autorequire.
66
+ Array(dep.autorequire || dep.name).each do |file|
67
+ required_file = file
68
+ Kernel.require file
69
+ end
70
+ rescue LoadError => e
71
+ REGEXPS.find { |r| r =~ e.message }
72
+ raise if dep.autorequire || $1 != required_file
73
+ end
74
+ end
75
+ end
76
+
77
+ def dependencies_for(*groups)
78
+ if groups.empty?
79
+ dependencies
80
+ else
81
+ dependencies.select { |d| (groups & d.groups).any? }
82
+ end
83
+ end
84
+
85
+ alias gems specs
86
+
87
+ def cache
88
+ FileUtils.mkdir_p(cache_path)
89
+
90
+ Bundler.ui.info "Updating .gem and git files in vendor/cache"
91
+ specs.each do |spec|
92
+ next if spec.name == 'bundler'
93
+ spec.source.cache(spec) if spec.source.respond_to?(:cache)
94
+ end
95
+ prune_cache unless Bundler.settings[:no_prune]
96
+ end
97
+
98
+ def prune_cache
99
+ FileUtils.mkdir_p(cache_path)
100
+
101
+ resolve = @definition.resolve
102
+ cached = Dir["#{cache_path}/*.gem"]
103
+
104
+ cached = cached.delete_if do |path|
105
+ spec = Gem::Format.from_file_by_path(path).spec
106
+
107
+ resolve.any? do |s|
108
+ s.name == spec.name && s.version == spec.version && !s.source.is_a?(Bundler::Source::Git)
109
+ end
110
+ end
111
+
112
+ if cached.any?
113
+ Bundler.ui.info "Removing outdated .gem files from vendor/cache"
114
+
115
+ cached.each do |path|
116
+ Bundler.ui.info " * #{File.basename(path)}"
117
+ File.delete(path)
118
+ end
119
+ end
120
+ end
121
+
122
+ def clean
123
+ return false if Bundler.settings[:path] == nil
124
+
125
+ gem_bins = Dir["#{Gem.dir}/bin/*"]
126
+ git_dirs = Dir["#{Gem.dir}/bundler/gems/*"]
127
+ gem_dirs = Dir["#{Gem.dir}/gems/*"]
128
+ spec_gem_paths = specs.collect {|spec| spec.full_gem_path }
129
+ spec_gem_executables = specs.collect do |spec|
130
+ spec.executables.collect do |executable|
131
+ "#{Gem.dir}/#{spec.bindir}/#{executable}"
132
+ end
133
+ end.flatten
134
+ stale_gem_bins = gem_bins - spec_gem_executables
135
+ stale_git_dirs = git_dirs - spec_gem_paths
136
+ stale_gem_dirs = gem_dirs - spec_gem_paths
137
+
138
+ stale_gem_bins.each {|bin| FileUtils.rm(bin) }
139
+ stale_gem_dirs.collect do |gem_dir|
140
+ full_name = Pathname.new(gem_dir).basename.to_s
141
+
142
+ FileUtils.rm_rf(gem_dir)
143
+ specification_file = "#{Gem.dir}/specifications/#{full_name}.gemspec"
144
+ FileUtils.rm(specification_file) if File.exists?(specification_file)
145
+
146
+ parts = full_name.split('-')
147
+ name = parts[0..-2].join('-')
148
+ version = parts.last
149
+ output = "#{name} (#{version})"
150
+
151
+ Bundler.ui.info "Removing #{output}"
152
+
153
+ output
154
+ end + stale_git_dirs.collect do |gem_dir|
155
+ full_name = Pathname.new(gem_dir).basename.to_s
156
+
157
+ FileUtils.rm_rf(gem_dir)
158
+
159
+ parts = full_name.split('-')
160
+ name = parts[0..-3].join('-')
161
+ revision = parts[-1]
162
+ version = parts[-2]
163
+ output = "#{name} (#{version} #{revision})"
164
+
165
+ Bundler.ui.info "Removing #{output}"
166
+
167
+ output
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ def cache_path
174
+ root.join("vendor/cache")
175
+ end
176
+
177
+ def setup_environment
178
+ begin
179
+ ENV["BUNDLE_BIN_PATH"] = Gem.bin_path("bundler", "bundle", VERSION)
180
+ rescue Gem::GemNotFoundException
181
+ ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/bundle", __FILE__)
182
+ end
183
+
184
+ # Set PATH
185
+ paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
186
+ paths.unshift "#{Bundler.bundle_path}/bin"
187
+ ENV["PATH"] = paths.uniq.join(File::PATH_SEPARATOR)
188
+
189
+ # Set BUNDLE_GEMFILE
190
+ ENV["BUNDLE_GEMFILE"] = default_gemfile.to_s
191
+
192
+ # Set RUBYOPT
193
+ rubyopt = [ENV["RUBYOPT"]].compact
194
+ if rubyopt.empty? || rubyopt.first !~ /-rbundler\/setup/
195
+ rubyopt.unshift "-rbundler/setup"
196
+ rubyopt.unshift "-I#{File.expand_path('../..', __FILE__)}"
197
+ ENV["RUBYOPT"] = rubyopt.join(' ')
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,117 @@
1
+ module Bundler
2
+ class Settings
3
+ def initialize(root)
4
+ @root = root
5
+ @local_config = File.exist?(local_config_file) ? YAML.load_file(local_config_file) : {}
6
+ @global_config = File.exist?(global_config_file) ? YAML.load_file(global_config_file) : {}
7
+ end
8
+
9
+ def [](key)
10
+ key = key_for(key)
11
+ @local_config[key] || ENV[key] || @global_config[key]
12
+ end
13
+
14
+ def []=(key, value)
15
+ set_key(key, value, @local_config, local_config_file)
16
+ end
17
+
18
+ def delete(key)
19
+ @local_config
20
+ end
21
+
22
+ def set_global(key, value)
23
+ set_key(key, value, @global_config, global_config_file)
24
+ end
25
+
26
+ def all
27
+ env_keys = ENV.keys.select { |k| k =~ /BUNDLE_.*/ }
28
+ keys = @global_config.keys | @local_config.keys | env_keys
29
+
30
+ keys.map do |key|
31
+ key.sub(/^BUNDLE_/, '').gsub(/__/, ".").downcase
32
+ end
33
+ end
34
+
35
+ def locations(key)
36
+ locations = {}
37
+
38
+ locations[:local] = @local_config[key] if @local_config.key?(key)
39
+ locations[:env] = ENV[key] if ENV[key]
40
+ locations[:global] = @global_config[key] if @global_config.key?(key)
41
+ locations
42
+ end
43
+
44
+ def pretty_values_for(exposed_key)
45
+ key = key_for(exposed_key)
46
+
47
+ locations = []
48
+ if @local_config.key?(key)
49
+ locations << "Set for your local app (#{local_config_file}): #{@local_config[key].inspect}"
50
+ end
51
+
52
+ if value = ENV[key]
53
+ locations << "Set via #{key}: #{value.inspect}"
54
+ end
55
+
56
+ if @global_config.key?(key)
57
+ locations << "Set for the current user (#{global_config_file}): #{@global_config[key].inspect}"
58
+ end
59
+
60
+ return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
61
+ locations
62
+ end
63
+
64
+ def without=(array)
65
+ unless array.empty?
66
+ self[:without] = array.join(":")
67
+ end
68
+ end
69
+
70
+ def without
71
+ self[:without] ? self[:without].split(":").map { |w| w.to_sym } : []
72
+ end
73
+
74
+ # @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
75
+ def path
76
+ path = ENV[key_for(:path)] || @global_config[key_for(:path)]
77
+ return path if path && !@local_config.key?(key_for(:path))
78
+
79
+ if path = self[:path]
80
+ "#{path}/#{Bundler.ruby_scope}"
81
+ else
82
+ Gem.dir
83
+ end
84
+ end
85
+
86
+ def allow_sudo?
87
+ !@local_config.key?(key_for(:path))
88
+ end
89
+
90
+ private
91
+ def key_for(key)
92
+ key = key.to_s.sub(".", "__").upcase
93
+ "BUNDLE_#{key}"
94
+ end
95
+
96
+ def set_key(key, value, hash, file)
97
+ key = key_for(key)
98
+
99
+ unless hash[key] == value
100
+ hash[key] = value
101
+ hash.delete(key) if value.nil?
102
+ FileUtils.mkdir_p(file.dirname)
103
+ File.open(file, "w") { |f| f.puts hash.to_yaml }
104
+ end
105
+ value
106
+ end
107
+
108
+ def global_config_file
109
+ file = ENV["BUNDLE_CONFIG"] || File.join(Gem.user_home, ".bundle/config")
110
+ Pathname.new(file)
111
+ end
112
+
113
+ def local_config_file
114
+ Pathname.new("#{@root}/config")
115
+ end
116
+ end
117
+ end