1
1
require 'rubygems'
2
- require 'bundler'
3
- Bundler . require ( :default , :rake )
4
-
5
2
require 'rake'
6
3
require 'rake/tasklib'
7
4
require 'date'
8
- require 'git '
5
+ require 'set '
9
6
10
7
module GithubGem
11
8
@@ -27,7 +24,7 @@ def self.detect_main_include
27
24
28
25
class RakeTasks
29
26
30
- attr_reader :gemspec , :modified_files , :git
27
+ attr_reader :gemspec , :modified_files
31
28
attr_accessor :gemspec_file , :task_namespace , :main_include , :root_dir , :spec_pattern , :test_pattern , :remote , :remote_branch , :local_branch
32
29
33
30
# Initializes the settings, yields itself for configuration
@@ -36,7 +33,7 @@ def initialize(task_namespace = :gem)
36
33
@gemspec_file = GithubGem . detect_gemspec_file
37
34
@task_namespace = task_namespace
38
35
@main_include = GithubGem . detect_main_include
39
- @modified_files = [ ]
36
+ @modified_files = Set . new
40
37
@root_dir = Dir . pwd
41
38
@test_pattern = 'test/**/*_test.rb'
42
39
@spec_pattern = 'spec/**/*_spec.rb'
@@ -46,13 +43,16 @@ def initialize(task_namespace = :gem)
46
43
47
44
yield ( self ) if block_given?
48
45
49
- @git = Git . open ( @root_dir )
50
46
load_gemspec!
51
47
define_tasks!
52
48
end
53
49
54
50
protected
55
51
52
+ def git
53
+ @git ||= ENV [ 'GIT' ] || 'git'
54
+ end
55
+
56
56
# Define Unit test tasks
57
57
def define_test_tasks!
58
58
require 'rake/testtask'
@@ -71,23 +71,23 @@ def define_test_tasks!
71
71
72
72
# Defines RSpec tasks
73
73
def define_rspec_tasks!
74
- require 'spec/rake/spectask '
74
+ require 'rspec/core/rake_task '
75
75
76
76
namespace ( :spec ) do
77
77
desc "Verify all RSpec examples for #{ gemspec . name } "
78
- Spec :: Rake :: SpecTask . new ( :basic ) do |t |
79
- t . spec_files = FileList [ spec_pattern ]
78
+ RSpec :: Core :: RakeTask . new ( :basic ) do |t |
79
+ t . pattern = spec_pattern
80
80
end
81
81
82
82
desc "Verify all RSpec examples for #{ gemspec . name } and output specdoc"
83
- Spec :: Rake :: SpecTask . new ( :specdoc ) do |t |
84
- t . spec_files = FileList [ spec_pattern ]
85
- t . spec_opts << '--format' << 'specdoc' << '--color'
83
+ RSpec :: Core :: RakeTask . new ( :specdoc ) do |t |
84
+ t . pattern = spec_pattern
85
+ t . rspec_opts = [ '--format' , 'documentation' , '--color' ]
86
86
end
87
87
88
88
desc "Run RCov on specs for #{ gemspec . name } "
89
- Spec :: Rake :: SpecTask . new ( :rcov ) do |t |
90
- t . spec_files = FileList [ spec_pattern ]
89
+ RSpec :: Core :: RakeTask . new ( :rcov ) do |t |
90
+ t . pattern = spec_pattern
91
91
t . rcov = true
92
92
t . rcov_opts = [ '--exclude' , '"spec/*,gems/*"' , '--rails' ]
93
93
end
@@ -122,23 +122,43 @@ def define_tasks!
122
122
checks = [ :check_current_branch , :check_clean_status , :check_not_diverged , :check_version ]
123
123
checks . unshift ( 'spec:basic' ) if has_specs?
124
124
checks . unshift ( 'test:basic' ) if has_tests?
125
- checks . push << [ :check_rubyforge ] if gemspec . rubyforge_project
125
+ # checks.push << [:check_rubyforge] if gemspec.rubyforge_project
126
126
127
127
desc "Perform all checks that would occur before a release"
128
128
task ( :release_checks => checks )
129
129
130
- release_tasks = [ :release_checks , :set_version , :build , :github_release ]
131
- release_tasks << [ :rubyforge_release ] if gemspec . rubyforge_project
130
+ release_tasks = [ :release_checks , :set_version , :build , :github_release , :gemcutter_release ]
131
+ # release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
132
132
133
- desc "Release a new verison of the gem"
133
+ desc "Release a new version of the gem using the VERSION environment variable "
134
134
task ( :release => release_tasks ) { release_task }
135
+
136
+ namespace ( :release ) do
137
+ desc "Release the next version of the gem, by incrementing the last version segment by 1"
138
+ task ( :next => [ :next_version ] + release_tasks ) { release_task }
139
+
140
+ desc "Release the next version of the gem, using a patch increment (0.0.1)"
141
+ task ( :patch => [ :next_patch_version ] + release_tasks ) { release_task }
142
+
143
+ desc "Release the next version of the gem, using a minor increment (0.1.0)"
144
+ task ( :minor => [ :next_minor_version ] + release_tasks ) { release_task }
135
145
136
- task ( :check_rubyforge ) { check_rubyforge_task }
137
- task ( :rubyforge_release ) { rubyforge_release_task }
146
+ desc "Release the next version of the gem, using a major increment (1.0.0)"
147
+ task ( :major => [ :next_major_version ] + release_tasks ) { release_task }
148
+ end
149
+
150
+ # task(:check_rubyforge) { check_rubyforge_task }
151
+ # task(:rubyforge_release) { rubyforge_release_task }
152
+ task ( :gemcutter_release ) { gemcutter_release_task }
138
153
task ( :github_release => [ :commit_modified_files , :tag_version ] ) { github_release_task }
139
154
task ( :tag_version ) { tag_version_task }
140
155
task ( :commit_modified_files ) { commit_modified_files_task }
141
156
157
+ task ( :next_version ) { next_version_task }
158
+ task ( :next_patch_version ) { next_version_task ( :patch ) }
159
+ task ( :next_minor_version ) { next_version_task ( :minor ) }
160
+ task ( :next_major_version ) { next_version_task ( :major ) }
161
+
142
162
desc "Updates the gem release tasks with the latest version on Github"
143
163
task ( :update_tasks ) { update_tasks_task }
144
164
end
@@ -148,7 +168,7 @@ def define_tasks!
148
168
# in the repository and the spec/test file pattern.
149
169
def manifest_task
150
170
# Load all the gem's files using "git ls-files"
151
- repository_files = git . ls_files . keys
171
+ repository_files = ` #{ git } ls-files` . split ( " \n " )
152
172
test_files = Dir [ test_pattern ] + Dir [ spec_pattern ]
153
173
154
174
update_gemspec ( :files , repository_files )
@@ -162,6 +182,32 @@ def build_task
162
182
sh "mv #{ gemspec . name } -#{ gemspec . version } .gem pkg/#{ gemspec . name } -#{ gemspec . version } .gem"
163
183
end
164
184
185
+ def newest_version
186
+ `#{ git } tag` . split ( "\n " ) . map { |tag | tag . split ( '-' ) . last } . compact . map { |v | Gem ::Version . new ( v ) } . max || Gem ::Version . new ( '0.0.0' )
187
+ end
188
+
189
+ def next_version ( increment = nil )
190
+ next_version = newest_version . segments
191
+ increment_index = case increment
192
+ when :micro then 3
193
+ when :patch then 2
194
+ when :minor then 1
195
+ when :major then 0
196
+ else next_version . length - 1
197
+ end
198
+
199
+ next_version [ increment_index ] ||= 0
200
+ next_version [ increment_index ] = next_version [ increment_index ] . succ
201
+ ( ( increment_index + 1 ) ...next_version . length ) . each { |i | next_version [ i ] = 0 }
202
+
203
+ Gem ::Version . new ( next_version . join ( '.' ) )
204
+ end
205
+
206
+ def next_version_task ( increment = nil )
207
+ ENV [ 'VERSION' ] = next_version ( increment ) . version
208
+ puts "Releasing version #{ ENV [ 'VERSION' ] } ..."
209
+ end
210
+
165
211
# Updates the version number in the gemspec file, the VERSION constant in the main
166
212
# include file and the contents of the VERSION file.
167
213
def version_task
@@ -174,70 +220,58 @@ def version_task
174
220
175
221
def check_version_task
176
222
raise "#{ ENV [ 'VERSION' ] } is not a valid version number!" if ENV [ 'VERSION' ] && !Gem ::Version . correct? ( ENV [ 'VERSION' ] )
177
- proposed_version = Gem ::Version . new ( ENV [ 'VERSION' ] || gemspec . version )
178
- # Loads the latest version number using the created tags
179
- newest_version = git . tags . map { |tag | tag . name . split ( '-' ) . last } . compact . map { |v | Gem ::Version . new ( v ) } . max
180
- raise "This version (#{ proposed_version } ) is not higher than the highest tagged version (#{ newest_version } )" if newest_version && newest_version >= proposed_version
223
+ proposed_version = Gem ::Version . new ( ENV [ 'VERSION' ] . dup || gemspec . version )
224
+ raise "This version (#{ proposed_version } ) is not higher than the highest tagged version (#{ newest_version } )" if newest_version >= proposed_version
181
225
end
182
226
183
227
# Checks whether the current branch is not diverged from the remote branch
184
228
def check_not_diverged_task
185
- raise "The current branch is diverged from the remote branch!" if git . log . between ( 'HEAD' , git . remote ( remote ) . branch ( remote_branch ) . gcommit ) . any?
229
+ raise "The current branch is diverged from the remote branch!" if ` #{ git } rev-list HEAD.. #{ remote } / #{ remote_branch } ` . split ( " \n " ) . any?
186
230
end
187
231
188
232
# Checks whether the repository status ic clean
189
233
def check_clean_status_task
190
- raise "The current working copy contains modifications" if git . status . changed . any?
234
+ raise "The current working copy contains modifications" if ` #{ git } ls-files -m` . split ( " \n " ) . any?
191
235
end
192
236
193
237
# Checks whether the current branch is correct
194
238
def check_current_branch_task
195
- raise "Currently not on #{ local_branch } branch!" unless git . branch . name == local_branch . to_s
239
+ raise "Currently not on #{ local_branch } branch!" unless ` #{ git } branch` . split ( " \n " ) . detect { | b | /^ \* / =~ b } == "* #{ local_branch } "
196
240
end
197
241
198
242
# Fetches the latest updates from Github
199
243
def fetch_origin_task
200
- git . fetch ( 'origin' )
244
+ sh git , ' fetch' , remote
201
245
end
202
246
203
247
# Commits every file that has been changed by the release task.
204
248
def commit_modified_files_task
205
- if modified_files . any?
206
- modified_files . each { |file | git . add ( file ) }
207
- git . commit ( "Released #{ gemspec . name } gem version #{ gemspec . version } " )
249
+ really_modified = `#{ git } ls-files -m #{ modified_files . entries . join ( ' ' ) } ` . split ( "\n " )
250
+ if really_modified . any?
251
+ really_modified . each { |file | sh git , 'add' , file }
252
+ sh git , 'commit' , '-m' , "Released #{ gemspec . name } gem version #{ gemspec . version } ."
208
253
end
209
254
end
210
255
211
256
# Adds a tag for the released version
212
257
def tag_version_task
213
- git . add_tag ( "#{ gemspec . name } -#{ gemspec . version } " )
258
+ sh git , 'tag' , '-a' , "#{ gemspec . name } -#{ gemspec . version } " , '-m' , "Released #{ gemspec . name } gem version #{ gemspec . version } ."
214
259
end
215
260
216
261
# Pushes the changes and tag to github
217
262
def github_release_task
218
- git . push ( remote , remote_branch , true )
219
- end
220
-
221
- # Checks whether Rubyforge is configured properly
222
- def check_rubyforge_task
223
- # Login no longer necessary when using rubyforge 2.0.0 gem
224
- # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
225
- output = `rubyforge names` . split ( "\n " )
226
- raise "Rubyforge group not found!" unless output . any? { |line | %r[^groups\s *\: .*\b #{ Regexp . quote ( gemspec . rubyforge_project ) } \b .*] =~ line }
227
- raise "Rubyforge package not found!" unless output . any? { |line | %r[^packages\s *\: .*\b #{ Regexp . quote ( gemspec . name ) } \b .*] =~ line }
263
+ sh git , 'push' , '--tags' , remote , remote_branch
228
264
end
229
265
230
- # Task to release the .gem file toRubyforge.
231
- def rubyforge_release_task
232
- sh 'rubyforge' , 'add_release' , gemspec . rubyforge_project , gemspec . name , gemspec . version . to_s , "pkg/#{ gemspec . name } -#{ gemspec . version } .gem"
266
+ def gemcutter_release_task
267
+ sh "gem" , 'push' , "pkg/#{ gemspec . name } -#{ gemspec . version } .gem"
233
268
end
234
269
235
270
# Gem release task.
236
271
# All work is done by the task's dependencies, so just display a release completed message.
237
272
def release_task
238
273
puts
239
- puts '------------------------------------------------------------'
240
- puts "Released #{ gemspec . name } version #{ gemspec . version } "
274
+ puts "Release successful."
241
275
end
242
276
243
277
private
@@ -297,6 +331,9 @@ def update_gemspec(attribute, new_value, literal = false)
297
331
298
332
# Reload the gemspec so the changes are incorporated
299
333
load_gemspec!
334
+
335
+ # Also mark the Gemfile.lock file as changed because of the new version.
336
+ modified_files << 'Gemfile.lock' if File . exist? ( File . join ( root_dir , 'Gemfile.lock' ) )
300
337
end
301
338
end
302
339
@@ -312,15 +349,13 @@ def update_tasks_task
312
349
open ( __FILE__ , "w" ) { |file | file . write ( response . body ) }
313
350
end
314
351
315
- relative_file = File . expand_path ( __FILE__ ) . sub ( %r[^#{ git . dir . path } /] , '' )
316
- if git . status [ relative_file ] && git . status [ relative_file ] . type == 'M'
317
- git . add ( relative_file )
318
- git . commit ( "Updated to latest gem release management tasks." )
319
- puts "Updated to latest version of gem release management tasks."
352
+ relative_file = File . expand_path ( __FILE__ ) . sub ( %r[^#{ @root_dir } /] , '' )
353
+ if `#{ git } ls-files -m #{ relative_file } ` . split ( "\n " ) . any?
354
+ sh git , 'add' , relative_file
355
+ sh git , 'commit' , '-m' , "Updated to latest gem release management tasks."
320
356
else
321
357
puts "Release managament tasks already are at the latest version."
322
358
end
323
359
end
324
-
325
360
end
326
361
end
0 commit comments