fingertips-adyen 0.3.7.20100917

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,152 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper.rb"
2
+
3
+ describe Adyen::Form do
4
+
5
+ before(:all) do
6
+ Adyen::Form.register_skin(:testing, '4aD37dJA', 'Kah942*$7sdp0)')
7
+ Adyen::Form.default_parameters[:merchant_account] = 'TestMerchant'
8
+ end
9
+
10
+ describe 'Action URLs' do
11
+
12
+ before(:each) do
13
+ # Use autodetection for the environment unless otherwise specified
14
+ Adyen.environment = nil
15
+ end
16
+
17
+ it "should generate correct the testing url" do
18
+ Adyen::Form.url.should eql('https://test.adyen.com/hpp/select.shtml')
19
+ end
20
+
21
+ it "should generate a live url if the environemtn is set top live" do
22
+ Adyen.environment = :live
23
+ Adyen::Form.url.should eql('https://live.adyen.com/hpp/select.shtml')
24
+ end
25
+
26
+ it "should generate correct live url in a production environment" do
27
+ Adyen.stub!(:autodetect_environment).and_return('live')
28
+ Adyen::Form.url.should eql('https://live.adyen.com/hpp/select.shtml')
29
+ end
30
+
31
+ it "should generate correct live url if explicitely asked for" do
32
+ Adyen::Form.url(:live).should eql('https://live.adyen.com/hpp/select.shtml')
33
+ end
34
+ end
35
+
36
+ describe 'redirect signature check' do
37
+ before(:each) do
38
+ # Example taken from integration manual
39
+
40
+ # Example get params sent back with redirect
41
+ @params = { :authResult => 'AUTHORISED', :pspReference => '1211992213193029',
42
+ :merchantReference => 'Internet Order 12345', :skinCode => '4aD37dJA',
43
+ :merchantSig => 'ytt3QxWoEhAskUzUne0P5VA9lPw='}
44
+ end
45
+
46
+ it "should calculate the signature string correctly" do
47
+ Adyen::Form.redirect_signature_string(@params).should eql('AUTHORISED1211992213193029Internet Order 123454aD37dJA')
48
+ end
49
+
50
+ it "should calculate the signature correctly" do
51
+ Adyen::Form.redirect_signature(@params).should eql(@params[:merchantSig])
52
+ end
53
+
54
+ it "should check the signature correctly with explicit shared signature" do
55
+ Adyen::Form.redirect_signature_check(@params, 'Kah942*$7sdp0)').should be_true
56
+ end
57
+
58
+ it "should check the signature correctly using the stored shared secret" do
59
+ Adyen::Form.redirect_signature_check(@params).should be_true
60
+ end
61
+
62
+
63
+ it "should detect a tampered field" do
64
+ Adyen::Form.redirect_signature_check(@params.merge(:pspReference => 'tampered')).should be_false
65
+ end
66
+
67
+ it "should detect a tampered signature" do
68
+ Adyen::Form.redirect_signature_check(@params.merge(:merchantSig => 'tampered')).should be_false
69
+ end
70
+
71
+ end
72
+
73
+ describe 'redirect URL generation' do
74
+ before(:each) do
75
+ @attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
76
+ :merchant_reference => 'Internet Order 12345', :skin => :testing,
77
+ :session_validity => 1.hour.from_now }
78
+
79
+ @redirect_url = Adyen::Form.redirect_url(@attributes)
80
+ end
81
+
82
+ it "should return an URL pointing to the adyen server" do
83
+ @redirect_url.should =~ %r[^#{Adyen::Form.url}]
84
+ end
85
+
86
+ it "should include all provided attributes" do
87
+ params = @redirect_url.split('?', 2).last.split('&').map { |param| param.split('=', 2).first }
88
+ params.should include(*(@attributes.keys.map { |k| k.to_s.camelize(:lower) }))
89
+ end
90
+
91
+ it "should include the merchant signature" do
92
+ params = @redirect_url.split('?', 2).last.split('&').map { |param| param.split('=', 2).first }
93
+ params.should include('merchantSig')
94
+ end
95
+ end
96
+
97
+ describe 'hidden fields generation' do
98
+
99
+ include ActionView::Helpers::TagHelper
100
+
101
+ before(:each) do
102
+ @attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
103
+ :merchant_reference => 'Internet Order 12345', :skin => :testing,
104
+ :session_validity => 1.hour.from_now }
105
+ end
106
+
107
+ it "should generate a valid payment form" do
108
+ content_tag(:form, Adyen::Form.hidden_fields(@attributes),
109
+ :action => Adyen::Form.url, :method => :post).should have_adyen_payment_form
110
+ end
111
+ end
112
+
113
+ describe 'signature calculation' do
114
+
115
+ # This example is taken from the Adyen integration manual
116
+
117
+ before(:each) do
118
+
119
+ @parameters = { :currency_code => 'GBP', :payment_amount => 10000,
120
+ :ship_before_date => '2007-10-20', :merchant_reference => 'Internet Order 12345',
121
+ :skin => :testing, :session_validity => '2007-10-11T11:00:00Z' }
122
+
123
+ Adyen::Form.do_parameter_transformations!(@parameters)
124
+ end
125
+
126
+ it "should construct the signature string correctly" do
127
+ signature_string = Adyen::Form.calculate_signature_string(@parameters)
128
+ signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z")
129
+ end
130
+
131
+ it "should calculate the signature correctly" do
132
+ signature = Adyen::Form.calculate_signature(@parameters)
133
+ signature.should eql('x58ZcRVL1H6y+XSeBGrySJ9ACVo=')
134
+ end
135
+
136
+ it "should calculate the signature correctly for a recurring payment" do
137
+ # Add the required recurrent payment attributes
138
+ @parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
139
+
140
+ signature_string = Adyen::Form.calculate_signature_string(@parameters)
141
+ signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Zgras.shopper@somewhere.orggrasshopper52DEFAULT")
142
+ end
143
+
144
+ it "should calculate the signature correctly for a recurring payment" do
145
+ # Add the required recurrent payment attributes
146
+ @parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
147
+
148
+ signature = Adyen::Form.calculate_signature(@parameters)
149
+ signature.should eql('F2BQEYbE+EUhiRGuPtcD16Gm7JY=')
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,97 @@
1
+ require "#{File.dirname(__FILE__)}/spec_helper.rb"
2
+
3
+ describe Adyen::Notification do
4
+
5
+ before(:all) do
6
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
7
+
8
+ ActiveRecord::Migration.verbose = false
9
+ Adyen::Notification::Migration.up
10
+ end
11
+
12
+ after(:all) do
13
+ Adyen::Notification::Migration.down
14
+ end
15
+
16
+ describe Adyen::Notification::HttpPost do
17
+
18
+ describe 'receiving payment authorization notification' do
19
+
20
+ before(:each) do
21
+ @request = mock('request')
22
+ @request.stub!(:params).and_return({
23
+ "merchantAccountCode"=>"FloorPlannerNL", "eventCode"=>"AUTHORISATION",
24
+ "paymentMethod"=>"mc", "eventDate"=>"2009-08-10T09:00:08.04Z",
25
+ "operations"=>"CANCEL,CAPTURE,REFUND", "merchantReference"=>"4",
26
+ "action"=>"process_adyen", "live"=>"false", "controller"=>"payment_notifications",
27
+ "value"=>"2500", "success"=>"false", "reason"=>"10676:1111:12/2012",
28
+ "originalReference"=>"", "pspReference"=>"8712498948081194", "currency"=>"USD"})
29
+
30
+ @notification = Adyen::Notification::HttpPost.log(@request)
31
+ end
32
+
33
+ after(:each) { @notification.destroy }
34
+
35
+ it "should have saved the notification record" do
36
+ @notification.should_not be_new_record
37
+ end
38
+
39
+ it "should be an authorization" do
40
+ @notification.should be_authorisation
41
+ end
42
+
43
+ it "should convert the amount to a bigdecimal" do
44
+ @notification.value.should eql(BigDecimal.new('25.00'))
45
+ end
46
+
47
+ it "should convert live to a boolean" do
48
+ @notification.should_not be_live
49
+ end
50
+
51
+ it "should convert success to a boolean" do
52
+ @notification.should_not be_success
53
+ end
54
+
55
+ it "should not be a successfull authorization" do
56
+ @notification.should_not be_successful_authorization
57
+ end
58
+
59
+ it "should convert the eventDate" do
60
+ @notification.event_date.should be_kind_of(Time)
61
+ end
62
+
63
+ it "should convert the empty original reference to NULL" do
64
+ @notification.original_reference.should be_nil
65
+ end
66
+ end
67
+
68
+ context 'duplicate detection' do
69
+ before(:each) do
70
+
71
+ @fields = { "merchantAccountCode"=>"FloorPlannerNL", "eventCode"=>"AUTHORISATION",
72
+ "paymentMethod"=>"mc", "eventDate"=>"2009-08-10T09:00:08.04Z",
73
+ "operations"=>"CANCEL,CAPTURE,REFUND", "merchantReference"=>"4",
74
+ "action"=>"process_adyen", "live"=>"false", "controller"=>"payment_notifications",
75
+ "value"=>"2500", "success"=>"false", "reason"=>"10676:1111:12/2012",
76
+ "originalReference"=>"", "pspReference"=>"8712498948081194", "currency"=>"USD"}
77
+
78
+ @request = mock('request')
79
+ @request.stub!(:params).and_return(@fields)
80
+ @notification = Adyen::Notification::HttpPost.log(@request)
81
+ end
82
+
83
+ after(:each) { @notification.destroy }
84
+
85
+ it "should raise an error on a duplicate notification" do
86
+ lambda { Adyen::Notification::HttpPost.log(@request) }.should raise_error(ActiveRecord::RecordInvalid)
87
+ end
88
+
89
+ it "should not raise an error on a when success is set to true" do
90
+ second_request = mock('request')
91
+ second_request.stub!(:params).and_return(@fields.merge('success' => 'true'))
92
+ lambda { Adyen::Notification::HttpPost.log(second_request) }.should_not raise_error
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rubygems'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'active_support'
7
+
8
+ require 'adyen'
9
+
10
+ Spec::Runner.configure do |config|
11
+ config.include Adyen::Matchers
12
+ end
@@ -0,0 +1,371 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/tasklib'
4
+ require 'date'
5
+ require 'git'
6
+
7
+ module GithubGem
8
+
9
+ # Detects the gemspc file of this project using heuristics.
10
+ def self.detect_gemspec_file
11
+ FileList['*.gemspec'].first
12
+ end
13
+
14
+ # Detects the main include file of this project using heuristics
15
+ def self.detect_main_include
16
+ if detect_gemspec_file =~ /^(\.*)\.gemspec$/ && File.exist?("lib/#{$1}.rb")
17
+ "lib/#{$1}.rb"
18
+ elsif FileList['lib/*.rb'].length == 1
19
+ FileList['lib/*.rb'].first
20
+ else
21
+ nil
22
+ end
23
+ end
24
+
25
+ class RakeTasks
26
+
27
+ attr_reader :gemspec, :modified_files, :git
28
+ attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
29
+
30
+ # Initializes the settings, yields itself for configuration
31
+ # and defines the rake tasks based on the gemspec file.
32
+ def initialize(task_namespace = :gem)
33
+ @gemspec_file = GithubGem.detect_gemspec_file
34
+ @task_namespace = task_namespace
35
+ @main_include = GithubGem.detect_main_include
36
+ @modified_files = []
37
+ @root_dir = Dir.pwd
38
+ @test_pattern = 'test/**/*_test.rb'
39
+ @spec_pattern = 'spec/**/*_spec.rb'
40
+ @local_branch = 'master'
41
+ @remote = 'origin'
42
+ @remote_branch = 'master'
43
+
44
+ yield(self) if block_given?
45
+
46
+ @git = Git.open(@root_dir)
47
+ load_gemspec!
48
+ define_tasks!
49
+ end
50
+
51
+ protected
52
+
53
+ # Define Unit test tasks
54
+ def define_test_tasks!
55
+ require 'rake/testtask'
56
+
57
+ namespace(:test) do
58
+ Rake::TestTask.new(:basic) do |t|
59
+ t.pattern = test_pattern
60
+ t.verbose = true
61
+ t.libs << 'test'
62
+ end
63
+ end
64
+
65
+ desc "Run all unit tests for #{gemspec.name}"
66
+ task(:test => ['test:basic'])
67
+ end
68
+
69
+ # Defines RSpec tasks
70
+ def define_rspec_tasks!
71
+ require 'spec/rake/spectask'
72
+
73
+ namespace(:spec) do
74
+ desc "Verify all RSpec examples for #{gemspec.name}"
75
+ Spec::Rake::SpecTask.new(:basic) do |t|
76
+ t.spec_files = FileList[spec_pattern]
77
+ end
78
+
79
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
80
+ Spec::Rake::SpecTask.new(:specdoc) do |t|
81
+ t.spec_files = FileList[spec_pattern]
82
+ t.spec_opts << '--format' << 'specdoc' << '--color'
83
+ end
84
+
85
+ desc "Run RCov on specs for #{gemspec.name}"
86
+ Spec::Rake::SpecTask.new(:rcov) do |t|
87
+ t.spec_files = FileList[spec_pattern]
88
+ t.rcov = true
89
+ t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
90
+ end
91
+ end
92
+
93
+ desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
94
+ task(:spec => ['spec:specdoc'])
95
+ end
96
+
97
+ # Defines the rake tasks
98
+ def define_tasks!
99
+
100
+ define_test_tasks! if has_tests?
101
+ define_rspec_tasks! if has_specs?
102
+
103
+ namespace(@task_namespace) do
104
+ desc "Updates the filelist in the gemspec file"
105
+ task(:manifest) { manifest_task }
106
+
107
+ desc "Builds the .gem package"
108
+ task(:build => :manifest) { build_task }
109
+
110
+ desc "Sets the version of the gem in the gemspec"
111
+ task(:set_version => [:check_version, :check_current_branch]) { version_task }
112
+ task(:check_version => :fetch_origin) { check_version_task }
113
+
114
+ task(:fetch_origin) { fetch_origin_task }
115
+ task(:check_current_branch) { check_current_branch_task }
116
+ task(:check_clean_status) { check_clean_status_task }
117
+ task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
118
+
119
+ checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
120
+ checks.unshift('spec:basic') if has_specs?
121
+ checks.unshift('test:basic') if has_tests?
122
+ # checks.push << [:check_rubyforge] if gemspec.rubyforge_project
123
+
124
+ desc "Perform all checks that would occur before a release"
125
+ task(:release_checks => checks)
126
+
127
+ release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
128
+ # release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
129
+
130
+ desc "Release a new version of the gem using the VERSION environment variable"
131
+ task(:release => release_tasks) { release_task }
132
+
133
+ namespace(:release) do
134
+ desc "Release the next version of the gem, by incrementing the last version segment by 1"
135
+ task(:next => [:next_version] + release_tasks) { release_task }
136
+
137
+ desc "Release the next version of the gem, using a patch increment (0.0.1)"
138
+ task(:patch => [:next_patch_version] + release_tasks) { release_task }
139
+
140
+ desc "Release the next version of the gem, using a minor increment (0.1.0)"
141
+ task(:minor => [:next_minor_version] + release_tasks) { release_task }
142
+
143
+ desc "Release the next version of the gem, using a major increment (1.0.0)"
144
+ task(:major => [:next_major_version] + release_tasks) { release_task }
145
+ end
146
+
147
+ # task(:check_rubyforge) { check_rubyforge_task }
148
+ # task(:rubyforge_release) { rubyforge_release_task }
149
+ task(:gemcutter_release) { gemcutter_release_task }
150
+ task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
151
+ task(:tag_version) { tag_version_task }
152
+ task(:commit_modified_files) { commit_modified_files_task }
153
+
154
+ task(:next_version) { next_version_task }
155
+ task(:next_patch_version) { next_version_task(:patch) }
156
+ task(:next_minor_version) { next_version_task(:minor) }
157
+ task(:next_major_version) { next_version_task(:major) }
158
+
159
+ desc "Updates the gem release tasks with the latest version on Github"
160
+ task(:update_tasks) { update_tasks_task }
161
+ end
162
+ end
163
+
164
+ # Updates the files list and test_files list in the gemspec file using the list of files
165
+ # in the repository and the spec/test file pattern.
166
+ def manifest_task
167
+ # Load all the gem's files using "git ls-files"
168
+ repository_files = git.ls_files.keys
169
+ test_files = Dir[test_pattern] + Dir[spec_pattern]
170
+
171
+ update_gemspec(:files, repository_files)
172
+ update_gemspec(:test_files, repository_files & test_files)
173
+ end
174
+
175
+ # Builds the gem
176
+ def build_task
177
+ sh "gem build -q #{gemspec_file}"
178
+ Dir.mkdir('pkg') unless File.exist?('pkg')
179
+ sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
180
+ end
181
+
182
+ def newest_version
183
+ git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
184
+ end
185
+
186
+ def next_version(increment = nil)
187
+ next_version = newest_version.segments
188
+ increment_index = case increment
189
+ when :micro then 3
190
+ when :patch then 2
191
+ when :minor then 1
192
+ when :major then 0
193
+ else next_version.length - 1
194
+ end
195
+
196
+ next_version[increment_index] ||= 0
197
+ next_version[increment_index] = next_version[increment_index].succ
198
+ ((increment_index + 1)...next_version.length).each { |i| next_version[i] = 0 }
199
+
200
+ Gem::Version.new(next_version.join('.'))
201
+ end
202
+
203
+ def next_version_task(increment = nil)
204
+ ENV['VERSION'] = next_version(increment).version
205
+ puts "Releasing version #{ENV['VERSION']}..."
206
+ end
207
+
208
+ # Updates the version number in the gemspec file, the VERSION constant in the main
209
+ # include file and the contents of the VERSION file.
210
+ def version_task
211
+ update_gemspec(:version, ENV['VERSION']) if ENV['VERSION']
212
+ update_gemspec(:date, Date.today)
213
+
214
+ update_version_file(gemspec.version)
215
+ update_version_constant(gemspec.version)
216
+ end
217
+
218
+ def check_version_task
219
+ raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
220
+ proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
221
+ raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
222
+ end
223
+
224
+ # Checks whether the current branch is not diverged from the remote branch
225
+ def check_not_diverged_task
226
+ raise "The current branch is diverged from the remote branch!" if git.log.between('HEAD', git.remote(remote).branch(remote_branch).gcommit).any?
227
+ end
228
+
229
+ # Checks whether the repository status ic clean
230
+ def check_clean_status_task
231
+ raise "The current working copy contains modifications" if git.status.changed.any?
232
+ end
233
+
234
+ # Checks whether the current branch is correct
235
+ def check_current_branch_task
236
+ raise "Currently not on #{local_branch} branch!" unless git.branch.name == local_branch.to_s
237
+ end
238
+
239
+ # Fetches the latest updates from Github
240
+ def fetch_origin_task
241
+ git.fetch('origin')
242
+ end
243
+
244
+ # Commits every file that has been changed by the release task.
245
+ def commit_modified_files_task
246
+ if modified_files.any?
247
+ modified_files.each { |file| git.add(file) }
248
+ git.commit("Released #{gemspec.name} gem version #{gemspec.version}")
249
+ end
250
+ end
251
+
252
+ # Adds a tag for the released version
253
+ def tag_version_task
254
+ git.add_tag("#{gemspec.name}-#{gemspec.version}")
255
+ end
256
+
257
+ # Pushes the changes and tag to github
258
+ def github_release_task
259
+ git.push(remote, remote_branch, true)
260
+ end
261
+
262
+ # # Checks whether Rubyforge is configured properly
263
+ # def check_rubyforge_task
264
+ # # Login no longer necessary when using rubyforge 2.0.0 gem
265
+ # # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
266
+ # output = `rubyforge names`.split("\n")
267
+ # raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
268
+ # raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
269
+ # end
270
+
271
+ # # Task to release the .gem file toRubyforge.
272
+ # def rubyforge_release_task
273
+ # sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
274
+ # end
275
+
276
+ def gemcutter_release_task
277
+ sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
278
+ end
279
+
280
+ # Gem release task.
281
+ # All work is done by the task's dependencies, so just display a release completed message.
282
+ def release_task
283
+ puts
284
+ puts '------------------------------------------------------------'
285
+ puts "Released #{gemspec.name} version #{gemspec.version}"
286
+ end
287
+
288
+ private
289
+
290
+ # Checks whether this project has any RSpec files
291
+ def has_specs?
292
+ FileList[spec_pattern].any?
293
+ end
294
+
295
+ # Checks whether this project has any unit test files
296
+ def has_tests?
297
+ FileList[test_pattern].any?
298
+ end
299
+
300
+ # Loads the gemspec file
301
+ def load_gemspec!
302
+ @gemspec = eval(File.read(@gemspec_file))
303
+ end
304
+
305
+ # Updates the VERSION file with the new version
306
+ def update_version_file(version)
307
+ if File.exists?('VERSION')
308
+ File.open('VERSION', 'w') { |f| f << version.to_s }
309
+ modified_files << 'VERSION'
310
+ end
311
+ end
312
+
313
+ # Updates the VERSION constant in the main include file if it exists
314
+ def update_version_constant(version)
315
+ if main_include && File.exist?(main_include)
316
+ file_contents = File.read(main_include)
317
+ if file_contents.sub!(/^(\s+VERSION\s*=\s*)[^\s].*$/) { $1 + version.to_s.inspect }
318
+ File.open(main_include, 'w') { |f| f << file_contents }
319
+ modified_files << main_include
320
+ end
321
+ end
322
+ end
323
+
324
+ # Updates an attribute of the gemspec file.
325
+ # This function will open the file, and search/replace the attribute using a regular expression.
326
+ def update_gemspec(attribute, new_value, literal = false)
327
+
328
+ unless literal
329
+ new_value = case new_value
330
+ when Array then "%w(#{new_value.join(' ')})"
331
+ when Hash, String then new_value.inspect
332
+ when Date then new_value.strftime('%Y-%m-%d').inspect
333
+ else raise "Cannot write value #{new_value.inspect} to gemspec file!"
334
+ end
335
+ end
336
+
337
+ spec = File.read(gemspec_file)
338
+ regexp = Regexp.new('^(\s+\w+\.' + Regexp.quote(attribute.to_s) + '\s*=\s*)[^\s].*$')
339
+ if spec.sub!(regexp) { $1 + new_value }
340
+ File.open(gemspec_file, 'w') { |f| f << spec }
341
+ modified_files << gemspec_file
342
+
343
+ # Reload the gemspec so the changes are incorporated
344
+ load_gemspec!
345
+ end
346
+ end
347
+
348
+ # Updates the tasks file using the latest file found on Github
349
+ def update_tasks_task
350
+ require 'net/http'
351
+
352
+ server = 'github.com'
353
+ path = '/wvanbergen/github-gem/raw/master/tasks/github-gem.rake'
354
+
355
+ Net::HTTP.start(server) do |http|
356
+ response = http.get(path)
357
+ open(__FILE__, "w") { |file| file.write(response.body) }
358
+ end
359
+
360
+ relative_file = File.expand_path(__FILE__).sub(%r[^#{git.dir.path}/], '')
361
+ if git.status[relative_file] && git.status[relative_file].type == 'M'
362
+ git.add(relative_file)
363
+ git.commit("Updated to latest gem release management tasks.")
364
+ puts "Updated to latest version of gem release management tasks."
365
+ else
366
+ puts "Release managament tasks already are at the latest version."
367
+ end
368
+ end
369
+
370
+ end
371
+ end