bowline-bundler 0.0.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 (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +291 -0
  3. data/Rakefile +45 -0
  4. data/VERSION +1 -0
  5. data/bin/bowline-bundle +59 -0
  6. data/lib/bowline/bundler/bundle.rb +323 -0
  7. data/lib/bowline/bundler/cli.rb +87 -0
  8. data/lib/bowline/bundler/dependency.rb +62 -0
  9. data/lib/bowline/bundler/dsl.rb +182 -0
  10. data/lib/bowline/bundler/environment.rb +87 -0
  11. data/lib/bowline/bundler/finder.rb +51 -0
  12. data/lib/bowline/bundler/gem_bundle.rb +11 -0
  13. data/lib/bowline/bundler/gem_ext.rb +34 -0
  14. data/lib/bowline/bundler/remote_specification.rb +53 -0
  15. data/lib/bowline/bundler/resolver.rb +250 -0
  16. data/lib/bowline/bundler/runtime.rb +2 -0
  17. data/lib/bowline/bundler/source.rb +361 -0
  18. data/lib/bowline/bundler/templates/app_script.erb +3 -0
  19. data/lib/bowline/bundler/templates/environment.erb +156 -0
  20. data/lib/bowline/bundler/templates/environment_picker.erb +4 -0
  21. data/lib/bowline/bundler.rb +35 -0
  22. data/spec/bundler/cli_spec.rb +558 -0
  23. data/spec/bundler/directory_spec.rb +255 -0
  24. data/spec/bundler/dsl_spec.rb +126 -0
  25. data/spec/bundler/fetcher_spec.rb +138 -0
  26. data/spec/bundler/git_spec.rb +266 -0
  27. data/spec/bundler/installer_spec.rb +155 -0
  28. data/spec/bundler/manifest_file_spec.rb +105 -0
  29. data/spec/bundler/manifest_spec.rb +257 -0
  30. data/spec/bundler/runtime_spec.rb +141 -0
  31. data/spec/bundler/system_gems_spec.rb +42 -0
  32. data/spec/quality_spec.rb +57 -0
  33. data/spec/resolver/engine_spec.rb +112 -0
  34. data/spec/resolver/error_spec.rb +50 -0
  35. data/spec/resolver/fake_source_index_spec.rb +43 -0
  36. data/spec/resolver/prerelease_spec.rb +113 -0
  37. data/spec/spec_helper.rb +46 -0
  38. data/spec/support/builders.rb +257 -0
  39. data/spec/support/core_ext.rb +18 -0
  40. data/spec/support/helpers.rb +126 -0
  41. data/spec/support/matchers.rb +201 -0
  42. data/spec/support/path_utils.rb +63 -0
  43. metadata +126 -0
@@ -0,0 +1,255 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Faking gems with directories" do
4
+
5
+ describe "with a simple directory structure" do
6
+ 2.times do |i|
7
+ describe "stubbing out a gem with a directory -- #{i}" do
8
+ before(:each) do
9
+ build_lib "very-simple"
10
+ path = tmp_path("libs/very-simple-1.0")
11
+ path = path.relative_path_from(bundled_app) if i == 1
12
+
13
+ install_manifest <<-Gemfile
14
+ clear_sources
15
+ source "file://#{gem_repo1}"
16
+ gem "very-simple", "1.0", :path => "#{path}"
17
+ Gemfile
18
+ end
19
+
20
+ it "does not download the gem" do
21
+ tmp_gem_path.should_not include_cached_gem("very-simple-1.0")
22
+ tmp_gem_path.should include_installed_gem("very-simple-1.0")
23
+ tmp_gem_path.should_not include_vendored_dir("very-simple")
24
+ end
25
+
26
+ it "has very-simple in the load path" do
27
+ out = run_in_context "require 'very-simple' ; puts VERYSIMPLE"
28
+ out.should == "1.0"
29
+ end
30
+
31
+ it "does not remove the directory during cleanup" do
32
+ install_manifest <<-Gemfile
33
+ clear_sources
34
+ source "file://#{gem_repo1}"
35
+ Gemfile
36
+
37
+ tmp_path("libs/very-simple-1.0").should be_directory
38
+ end
39
+
40
+ it "can bundle --cached" do
41
+ %w(doc gems specifications environment.rb).each do |file|
42
+ FileUtils.rm_rf(tmp_gem_path(file))
43
+ end
44
+
45
+ Dir.chdir(bundled_app) do
46
+ out = gem_command :bundle, "--cached"
47
+ out = run_in_context "require 'very-simple' ; puts VERYSIMPLE"
48
+ out.should == "1.0"
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "bad directory stubbing" do
55
+ it "raises an exception unless the version is specified" do
56
+ build_lib "very-simple"
57
+ lambda do
58
+ install_manifest <<-Gemfile
59
+ clear_sources
60
+ gem "very-simple", :path => "#{tmp_path}/libs/very-simple-1.0"
61
+ Gemfile
62
+ end.should raise_error(Bundler::DirectorySourceError, /Please explicitly specify a version/)
63
+ end
64
+
65
+ it "raises an exception unless the version is an exact version" do
66
+ pending
67
+ lambda do
68
+ install_manifest <<-Gemfile
69
+ clear_sources
70
+ gem "very-simple", ">= 0.1.0", :path => "#{fixture_dir.join("very-simple")}"
71
+ Gemfile
72
+ end.should raise_error(ArgumentError, /:at/)
73
+ end
74
+ end
75
+ end
76
+
77
+ it "checks the root directory for a *.gemspec file" do
78
+ build_lib("very-simple", "1.0", :path => tmp_path("very-simple"), :gemspec => true) do |s|
79
+ s.add_dependency "rack", "= 0.9.1"
80
+ s.write "lib/very-simple.rb", "class VerySimpleForTests ; end"
81
+ end
82
+
83
+ install_manifest <<-Gemfile
84
+ clear_sources
85
+ source "file://#{gem_repo1}"
86
+ gem "very-simple", "1.0", :path => "#{tmp_path("very-simple")}"
87
+ Gemfile
88
+
89
+ tmp_gem_path.should_not include_cached_gem("very-simple-1.0")
90
+ tmp_gem_path.should include_cached_gem("rack-0.9.1")
91
+ tmp_gem_path.should include_installed_gem("rack-0.9.1")
92
+ end
93
+
94
+ it "works with prerelease gems" do
95
+ build_lib "very-simple", "1.0.pre", :gemspec => true
96
+ install_manifest <<-Gemfile
97
+ clear_sources
98
+ gem "very-simple", :path => "#{tmp_path}/libs/very-simple-1.0.pre"
99
+ Gemfile
100
+
101
+ out = run_in_context "Bundler.require_env ; puts VERYSIMPLE"
102
+ out.should == "1.0.pre"
103
+ end
104
+
105
+ it "recursively finds all gemspec files in a directory" do
106
+ build_lib("first", "1.0", :gemspec => true)
107
+ build_lib("second", "1.0", :gemspec => true) do |s|
108
+ s.add_dependency "first", ">= 0"
109
+ s.write "lib/second.rb", "require 'first' ; SECOND = '1.0'"
110
+ end
111
+
112
+ install_manifest <<-Gemfile
113
+ clear_sources
114
+ gem "second", :path => "#{tmp_path('libs')}"
115
+ Gemfile
116
+
117
+ out = run_in_context <<-RUBY
118
+ Bundler.require_env
119
+ puts FIRST
120
+ puts SECOND
121
+ RUBY
122
+
123
+ out.should == "1.0\n1.0"
124
+ end
125
+
126
+ it "copies bin files to the bin dir" do
127
+ build_lib('very-simple', '1.0', :gemspec => true) do |s|
128
+ s.executables << 'very_simple'
129
+ s.write "bin/very_simple", "#!#{Gem.ruby}\nputs 'OMG'"
130
+ end
131
+
132
+ install_manifest <<-Gemfile
133
+ clear_sources
134
+ gem "very-simple", :path => "#{tmp_path('libs/very-simple-1.0')}"
135
+ Gemfile
136
+
137
+ tmp_bindir('very_simple').should exist
138
+ `#{tmp_bindir('very_simple')}`.strip.should == 'OMG'
139
+ end
140
+
141
+ it "always pulls the dependency from the directory even if there is a newer gem available" do
142
+ build_lib('rack', '0.5', :gemspec => true)
143
+
144
+ install_manifest <<-Gemfile
145
+ clear_sources
146
+ source "file://#{gem_repo1}"
147
+ gem "rack", :path => "#{tmp_path('libs')}"
148
+ Gemfile
149
+
150
+ out = run_in_context <<-RUBY
151
+ Bundler.require_env
152
+ puts RACK
153
+ RUBY
154
+
155
+ out.should == '0.5'
156
+ end
157
+
158
+ describe "listing gems in a directory" do
159
+ it "directory can take a block" do
160
+ ext = bundled_app("externals")
161
+ ext.mkdir_p
162
+
163
+ build_lib "omg", "1.0", :path => "#{ext}/omg"
164
+ build_lib "hi2u", "1.0", :path => "#{ext}/hi2u"
165
+
166
+ install_manifest <<-Gemfile
167
+ clear_sources
168
+ directory "#{ext}" do
169
+ gem "omg", "1.0", :path => "omg"
170
+ gem "hi2u", "1.0", :path => "hi2u"
171
+ end
172
+ Gemfile
173
+
174
+ :default.should have_const("OMG")
175
+ :default.should have_const("HI2U")
176
+ end
177
+
178
+ it "directory can specify spermy specifiers" do
179
+ build_lib "omg", "1.0.2", :gemspec => true
180
+
181
+ install_manifest <<-Gemfile
182
+ clear_sources
183
+ gem "omg", "~> 1.0.0", :path => "#{tmp_path}/libs"
184
+ Gemfile
185
+
186
+ :default.should have_const("OMG")
187
+ end
188
+
189
+ it "raises exception when directory does not contain correct gem version" do
190
+ build_lib "omg", "1.0.2", :gemspec => true
191
+
192
+ lambda do
193
+ install_manifest <<-Gemfile
194
+ clear_sources
195
+ gem "omg", "~> 1.1", :path => "#{tmp_path}/libs"
196
+ Gemfile
197
+ end.should raise_error(Bundler::GemNotFound, /directory/)
198
+ end
199
+
200
+ it "can list vendored gems without :path" do
201
+ build_lib "omg", "1.0"
202
+ install_manifest <<-Gemfile
203
+ clear_sources
204
+ directory "#{tmp_path}/libs/omg-1.0" do
205
+ gem "omg", "1.0"
206
+ end
207
+ Gemfile
208
+
209
+ :default.should have_const("OMG")
210
+ end
211
+
212
+ it "raises an error when two gems are defined for the same path" do
213
+ build_lib "omg", "1.0"
214
+
215
+ lambda {
216
+ install_manifest <<-Gemfile
217
+ clear_sources
218
+ directory "#{tmp_path}/libs/omg-1.0" do
219
+ gem "omg", "1.0", :path => "omg"
220
+ gem "lol", "1.0", :path => "omg"
221
+ end
222
+ Gemfile
223
+ }.should raise_error(Bundler::DirectorySourceError, /already have a gem defined for/)
224
+ end
225
+
226
+ it "lets you set a directory source without a block" do
227
+ build_lib "omg", "1.0", :gemspec => true
228
+ build_lib "lol", "1.0", :gemspec => true
229
+
230
+ install_manifest <<-Gemfile
231
+ clear_sources
232
+ directory "#{tmp_path}/libs"
233
+ gem "omg"
234
+ gem "lol"
235
+ Gemfile
236
+
237
+ :default.should have_const("OMG")
238
+ end
239
+ end
240
+
241
+ it "takes a glob" do
242
+ build_lib "omg", "1.0", :gemspec => true
243
+ build_lib "omg", "2.0", :gemspec => true
244
+ install_manifest <<-Gemfile
245
+ clear_sources
246
+ directory "#{tmp_path}/libs", :glob => "**/*-1*/*.gemspec" do
247
+ gem "omg"
248
+ end
249
+ Gemfile
250
+
251
+ out = run_in_context "Bundler.require_env ; puts OMG"
252
+ out.should == "1.0"
253
+ end
254
+
255
+ end
@@ -0,0 +1,126 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Bundler DSL" do
4
+
5
+ it "supports only blocks" do
6
+ install_manifest <<-Gemfile
7
+ clear_sources
8
+ source "file://#{gem_repo1}"
9
+
10
+ gem "activerecord"
11
+
12
+ only :test do
13
+ gem "rspec", :require_as => "spec"
14
+ gem "very-simple"
15
+ end
16
+ Gemfile
17
+
18
+ "default".should have_const("ACTIVERECORD")
19
+ "default".should_not have_const("SPEC")
20
+ "default".should_not have_const("VERYSIMPLE")
21
+
22
+ "test".should have_const("ACTIVERECORD")
23
+ "test".should have_const("SPEC")
24
+ "test".should have_const("VERYSIMPLE")
25
+ end
26
+
27
+ it "supports only blocks with multiple args" do
28
+ install_manifest <<-Gemfile
29
+ clear_sources
30
+ source "file://#{gem_repo1}"
31
+ only :test, :production do
32
+ gem "rack"
33
+ end
34
+ Gemfile
35
+
36
+ "default".should_not have_const("RACK")
37
+ "test".should have_const("RACK")
38
+ "production".should have_const("RACK")
39
+ end
40
+
41
+ it "supports nesting only blocks" do
42
+ install_manifest <<-Gemfile
43
+ clear_sources
44
+ source "file://#{gem_repo1}"
45
+
46
+ only [:test, :staging] do
47
+ gem "very-simple"
48
+ only :test do
49
+ gem "rspec", :require_as => "spec"
50
+ end
51
+ end
52
+ Gemfile
53
+
54
+ "test".should have_const("VERYSIMPLE")
55
+ "test".should have_const("SPEC")
56
+ "staging".should have_const("VERYSIMPLE")
57
+ "staging".should_not have_const("SPEC")
58
+ end
59
+
60
+ it "supports except blocks" do
61
+ install_manifest <<-Gemfile
62
+ clear_sources
63
+ source "file://#{gem_repo1}"
64
+
65
+ gem "activerecord"
66
+
67
+ except :test do
68
+ gem "rspec", :require_as => "spec"
69
+ gem "very-simple"
70
+ end
71
+ Gemfile
72
+
73
+ "default".should have_const("ACTIVERECORD")
74
+ "default".should have_const("SPEC")
75
+ "default".should have_const("VERYSIMPLE")
76
+
77
+ "test".should have_const("ACTIVERECORD")
78
+ "test".should_not have_const("SPEC")
79
+ "test".should_not have_const("VERYSIMPLE")
80
+ end
81
+
82
+ it "supports except blocks with multiple args" do
83
+ install_manifest <<-Gemfile
84
+ clear_sources
85
+ source "file://#{gem_repo1}"
86
+ except :test, :production do
87
+ gem "rack"
88
+ end
89
+ Gemfile
90
+
91
+ "default".should have_const("RACK")
92
+ "test".should_not have_const("RACK")
93
+ "production".should_not have_const("RACK")
94
+ end
95
+
96
+ it "supports nesting except blocks" do
97
+ install_manifest <<-Gemfile
98
+ clear_sources
99
+ source "file://#{gem_repo1}"
100
+
101
+ except [:test] do
102
+ gem "very-simple"
103
+ except :omg do
104
+ gem "rspec", :require_as => "spec"
105
+ end
106
+ end
107
+ Gemfile
108
+
109
+ "default".should have_const("SPEC")
110
+ "default".should have_const("VERYSIMPLE")
111
+ "test".should_not have_const("VERYSIMPLE")
112
+ "test".should_not have_const("SPEC")
113
+ "omg".should have_const("VERYSIMPLE")
114
+ "omg".should_not have_const("SPEC")
115
+ end
116
+
117
+ it "raises an exception if you provide an invalid key" do
118
+ lambda do
119
+ install_manifest <<-Gemfile
120
+ clear_sources
121
+
122
+ gem "very-simple", :version => "1.0"
123
+ Gemfile
124
+ end.should raise_error(Bundler::InvalidKey)
125
+ end
126
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Fetcher" do
4
+
5
+ it "raises if the source does not exist" do
6
+ m = build_manifest <<-Gemfile
7
+ clear_sources
8
+ source "file://not/a/gem/source"
9
+ gem "foo"
10
+ Gemfile
11
+ lambda { m.install }.should raise_error(ArgumentError)
12
+ end
13
+
14
+ it "raises if the source is not available" do
15
+ m = build_manifest <<-Gemfile
16
+ clear_sources
17
+ source "http://localhost"
18
+ gem "foo"
19
+ Gemfile
20
+ lambda { m.install }.should raise_error(ArgumentError)
21
+ end
22
+
23
+ it "raises if the source is not a gem repository" do
24
+ m = build_manifest <<-Gemfile
25
+ clear_sources
26
+ source "http://google.com/not/a/gem/location"
27
+ gem "foo"
28
+ Gemfile
29
+ lambda { m.install }.should raise_error(ArgumentError)
30
+ end
31
+
32
+ it "outputs a logger message when updating an index from source" do
33
+ m = build_manifest <<-Gemfile
34
+ clear_sources
35
+ source "file://#{gem_repo1}"
36
+ gem "very-simple"
37
+ Gemfile
38
+ m.install
39
+ @log_output.should have_log_message("Updating source: file:#{gem_repo1}")
40
+ end
41
+
42
+ it "works with repositories that don't provide Marshal.4.8.Z" do
43
+ build_repo2
44
+ Dir["#{gem_repo2}/Marshal.*"].each { |f| File.unlink(f) }
45
+
46
+ install_manifest <<-Gemfile
47
+ clear_sources
48
+ source "file://#{gem_repo2}"
49
+ gem "rack"
50
+ Gemfile
51
+
52
+ tmp_gem_path.should have_cached_gems("rack-1.0.0")
53
+ end
54
+
55
+ it "works with repositories that don't provide prerelease_specs.4.8.gz" do
56
+ FileUtils.cp_r gem_repo1, gem_repo2
57
+ Dir["#{gem_repo2}/prerelease*"].each { |f| File.unlink(f) }
58
+
59
+ install_manifest <<-Gemfile
60
+ clear_sources
61
+ source "file://#{gem_repo2}"
62
+ gem "rack"
63
+ Gemfile
64
+
65
+ @log_output.should have_log_message("Source 'file:#{gem_repo2}' does not support prerelease gems")
66
+ tmp_gem_path.should have_cached_gems("rack-1.0.0")
67
+ end
68
+
69
+ describe "platforms" do
70
+ after :each do
71
+ Gem.platforms = nil
72
+ end
73
+
74
+ def rb ; Gem::Platform::RUBY ; end
75
+ def java ; Gem::Platform.new [nil, "java", nil] ; end
76
+ def linux ; Gem::Platform.new ['x86', 'linux', nil] ; end
77
+
78
+ it "installs the gem for the correct platform" do
79
+ Gem.platforms = [rb]
80
+ install_manifest <<-Gemfile
81
+ clear_sources
82
+ source "file://#{gem_repo1}"
83
+ gem "platform_specific"
84
+ Gemfile
85
+
86
+ out = run_in_context "Bundler.require_env ; puts PLATFORM_SPECIFIC"
87
+ out.should == "1.0.0 RUBY"
88
+ end
89
+
90
+ it "raises GemNotFound if no gem for correct platform exists" do
91
+ Gem.platforms = [linux]
92
+ lambda do
93
+ install_manifest <<-Gemfile
94
+ clear_sources
95
+ source "file://#{gem_repo1}"
96
+ gem "platform_specific"
97
+ Gemfile
98
+ end.should raise_error(Bundler::GemNotFound)
99
+ end
100
+
101
+ it "selects java one when both are available" do
102
+ Gem.platforms = [rb, java]
103
+ install_manifest <<-Gemfile
104
+ clear_sources
105
+ source "file://#{gem_repo1}"
106
+ gem "platform_specific"
107
+ Gemfile
108
+
109
+ out = run_in_context "Bundler.require_env ; puts PLATFORM_SPECIFIC"
110
+ out.should == "1.0.0 JAVA"
111
+ end
112
+
113
+ it "finds the java one when only Java is there" do
114
+ Gem.platforms = [rb, java]
115
+
116
+ install_manifest <<-Gemfile
117
+ clear_sources
118
+ source "file://#{gem_repo1}"
119
+ gem "only_java"
120
+ Gemfile
121
+
122
+ out = run_in_context "Bundler.require_env ; puts ONLY_JAVA"
123
+ out.should == "1.0"
124
+ end
125
+
126
+ it "raises GemNotFound if no gem for corect platform exists when gem dependencies are tied to specific sources" do
127
+ Gem.platforms = [rb]
128
+ system_gems "platform_specific-1.0-java" do
129
+ lambda do
130
+ install_manifest <<-Gemfile
131
+ clear_sources
132
+ gem "platform_specific", :bundle => false
133
+ Gemfile
134
+ end.should raise_error(Bundler::GemNotFound)
135
+ end
136
+ end
137
+ end
138
+ end