bowline-bundler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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