appraisal 0.5.2 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -4
- data/README.md +87 -36
- data/appraisal.gemspec +10 -7
- data/bin/appraisal +7 -0
- data/features/appraisals.feature +16 -2
- data/features/bundler_gemfile_compatibility.feature +70 -0
- data/features/gemspec.feature +0 -11
- data/features/missing_appraisals_file.feature +23 -0
- data/features/step_definitions/dependency_steps.rb +17 -24
- data/features/support/dependency_helpers.rb +29 -0
- data/lib/appraisal/appraisal.rb +52 -12
- data/lib/appraisal/cli.rb +87 -0
- data/lib/appraisal/command.rb +4 -2
- data/lib/appraisal/errors.rb +8 -0
- data/lib/appraisal/file.rb +8 -2
- data/lib/appraisal/gemfile.rb +40 -10
- data/lib/appraisal/gemspec.rb +1 -7
- data/lib/appraisal/git_source.rb +23 -0
- data/lib/appraisal/group.rb +17 -0
- data/lib/appraisal/task.rb +20 -18
- data/lib/appraisal/utils.rb +8 -0
- data/lib/appraisal/version.rb +1 -1
- data/spec/acceptance/cli_spec.rb +233 -0
- data/spec/appraisal/appraisal_spec.rb +61 -7
- data/spec/appraisal/file_spec.rb +9 -0
- data/spec/appraisal/gemfile_spec.rb +43 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/acceptance_test_helpers.rb +113 -0
- metadata +61 -11
- data/GOALS +0 -5
data/lib/appraisal/version.rb
CHANGED
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'appraisal/utils'
|
3
|
+
|
4
|
+
describe 'CLI' do
|
5
|
+
context 'appraisal (with no arguments)' do
|
6
|
+
it 'runs install command' do
|
7
|
+
build_appraisal_file <<-Appraisal
|
8
|
+
appraise '1.0.0' do
|
9
|
+
gem 'dummy', '1.0.0'
|
10
|
+
end
|
11
|
+
Appraisal
|
12
|
+
|
13
|
+
run_simple 'appraisal'
|
14
|
+
|
15
|
+
expect(file 'gemfiles/1.0.0.gemfile').to be_exists
|
16
|
+
expect(file 'gemfiles/1.0.0.gemfile.lock').to be_exists
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'appraisal (with arguments)' do
|
21
|
+
before do
|
22
|
+
build_appraisal_file <<-Appraisal
|
23
|
+
appraise '1.0.0' do
|
24
|
+
gem 'dummy', '1.0.0'
|
25
|
+
end
|
26
|
+
|
27
|
+
appraise '1.1.0' do
|
28
|
+
gem 'dummy', '1.1.0'
|
29
|
+
end
|
30
|
+
Appraisal
|
31
|
+
|
32
|
+
run_simple 'appraisal install'
|
33
|
+
write_file 'test.rb', 'puts "Running: #{$dummy_version}"'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets APPRAISAL_INITIALIZED environment variable' do
|
37
|
+
write_file 'test.rb', <<-TEST_FILE.strip_heredoc
|
38
|
+
if ENV['APPRAISAL_INITIALIZED']
|
39
|
+
puts "Appraisal initialized!"
|
40
|
+
end
|
41
|
+
TEST_FILE
|
42
|
+
|
43
|
+
test_command = 'appraisal 1.0.0 ruby -rbundler/setup -rdummy test.rb'
|
44
|
+
run_simple test_command
|
45
|
+
expect(output_from test_command).to include 'Appraisal initialized!'
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with appraisal name' do
|
49
|
+
it 'runs the given command against a correct versions of dependency' do
|
50
|
+
test_command = 'appraisal 1.0.0 ruby -rbundler/setup -rdummy test.rb'
|
51
|
+
run_simple test_command
|
52
|
+
|
53
|
+
expect(output_from test_command).to include 'Running: 1.0.0'
|
54
|
+
expect(output_from test_command).to_not include 'Running: 1.1.0'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'without appraisal name' do
|
59
|
+
it 'runs the given command against all versions of dependency' do
|
60
|
+
test_command = 'appraisal ruby -rbundler/setup -rdummy test.rb'
|
61
|
+
run_simple test_command
|
62
|
+
|
63
|
+
expect(output_from test_command).to include 'Running: 1.0.0'
|
64
|
+
expect(output_from test_command).to include 'Running: 1.1.0'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'appraisal generate' do
|
70
|
+
it 'generates the gemfiles' do
|
71
|
+
build_appraisal_file <<-Appraisal
|
72
|
+
appraise '1.0.0' do
|
73
|
+
gem 'dummy', '1.0.0'
|
74
|
+
end
|
75
|
+
|
76
|
+
appraise '1.1.0' do
|
77
|
+
gem 'dummy', '1.1.0'
|
78
|
+
end
|
79
|
+
Appraisal
|
80
|
+
|
81
|
+
run_simple 'appraisal generate'
|
82
|
+
|
83
|
+
expect(file 'gemfiles/1.0.0.gemfile').to be_exists
|
84
|
+
expect(file 'gemfiles/1.1.0.gemfile').to be_exists
|
85
|
+
expect(content_of 'gemfiles/1.0.0.gemfile').to eq <<-gemfile.strip_heredoc
|
86
|
+
# This file was generated by Appraisal
|
87
|
+
|
88
|
+
source "https://rubygems.org"
|
89
|
+
|
90
|
+
gem "appraisal", :path=>"#{PROJECT_ROOT}"
|
91
|
+
gem "dummy", "1.0.0"
|
92
|
+
gemfile
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'appraisal install' do
|
97
|
+
it 'installs the dependencies' do
|
98
|
+
build_appraisal_file <<-Appraisal
|
99
|
+
appraise '1.0.0' do
|
100
|
+
gem 'dummy', '1.0.0'
|
101
|
+
end
|
102
|
+
|
103
|
+
appraise '1.1.0' do
|
104
|
+
gem 'dummy', '1.1.0'
|
105
|
+
end
|
106
|
+
Appraisal
|
107
|
+
|
108
|
+
run_simple 'appraisal install'
|
109
|
+
|
110
|
+
expect(file 'gemfiles/1.0.0.gemfile.lock').to be_exists
|
111
|
+
expect(file 'gemfiles/1.1.0.gemfile.lock').to be_exists
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'relativize directory in gemfile.lock' do
|
115
|
+
build_gemspec
|
116
|
+
add_gemspec_to_gemfile
|
117
|
+
build_appraisal_file <<-Appraisal
|
118
|
+
appraise '1.0.0' do
|
119
|
+
gem 'dummy', '1.0.0'
|
120
|
+
end
|
121
|
+
Appraisal
|
122
|
+
|
123
|
+
run_simple 'appraisal install'
|
124
|
+
|
125
|
+
expect(content_of 'gemfiles/1.0.0.gemfile.lock').not_to include current_dir
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'with job size', parallel: true do
|
129
|
+
before do
|
130
|
+
build_appraisal_file <<-Appraisal
|
131
|
+
appraise '1.0.0' do
|
132
|
+
gem 'dummy', '1.0.0'
|
133
|
+
end
|
134
|
+
Appraisal
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'accepts --jobs option to set job size' do
|
138
|
+
run_simple 'appraisal install --jobs=2'
|
139
|
+
|
140
|
+
expect(output_from 'appraisal install --jobs=2').to include
|
141
|
+
'bundle install --gemfile=gemfiles/1.0.0.gemfile --jobs=2'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'ignores --jobs option if the job size is less than or equal to 1' do
|
145
|
+
run_simple 'appraisal install --jobs=0'
|
146
|
+
|
147
|
+
expect(output_from 'appraisal install --jobs=0').not_to include
|
148
|
+
'bundle install --gemfile=gemfiles/1.0.0.gemfile'
|
149
|
+
expect(output_from 'appraisal install --jobs=0').not_to include
|
150
|
+
'bundle install --gemfile=gemfiles/1.0.0.gemfile --jobs=0'
|
151
|
+
expect(output_from 'appraisal install --jobs=0').not_to include
|
152
|
+
'bundle install --gemfile=gemfiles/1.0.0.gemfile --jobs=1'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'appraisal clean' do
|
158
|
+
it 'remove all gemfiles from gemfiles directory' do
|
159
|
+
build_appraisal_file <<-Appraisal
|
160
|
+
appraise '1.0.0' do
|
161
|
+
gem 'dummy', '1.0.0'
|
162
|
+
end
|
163
|
+
Appraisal
|
164
|
+
|
165
|
+
run_simple 'appraisal install'
|
166
|
+
write_file 'gemfiles/non_related_file', ''
|
167
|
+
|
168
|
+
run_simple 'appraisal clean'
|
169
|
+
|
170
|
+
expect(file 'gemfiles/1.0.0.gemfile').not_to be_exists
|
171
|
+
expect(file 'gemfiles/1.0.0.gemfile.lock').not_to be_exists
|
172
|
+
expect(file 'gemfiles/non_related_file').to be_exists
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'appraisal update' do
|
177
|
+
before do
|
178
|
+
build_gem 'dummy2', '1.0.0'
|
179
|
+
|
180
|
+
build_appraisal_file <<-Appraisal
|
181
|
+
appraise 'dummy' do
|
182
|
+
gem 'dummy', '~> 1.0.0'
|
183
|
+
gem 'dummy2', '~> 1.0.0'
|
184
|
+
end
|
185
|
+
Appraisal
|
186
|
+
|
187
|
+
run_simple 'appraisal install'
|
188
|
+
build_gem 'dummy', '1.0.1'
|
189
|
+
build_gem 'dummy2', '1.0.1'
|
190
|
+
end
|
191
|
+
|
192
|
+
after do
|
193
|
+
in_current_dir do
|
194
|
+
`gem uninstall dummy -v 1.0.1`
|
195
|
+
`gem uninstall dummy2 -a`
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'with no arguments' do
|
200
|
+
it 'updates all the gems' do
|
201
|
+
run_simple 'appraisal update'
|
202
|
+
|
203
|
+
expect(content_of 'gemfiles/dummy.gemfile.lock').to include 'dummy (1.0.1)'
|
204
|
+
expect(content_of 'gemfiles/dummy.gemfile.lock').to include 'dummy2 (1.0.1)'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'with a list of gems' do
|
209
|
+
it 'only updates specified gems' do
|
210
|
+
run_simple 'appraisal update dummy'
|
211
|
+
|
212
|
+
expect(content_of 'gemfiles/dummy.gemfile.lock').to include 'dummy (1.0.1)'
|
213
|
+
expect(content_of 'gemfiles/dummy.gemfile.lock').to include 'dummy2 (1.0.0)'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'appraisal help' do
|
219
|
+
it 'prints usage along with commands, and list of appraisals' do
|
220
|
+
build_appraisal_file <<-Appraisal
|
221
|
+
appraise '1.0.0' do
|
222
|
+
gem 'dummy', '1.0.0'
|
223
|
+
end
|
224
|
+
Appraisal
|
225
|
+
|
226
|
+
run_simple 'appraisal help'
|
227
|
+
|
228
|
+
expect(output_from 'appraisal help').to include 'Usage:'
|
229
|
+
expect(output_from 'appraisal help').to include 'appraisal [APPRAISAL_NAME] EXTERNAL_COMMAND'
|
230
|
+
expect(output_from 'appraisal help').to include '1.0.0'
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
@@ -1,14 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'appraisal/appraisal'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'active_support/core_ext/kernel/reporting'
|
3
5
|
|
4
6
|
describe Appraisal::Appraisal do
|
5
|
-
it "creates a proper bundle command" do
|
6
|
-
appraisal = Appraisal::Appraisal.new('fake', 'fake')
|
7
|
-
appraisal.stub(:gemfile_path).and_return("/home/test/test directory")
|
8
|
-
|
9
|
-
appraisal.bundle_command.should == "bundle check --gemfile='/home/test/test directory' || bundle install --gemfile='/home/test/test directory'"
|
10
|
-
end
|
11
|
-
|
12
7
|
it "converts spaces to underscores in the gemfile path" do
|
13
8
|
appraisal = Appraisal::Appraisal.new("one two", "Gemfile")
|
14
9
|
appraisal.gemfile_path.should =~ /one_two\.gemfile$/
|
@@ -23,4 +18,63 @@ describe Appraisal::Appraisal do
|
|
23
18
|
appraisal = Appraisal::Appraisal.new("rails3.0", "Gemfile")
|
24
19
|
appraisal.gemfile_path.should =~ /rails3\.0\.gemfile$/
|
25
20
|
end
|
21
|
+
|
22
|
+
context 'gemfiles generation' do
|
23
|
+
before do
|
24
|
+
@output = Tempfile.new('output')
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
@output.close
|
29
|
+
@output.unlink
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'generates a gemfile with a newline at the end of file' do
|
33
|
+
appraisal = Appraisal::Appraisal.new('fake', 'fake')
|
34
|
+
appraisal.stub(:gemfile_path) { @output.path }
|
35
|
+
appraisal.write_gemfile
|
36
|
+
@output.read.should =~ /[^\n]*\n\z/m
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'parallel installation' do
|
41
|
+
before do
|
42
|
+
@appraisal = Appraisal::Appraisal.new('fake', 'fake')
|
43
|
+
@appraisal.stub(:gemfile_path).and_return("/home/test/test directory")
|
44
|
+
Appraisal::Command.stub(:new => double(:run => true))
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'runs single install command on Bundler < 1.4.0' do
|
48
|
+
stub_const('Bundler::VERSION', '1.3.0')
|
49
|
+
|
50
|
+
warning = capture(:stderr) do
|
51
|
+
@appraisal.install(42)
|
52
|
+
end
|
53
|
+
|
54
|
+
Appraisal::Command.should have_received(:new).
|
55
|
+
with("#{bundle_check_command} || #{bundle_single_install_command}")
|
56
|
+
warning.should include 'Please upgrade Bundler'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'runs parallel install command on Bundler >= 1.4.0' do
|
60
|
+
stub_const('Bundler::VERSION', '1.4.0')
|
61
|
+
|
62
|
+
@appraisal.install(42)
|
63
|
+
|
64
|
+
Appraisal::Command.should have_received(:new).
|
65
|
+
with("#{bundle_check_command} || #{bundle_parallel_install_command}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def bundle_check_command
|
69
|
+
"bundle check --gemfile='/home/test/test directory'"
|
70
|
+
end
|
71
|
+
|
72
|
+
def bundle_single_install_command
|
73
|
+
"bundle install --gemfile='/home/test/test directory'"
|
74
|
+
end
|
75
|
+
|
76
|
+
def bundle_parallel_install_command
|
77
|
+
"bundle install --gemfile='/home/test/test directory' --jobs=42"
|
78
|
+
end
|
79
|
+
end
|
26
80
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'appraisal/file'
|
3
|
+
|
4
|
+
describe Appraisal::File do
|
5
|
+
it "should complain when no Appraisals file is found" do
|
6
|
+
::File.stub(:exist?).with("Appraisals").and_return(false)
|
7
|
+
expect { described_class.new }.to raise_error(Appraisal::AppraisalsNotFound)
|
8
|
+
end
|
9
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'appraisal/gemfile'
|
3
|
+
require 'active_support/core_ext/string/strip'
|
3
4
|
|
4
5
|
describe Appraisal::Gemfile do
|
5
6
|
it "supports gemfiles without sources" do
|
@@ -27,4 +28,46 @@ describe Appraisal::Gemfile do
|
|
27
28
|
gemfile.source :one
|
28
29
|
gemfile.to_s.strip.should == %{source :one}
|
29
30
|
end
|
31
|
+
|
32
|
+
it 'supports group syntax' do
|
33
|
+
gemfile = Appraisal::Gemfile.new
|
34
|
+
|
35
|
+
gemfile.group :development, :test do
|
36
|
+
gem "one"
|
37
|
+
end
|
38
|
+
|
39
|
+
gemfile.to_s.should == <<-GEMFILE.strip_heredoc.strip
|
40
|
+
group :development, :test do
|
41
|
+
gem "one"
|
42
|
+
end
|
43
|
+
GEMFILE
|
44
|
+
end
|
45
|
+
|
46
|
+
context "excess new line" do
|
47
|
+
context "no contents" do
|
48
|
+
it "shows empty string" do
|
49
|
+
gemfile = Appraisal::Gemfile.new
|
50
|
+
gemfile.to_s.should eq ""
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "full contents" do
|
55
|
+
it "does not show newline at end" do
|
56
|
+
gemfile = Appraisal::Gemfile.new
|
57
|
+
gemfile.source "source"
|
58
|
+
gemfile.gem "gem"
|
59
|
+
gemfile.gemspec
|
60
|
+
gemfile.to_s.should =~ /[^\n]\z/m
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "no gemspec" do
|
65
|
+
it "does not show newline at end" do
|
66
|
+
gemfile = Appraisal::Gemfile.new
|
67
|
+
gemfile.source "source"
|
68
|
+
gemfile.gem "gem"
|
69
|
+
gemfile.to_s.should =~ /[^\n]\z/m
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
30
73
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
|
+
require 'aruba/api'
|
4
|
+
require './spec/support/acceptance_test_helpers'
|
5
|
+
|
6
|
+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
|
7
|
+
TMP_GEM_ROOT = File.join(PROJECT_ROOT, "tmp", "gems")
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.include AcceptanceTestHelpers, :type => :acceptance, :example_group => {
|
11
|
+
:file_path => %r{spec\/acceptance\/}
|
12
|
+
}
|
13
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'rspec/expectations/expectation_target'
|
2
|
+
require 'active_support/core_ext/string/strip'
|
3
|
+
require 'active_support/concern'
|
4
|
+
require './features/support/dependency_helpers'
|
5
|
+
|
6
|
+
module AcceptanceTestHelpers
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include Aruba::Api
|
9
|
+
include DependencyHelpers
|
10
|
+
|
11
|
+
included do
|
12
|
+
metadata[:type] = :acceptance
|
13
|
+
|
14
|
+
before :all do
|
15
|
+
initialize_aruba_instance_variables
|
16
|
+
build_default_dummy_gems
|
17
|
+
end
|
18
|
+
|
19
|
+
after :all do
|
20
|
+
cleanup_default_gems
|
21
|
+
end
|
22
|
+
|
23
|
+
before parallel: true do
|
24
|
+
unless Appraisal::Utils.support_parallel_installation?
|
25
|
+
pending 'This Bundler version does not support --jobs flag.'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
before do
|
30
|
+
cleanup_artifacts
|
31
|
+
build_default_gemfile
|
32
|
+
unset_bundler_env_vars
|
33
|
+
ENV["GEM_PATH"] = [TMP_GEM_ROOT, ENV["GEM_PATH"]].join(":")
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
restore_env
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_appraisal_file(content)
|
42
|
+
write_file 'Appraisals', content.strip_heredoc
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_gemfile(content)
|
46
|
+
write_file 'Gemfile', content.strip_heredoc
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_gemspec_to_gemfile
|
50
|
+
append_to_file 'gemfile', 'gemspec'
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_gemspec
|
54
|
+
gem_name = dirs.last
|
55
|
+
|
56
|
+
write_file "#{gem_name}.gemspec", <<-gemspec
|
57
|
+
Gem::Specification.new do |s|
|
58
|
+
s.name = '#{gem_name}'
|
59
|
+
s.version = '0.1'
|
60
|
+
s.summary = 'Awesome Gem!'
|
61
|
+
end
|
62
|
+
gemspec
|
63
|
+
end
|
64
|
+
|
65
|
+
def content_of(path)
|
66
|
+
file(path).read
|
67
|
+
end
|
68
|
+
|
69
|
+
def file(path)
|
70
|
+
Pathname.new(current_dir) + path
|
71
|
+
end
|
72
|
+
|
73
|
+
def be_exists
|
74
|
+
be_exist
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def cleanup_artifacts
|
80
|
+
FileUtils.rm_rf(current_dir)
|
81
|
+
end
|
82
|
+
|
83
|
+
def cleanup_default_gems
|
84
|
+
FileUtils.rm_rf(TMP_GEM_ROOT)
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize_aruba_instance_variables
|
88
|
+
@announce_stdout = nil
|
89
|
+
@announce_stderr = nil
|
90
|
+
@announce_cmd = nil
|
91
|
+
@announce_dir = nil
|
92
|
+
@announce_env = nil
|
93
|
+
@aruba_timeout_seconds = 60
|
94
|
+
@aruba_io_wait_seconds = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_default_dummy_gems
|
98
|
+
FileUtils.rm_rf(TMP_GEM_ROOT)
|
99
|
+
FileUtils.mkdir_p(TMP_GEM_ROOT)
|
100
|
+
|
101
|
+
build_gem 'dummy', '1.0.0'
|
102
|
+
build_gem 'dummy', '1.1.0'
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_default_gemfile
|
106
|
+
build_gemfile <<-Gemfile
|
107
|
+
source 'https://rubygems.org'
|
108
|
+
|
109
|
+
gem 'dummy'
|
110
|
+
gem 'appraisal', :path => '#{PROJECT_ROOT}'
|
111
|
+
Gemfile
|
112
|
+
end
|
113
|
+
end
|