hoe-mercurial 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data.tar.gz.sig +0 -0
  2. data/ChangeLog +143 -0
  3. data/History.md +5 -0
  4. data/README.md +107 -0
  5. data/Rakefile +67 -0
  6. data/lib/hoe/mercurial.rb +626 -0
  7. metadata +131 -0
  8. metadata.gz.sig +0 -0
data.tar.gz.sig ADDED
Binary file
data/ChangeLog ADDED
@@ -0,0 +1,143 @@
1
+ 2010-12-21 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * .hgtags:
4
+ Added tag v1.1.0 for changeset b5258eedbb47
5
+ [e9bdf9672799] [master, tip]
6
+
7
+ * .hgsigs:
8
+ Added signature for changeset 6d0d956a3ada
9
+ [b5258eedbb47] [v1.1.0]
10
+
11
+ * README.md, Rakefile:
12
+ Markdown fixes, README updates, turn on tag-signing.
13
+ [6d0d956a3ada] [github/master]
14
+
15
+ * .hgignore, CHANGELOG.rdoc, History.md, Manifest.txt, README.md,
16
+ README.rdoc, Rakefile, lib/hoe/hg.rb, lib/hoe/mercurial.rb:
17
+ Tabify, finish name-change, split history and changelog, rdoc ->
18
+ Markdown
19
+ [500441aaf812]
20
+
21
+ * README.rdoc, Rakefile, lib/hoe/hg.rb:
22
+ Update the README with fork info, gem name change to hoe-mercurial,
23
+ bugfixes.
24
+ [3aebc113ee1c]
25
+
26
+ 2010-12-14 Michael Granger <ged@FaerieMUD.org>
27
+
28
+ * Rakefile:
29
+ Require the local hoe/hg before loading plugins.
30
+ [66f734138092]
31
+
32
+ 2010-12-13 Michael Granger <ged@FaerieMUD.org>
33
+
34
+ * Rakefile, lib/hoe/hg.rb:
35
+ Hoespec update,
36
+ * Add myself to the developers list, as 'hg churn' says 56% of the
37
+ code is my fault.
38
+ * Move the 'ci' task into the plugin
39
+ * Add a :pre task for making prerelease gems so I can eat my own food
40
+ * Bump hoe dependency to 2.8.0
41
+ * Make the hoe depedency a pessimistic
42
+ * Change versioning to use the semantic versioning standard for tags
43
+ [757913bd6273]
44
+
45
+ 2010-12-10 Michael Granger <ged@FaerieMUD.org>
46
+
47
+ * lib/hoe/hg.rb:
48
+ Only sign if hg_sign_tags is true
49
+ [9401777a9ead]
50
+
51
+ 2010-12-08 Michael Granger <ged@FaerieMUD.org>
52
+
53
+ * Rakefile:
54
+ Default ENV['VERSION']
55
+ [78b1b7a07509]
56
+
57
+ * lib/hoe/hg.rb:
58
+ Fix the tag-extractor function
59
+ [08eb1bdc0a57]
60
+
61
+ * .hgignore, Rakefile, lib/hoe/hg.rb:
62
+ Merging in my Mercurial rake task library.
63
+ * Fixes for 1.9.2
64
+ * Adding tasks for checkin, pull, push, and a (IMO) cleaner release-
65
+ check task, hooked on 'prerelease' instead of 'release_sanity', as
66
+ there are circumstances in which you might want to release with
67
+ outstanding changes (e.g., preprelease gems)
68
+ [e875bbbdfc06]
69
+
70
+ 2010-01-15 mml <mml>
71
+
72
+ * .hgtags:
73
+ tagging r1.0.5 for release
74
+ [0f0b88dd5cba]
75
+
76
+ * CHANGELOG.rdoc, Rakefile, lib/hoe/hg.rb:
77
+ updated changelog & bumprev
78
+ [385c3a28eb3d] [r1.0.5]
79
+
80
+ * CHANGELOG.rdoc, README.rdoc:
81
+ bumped rev
82
+ [0a9a4b6d25c9]
83
+
84
+ * lib/hoe/hg.rb:
85
+ bumped rev
86
+ [1e6d706b5749]
87
+
88
+ * Rakefile:
89
+ removed auto-set of VER
90
+ [02a6bde36a66]
91
+
92
+ * .hgtags:
93
+ tagging r1.0.3 for release
94
+ [e44ecb58aeee]
95
+
96
+ * CHANGELOG.rdoc, lib/hoe/hg.rb:
97
+ fixie
98
+ [18c33e15c18b] [r1.0.3]
99
+
100
+ * Rakefile, lib/hoe/hg.rb:
101
+ more updates
102
+ [ced484fa5698]
103
+
104
+ * .hgtags:
105
+ tagging r1.0.1 for release
106
+ [af15ccec537a]
107
+
108
+ * .hgtags:
109
+ tagging r1.0.0 for release
110
+ [4597b7507145] [r1.0.1]
111
+
112
+ * README.rdoc, lib/hoe/hg.rb:
113
+ fixed sanity check
114
+ [b687d8a8393e] [r1.0.0]
115
+
116
+ * CHANGELOG.rdoc:
117
+ changelog update
118
+ [c9ab41f8f4f3]
119
+
120
+ * CHANGELOG.rdoc, lib/hoe/hg.rb:
121
+ removed changelog generation stuff.
122
+ [1da95eeab61b]
123
+
124
+ * .hgignore, Manifest.txt, Rakefile, lib/hoe/hg.rb:
125
+ removed some comments, ported sanity
126
+ [64235fa1b635]
127
+
128
+ * Manifest.txt, lib/hoe/hg.rb:
129
+ ported to use hg
130
+ [44e73e6cc634]
131
+
132
+ * .hgtags:
133
+ Removed tag bar
134
+ [48ae61cd50eb]
135
+
136
+ * .hgtags:
137
+ Added tag bar for changeset 5163b27315b4
138
+ [c2cd50b7e784]
139
+
140
+ * .hgignore, CHANGELOG.rdoc, Manifest.txt, README.rdoc, Rakefile,
141
+ lib/hoe/hg.rb:
142
+ r1
143
+ [5163b27315b4]
data/History.md ADDED
@@ -0,0 +1,5 @@
1
+
2
+ ## 1.1.0 [2010-12-14] Michael Granger <ged@FaerieMUD.org>
3
+
4
+ Initial release after forking from hoe-hg.
5
+
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # (Another) Mercurial Plugin for hoe
2
+
3
+ * http://bitbucket.org/ged/hoe-mercurial
4
+
5
+
6
+ ## Description
7
+
8
+ This is a fork of the [hoe-hg](https://bitbucket.org/mml/hoe-hg)
9
+ plugin. I forked it because I use quite a few additional Mercurial
10
+ tasks for my development workflow than are provided by the original,
11
+ and I thought they'd possibly be useful to someone else.
12
+
13
+ I've offered to push my changes back up to the original, but I gave
14
+ up waiting for a response.
15
+
16
+
17
+ ## Examples
18
+
19
+ # in your Rakefile
20
+ Hoe.plugin :mercurial
21
+
22
+ If there isn't a '.hg' directory at the root of your project, it won't
23
+ be activated.
24
+
25
+
26
+ ### Committing
27
+
28
+ $ rake hg:checkin
29
+
30
+ -or-
31
+
32
+ $ rake ci
33
+
34
+ This will offer to pull and merge from the default repo (if there is one),
35
+ check for any unregistered files and offer to add/ignore/delete or
36
+ temporarily skip them, run the **:precheckin** task (which you can use to
37
+ run tests, lint, or whatever before checking in), builds a commit message
38
+ file out of the diff that's being committed and invokes your editor on it,
39
+ does the checkin, then offers to push back to the default repo.
40
+
41
+ ### Pre-Release Hook
42
+
43
+ This plugin also hooks Hoe's **prerelease** task to tag and (optionally) sign
44
+ the rev being released, then push to the default repo. If there are any
45
+ uncommitted files, it also verifies that you want to release with
46
+ uncommitted changes, and ensures you've bumped the version number by
47
+ checking for an existing tag with the same version.
48
+
49
+ To sign tagged revisions using 'hg sign', do this in your hoespec:
50
+
51
+ self.hg_sign_tags = true
52
+
53
+ This requires that 'hg sign' work on its own, of course.
54
+
55
+
56
+ ### Other Tasks
57
+
58
+ It also provides other tasks for pulling, updating, pushing, etc. These
59
+ aren't very useful on their own, as it's usually just as easy to do the
60
+ same thing yourself with 'hg', but they're intended to be used as
61
+ dependencies in other tasks.
62
+
63
+ A 'rake -T' will show them all; they're all in the 'hg' namespace.
64
+
65
+
66
+ ## Dependencies
67
+
68
+ Hoe and Mercurial, obviously. I haven't tested these tasks with Mercurial
69
+ versions earlier than 1.6 or so.
70
+
71
+
72
+ ## Installation
73
+
74
+ $ gem install hoe-mercurial
75
+
76
+
77
+ ## License
78
+
79
+ The original is used under the terms of the following license:
80
+
81
+ Copyright 2009 McClain Looney (m@loonsoft.com)
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining
84
+ a copy of this software and associated documentation files (the
85
+ 'Software'), to deal in the Software without restriction, including
86
+ without limitation the rights to use, copy, modify, merge, publish,
87
+ distribute, sublicense, and/or sell copies of the Software, and to
88
+ permit persons to whom the Software is furnished to do so, subject to
89
+ the following conditions:
90
+
91
+ The above copyright notice and this permission notice shall be
92
+ included in all copies or substantial portions of the Software.
93
+
94
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
95
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
96
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
97
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
98
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
99
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
100
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
101
+
102
+ My modifications are:
103
+
104
+ Copyright © 2010 Michael Granger <ged@FaerieMUD.org>
105
+
106
+ and are licensed under the same terms as the original.
107
+
data/Rakefile ADDED
@@ -0,0 +1,67 @@
1
+ #!rake
2
+ #encoding: utf-8
3
+
4
+ require 'hoe'
5
+ require 'rake/clean'
6
+
7
+ # 1.9.2 and later require explicit relative require
8
+ if defined?( require_relative )
9
+ $stderr.puts "Requiring relative lib/hoe/mercurial..."
10
+ require_relative "lib/hoe/mercurial"
11
+ $stderr.puts " require done."
12
+ else
13
+ $LOAD_PATH.unshift( 'lib' )
14
+ require 'hoe/mercurial'
15
+ end
16
+
17
+
18
+ Hoe.plugin :mercurial
19
+ Hoe.plugin :signing
20
+
21
+ Hoe.plugins.delete :rubyforge
22
+
23
+ ### Main spec
24
+ hoespec = Hoe.spec "hoe-mercurial" do
25
+ developer "Michael Granger", "ged@FaerieMUD.org"
26
+
27
+ self.extra_rdoc_files = FileList["*.rdoc"]
28
+ self.history_file = "History.md"
29
+ self.readme_file = "README.md"
30
+
31
+ self.hg_sign_tags = true
32
+
33
+ extra_deps << ["hoe", "~> 2.8.0"]
34
+ end
35
+
36
+
37
+ include Hoe::MercurialHelpers
38
+
39
+ ### Task: prerelease
40
+ desc "Append the package build number to package versions"
41
+ task :pre do
42
+ rev = get_numeric_rev()
43
+ trace "Current rev is: %p" % [ rev ]
44
+ hoespec.spec.version.version << "pre#{rev}"
45
+ Rake::Task[:gem].clear
46
+
47
+ Gem::PackageTask.new( hoespec.spec ) do |pkg|
48
+ pkg.need_zip = true
49
+ pkg.need_tar = true
50
+ end
51
+ end
52
+
53
+
54
+ ### Make the ChangeLog update if the repo has changed since it was last built
55
+ file '.hg/branch'
56
+ file 'ChangeLog' => '.hg/branch' do |task|
57
+ log "Updating the changelog..."
58
+ content = make_changelog()
59
+ File.open( task.name, 'w', 0644 ) do |fh|
60
+ fh.print( content )
61
+ end
62
+ end
63
+
64
+ # Rebuild the ChangeLog immediately before release
65
+ task :prerelease => 'ChangeLog'
66
+
67
+
@@ -0,0 +1,626 @@
1
+ #!/usr/bin/env ruby
2
+ #coding: utf-8
3
+
4
+ require 'pathname'
5
+ require 'shellwords'
6
+ require 'fileutils'
7
+ require 'rake/clean'
8
+
9
+ begin
10
+ require 'readline'
11
+ include Readline
12
+ rescue LoadError
13
+ # Fall back to a plain prompt
14
+ def readline( text )
15
+ $stderr.print( text.chomp )
16
+ return $stdin.gets
17
+ end
18
+ end
19
+
20
+ class Hoe
21
+
22
+ ### Prompting, command-execution, and other utility functions
23
+ module RakeHelpers
24
+
25
+ # The editor to invoke if ENV['EDITOR'] and ENV['VISUAL'] aren't set.
26
+ DEFAULT_EDITOR = 'vi'
27
+
28
+ # Set some ANSI escape code constants (Shamelessly stolen from Perl's
29
+ # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
30
+ ANSI_ATTRIBUTES = {
31
+ 'clear' => 0,
32
+ 'reset' => 0,
33
+ 'bold' => 1,
34
+ 'dark' => 2,
35
+ 'underline' => 4,
36
+ 'underscore' => 4,
37
+ 'blink' => 5,
38
+ 'reverse' => 7,
39
+ 'concealed' => 8,
40
+
41
+ 'black' => 30, 'on_black' => 40,
42
+ 'red' => 31, 'on_red' => 41,
43
+ 'green' => 32, 'on_green' => 42,
44
+ 'yellow' => 33, 'on_yellow' => 43,
45
+ 'blue' => 34, 'on_blue' => 44,
46
+ 'magenta' => 35, 'on_magenta' => 45,
47
+ 'cyan' => 36, 'on_cyan' => 46,
48
+ 'white' => 37, 'on_white' => 47
49
+ }
50
+
51
+ # Prompt for multiline input
52
+ MULTILINE_PROMPT = <<-'EOF'
53
+ Enter one or more values for '%s'.
54
+ A blank line finishes input.
55
+ EOF
56
+
57
+ # ANSI escapes for clearing to the end of the line and the entire line
58
+ CLEAR_TO_EOL = "\e[K"
59
+ CLEAR_CURRENT_LINE = "\e[2K"
60
+
61
+
62
+ ###############
63
+ module_function
64
+ ###############
65
+
66
+ ### Create a string that contains the ANSI codes specified and return it
67
+ def ansi_code( *attributes )
68
+ attributes.flatten!
69
+ attributes.collect! {|at| at.to_s }
70
+ # $stderr.puts "Returning ansicode for TERM = %p: %p" %
71
+ # [ ENV['TERM'], attributes ]
72
+ return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
73
+ attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
74
+
75
+ # $stderr.puts " attr is: %p" % [attributes]
76
+ if attributes.empty?
77
+ return ''
78
+ else
79
+ return "\e[%sm" % attributes
80
+ end
81
+ end
82
+
83
+
84
+ ### Colorize the given +string+ with the specified +attributes+ and return it, handling
85
+ ### line-endings, color reset, etc.
86
+ def colorize( *args )
87
+ string = ''
88
+
89
+ if block_given?
90
+ string = yield
91
+ else
92
+ string = args.shift
93
+ end
94
+
95
+ ending = string[/(\s)$/] || ''
96
+ string = string.rstrip
97
+
98
+ return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
99
+ end
100
+
101
+
102
+ ### Output the specified <tt>msg</tt> as an ANSI-colored error message
103
+ ### (white on red).
104
+ def error_message( msg, details='' )
105
+ $stderr.puts colorize( 'bold', 'white', 'on_red' ) { msg } + details
106
+ end
107
+ alias :error :error_message
108
+
109
+
110
+ ### Make a prompt string that will always appear flush left.
111
+ def make_prompt_string( string )
112
+ return CLEAR_CURRENT_LINE + colorize( 'bold', 'green' ) { string + ' ' }
113
+ end
114
+
115
+
116
+ ### Output the specified <tt>prompt_string</tt> as a prompt (in green) and
117
+ ### return the user's input with leading and trailing spaces removed. If a
118
+ ### test is provided, the prompt will repeat until the test returns true.
119
+ ### An optional failure message can also be passed in.
120
+ def prompt( prompt_string, failure_msg="Try again." ) # :yields: response
121
+ prompt_string.chomp!
122
+ prompt_string << ":" unless /\W$/.match( prompt_string )
123
+ response = nil
124
+
125
+ begin
126
+ prompt = make_prompt_string( prompt_string )
127
+ response = readline( prompt ) || ''
128
+ response.strip!
129
+ if block_given? && ! yield( response )
130
+ error_message( failure_msg + "\n\n" )
131
+ response = nil
132
+ end
133
+ end while response.nil?
134
+
135
+ return response
136
+ end
137
+
138
+
139
+ ### Prompt the user with the given <tt>prompt_string</tt> via #prompt,
140
+ ### substituting the given <tt>default</tt> if the user doesn't input
141
+ ### anything. If a test is provided, the prompt will repeat until the test
142
+ ### returns true. An optional failure message can also be passed in.
143
+ def prompt_with_default( prompt_string, default, failure_msg="Try again." )
144
+ response = nil
145
+
146
+ begin
147
+ default ||= '~'
148
+ response = prompt( "%s [%s]" % [ prompt_string, default ] )
149
+ response = default.to_s if !response.nil? && response.empty?
150
+
151
+ trace "Validating response %p" % [ response ]
152
+
153
+ # the block is a validator. We need to make sure that the user didn't
154
+ # enter '~', because if they did, it's nil and we should move on. If
155
+ # they didn't, then call the block.
156
+ if block_given? && response != '~' && ! yield( response )
157
+ error_message( failure_msg + "\n\n" )
158
+ response = nil
159
+ end
160
+ end while response.nil?
161
+
162
+ return nil if response == '~'
163
+ return response
164
+ end
165
+
166
+
167
+ ### Prompt for an array of values
168
+ def prompt_for_multiple_values( label, default=nil )
169
+ $stderr.puts( MULTILINE_PROMPT % [label] )
170
+ if default
171
+ $stderr.puts "Enter a single blank line to keep the default:\n %p" % [ default ]
172
+ end
173
+
174
+ results = []
175
+ result = nil
176
+
177
+ begin
178
+ result = readline( make_prompt_string("> ") )
179
+ if result.nil? || result.empty?
180
+ results << default if default && results.empty?
181
+ else
182
+ results << result
183
+ end
184
+ end until result.nil? || result.empty?
185
+
186
+ return results.flatten
187
+ end
188
+
189
+
190
+ ### Display a description of a potentially-dangerous task, and prompt
191
+ ### for confirmation. If the user answers with anything that begins
192
+ ### with 'y', yield to the block. If +abort_on_decline+ is +true+,
193
+ ### any non-'y' answer will fail with an error message.
194
+ def ask_for_confirmation( description, abort_on_decline=true )
195
+ prompt = 'Continue?'
196
+
197
+ # If the description looks like a question, use it for the prompt. Otherwise,
198
+ # print it out and
199
+ if description.strip.rindex( '?' )
200
+ prompt = description
201
+ else
202
+ log description
203
+ end
204
+
205
+ answer = prompt_with_default( prompt, 'n' ) do |input|
206
+ input =~ /^[yn]/i
207
+ end
208
+
209
+ if answer =~ /^y/i
210
+ return yield
211
+ elsif abort_on_decline
212
+ error "Aborted."
213
+ fail
214
+ end
215
+
216
+ return false
217
+ end
218
+ alias :prompt_for_confirmation :ask_for_confirmation
219
+
220
+
221
+ ### Output a logging message
222
+ def log( *msg )
223
+ output = colorize( msg.flatten.join(' '), 'cyan' )
224
+ $stderr.puts( output )
225
+ end
226
+
227
+
228
+ ### Output a logging message if tracing is on
229
+ def trace( *msg )
230
+ return unless Rake.application.options.trace
231
+ output = colorize( msg.flatten.join(' '), 'yellow' )
232
+ $stderr.puts( output )
233
+ end
234
+
235
+
236
+ ### Return the specified args as a string, quoting any that have a space.
237
+ def quotelist( *args )
238
+ return args.flatten.collect {|part| part =~ /\s/ ? part.inspect : part}
239
+ end
240
+
241
+
242
+ ### Run the specified command +cmd+ with system(), failing if the execution
243
+ ### fails. Doesn't invoke a subshell (unlike 'sh').
244
+ def run( *cmd )
245
+ cmd.flatten!
246
+
247
+ if cmd.length > 1
248
+ trace( "Running:", quotelist(*cmd) )
249
+ else
250
+ trace( "Running:", cmd )
251
+ end
252
+
253
+ if Rake.application.options.dryrun
254
+ log "(dry run mode)"
255
+ else
256
+ system( *cmd )
257
+ unless $?.success?
258
+ fail "Command failed: [%s]" % [cmd.join(' ')]
259
+ end
260
+ end
261
+ end
262
+
263
+
264
+ ### Invoke the user's editor on the given +filename+ and return the exit code
265
+ ### from doing so.
266
+ def edit( filename )
267
+ editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR
268
+ system editor, filename
269
+ unless $?.success? || editor =~ /vim/i
270
+ fail "Editor exited uncleanly."
271
+ end
272
+ end
273
+
274
+
275
+ ### Run the given +cmd+ with the specified +args+ without interpolation by the shell and
276
+ ### return anything written to its STDOUT.
277
+ def read_command_output( cmd, *args )
278
+ # output = IO.read( '|-' ) or exec cmd, *args # No popen on some platforms. :(
279
+ argstr = Shellwords.join( args )
280
+ output = `#{cmd} #{argstr}`.chomp
281
+ return output
282
+ end
283
+
284
+
285
+ ### Extract all the non Rake-target arguments from ARGV and return them.
286
+ def get_target_args
287
+ args = ARGV.reject {|arg| arg =~ /^-/ || Rake::Task.task_defined?(arg) }
288
+ return args
289
+ end
290
+
291
+
292
+ ### Returns a human-scannable file list by joining and truncating the list if it's too long.
293
+ def humanize_file_list( list, indent=FILE_INDENT )
294
+ listtext = list[0..5].join( "\n#{indent}" )
295
+ if list.length > 5
296
+ listtext << " (and %d other/s)" % [ list.length - 5 ]
297
+ end
298
+
299
+ return listtext
300
+ end
301
+
302
+ end # module RakeHelpers
303
+
304
+
305
+ ### Mercurial command wrapper functions.
306
+ module MercurialHelpers
307
+ include FileUtils,
308
+ Hoe::RakeHelpers
309
+ include FileUtils::DryRun if Rake.application.options.dryrun
310
+
311
+ # The name of the ignore file
312
+ IGNORE_FILE = Pathname( '.hgignore' )
313
+
314
+
315
+ ### Generate a commit log from a diff and return it as a String. At the moment it just
316
+ ### returns the diff as-is, but will (someday) do something better.
317
+ def make_commit_log
318
+ diff = read_command_output( 'hg', 'diff' )
319
+ fail "No differences." if diff.empty?
320
+
321
+ return diff
322
+ end
323
+
324
+
325
+ ### Generate a commit log and invoke the user's editor on it.
326
+ def edit_commit_log( logfile )
327
+ diff = make_commit_log()
328
+
329
+ File.open( logfile, 'w' ) do |fh|
330
+ fh.print( diff )
331
+ end
332
+
333
+ edit( logfile )
334
+ end
335
+
336
+
337
+ ### Generate a changelog.
338
+ def make_changelog
339
+ log = read_command_output( 'hg', 'log', '--style', 'changelog' )
340
+ return log
341
+ end
342
+
343
+
344
+ def get_manifest
345
+ raw = read_command_output( 'hg', 'manifest' )
346
+ return raw.split( $/ )
347
+ end
348
+
349
+
350
+ ### Get the 'tip' info and return it as a Hash
351
+ def get_tip_info
352
+ data = read_command_output( 'hg', 'tip' )
353
+ return YAML.load( data )
354
+ end
355
+
356
+
357
+ ### Return the ID for the current rev
358
+ def get_current_rev
359
+ id = read_command_output( 'hg', '-q', 'identify' )
360
+ return id.chomp
361
+ end
362
+
363
+
364
+ ### Return the current numeric (local) rev number
365
+ def get_numeric_rev
366
+ id = read_command_output( 'hg', '-q', 'identify', '-n' )
367
+ return id.chomp[ /^(\d+)/, 1 ] || '0'
368
+ end
369
+
370
+
371
+ ### Read the list of existing tags and return them as an Array
372
+ def get_tags
373
+ taglist = read_command_output( 'hg', 'tags' )
374
+ return taglist.split( /\n/ ).collect {|tag| tag[/^\S+/] }
375
+ end
376
+
377
+
378
+ ### Read any remote repo paths known by the current repo and return them as a hash.
379
+ def get_repo_paths
380
+ paths = {}
381
+ pathspec = read_command_output( 'hg', 'paths' )
382
+ pathspec.split.each_slice( 3 ) do |name, _, url|
383
+ paths[ name ] = url
384
+ end
385
+ return paths
386
+ end
387
+
388
+
389
+ ### Return the list of files which are not of status 'clean'
390
+ def get_uncommitted_files
391
+ list = read_command_output( 'hg', 'status', '-n', '--color', 'never' )
392
+ list = list.split( /\n/ )
393
+
394
+ trace "Changed files: %p" % [ list ]
395
+ return list
396
+ end
397
+
398
+
399
+ ### Return the list of files which are of status 'unknown'
400
+ def get_unknown_files
401
+ list = read_command_output( 'hg', 'status', '-un', '--color', 'never' )
402
+ list = list.split( /\n/ )
403
+
404
+ trace "New files: %p" % [ list ]
405
+ return list
406
+ end
407
+
408
+
409
+ ### Add the list of +pathnames+ to the .hgignore list.
410
+ def hg_ignore_files( *pathnames )
411
+ patterns = pathnames.flatten.collect do |path|
412
+ '^' + Regexp.escape(path) + '$'
413
+ end
414
+ trace "Ignoring %d files." % [ pathnames.length ]
415
+
416
+ IGNORE_FILE.open( File::CREAT|File::WRONLY|File::APPEND, 0644 ) do |fh|
417
+ fh.puts( patterns )
418
+ end
419
+ end
420
+
421
+
422
+ ### Delete the files in the given +filelist+ after confirming with the user.
423
+ def delete_extra_files( filelist )
424
+ description = humanize_file_list( filelist, ' ' )
425
+ log "Files to delete:\n ", description
426
+ ask_for_confirmation( "Really delete them?", false ) do
427
+ filelist.each do |f|
428
+ rm_rf( f, :verbose => true )
429
+ end
430
+ end
431
+ end
432
+
433
+ end # module MercurialHelpers
434
+
435
+
436
+
437
+ module Mercurial
438
+ include Hoe::RakeHelpers,
439
+ Hoe::MercurialHelpers
440
+
441
+ VERSION = "1.1.0"
442
+
443
+ # The name of the file to edit for the commit message
444
+ COMMIT_MSG_FILE = 'commit-msg.txt'
445
+
446
+ attr_accessor :hg_release_tag_prefix
447
+ attr_accessor :hg_repo, :hg_release_branch
448
+ attr_accessor :hg_sign_tags
449
+
450
+
451
+ ### Set up defaults
452
+ def initialize_mercurial
453
+ # Follow semantic versioning tagging specification (http://semver.org/)
454
+ self.hg_release_tag_prefix = "v"
455
+ self.hg_release_branch = "default"
456
+ self.hg_sign_tags = false
457
+ end
458
+
459
+
460
+ ### Hoe hook -- Define Rake tasks when the plugin is loaded.
461
+ def define_mercurial_tasks
462
+ return unless File.exist? ".hg"
463
+
464
+ file COMMIT_MSG_FILE do |task|
465
+ edit_commit_log( task.name )
466
+ end
467
+
468
+ namespace :hg do
469
+
470
+ desc "Prepare for a new release"
471
+ task :prep_release do
472
+ uncommitted_files = get_uncommitted_files()
473
+ unless uncommitted_files.empty?
474
+ log "Uncommitted files:\n",
475
+ *uncommitted_files.map {|fn| " #{fn}\n" }
476
+ ask_for_confirmation( "\nRelease anyway?", true ) do
477
+ log "Okay, releasing with uncommitted versions."
478
+ end
479
+ end
480
+
481
+ tags = get_tags()
482
+ rev = get_current_rev()
483
+ pkg_version_tag = "#{hg_release_tag_prefix}#{version}"
484
+
485
+ # Look for a tag for the current release version, and if it exists abort
486
+ if tags.include?( pkg_version_tag )
487
+ error "Version #{version} already has a tag."
488
+ fail
489
+ end
490
+
491
+ # Sign the current rev
492
+ if self.hg_sign_tags
493
+ log "Signing rev #{rev}"
494
+ run 'hg', 'sign'
495
+ end
496
+
497
+ # Tag the current rev
498
+ log "Tagging rev #{rev} as #{pkg_version_tag}"
499
+ run 'hg', 'tag', pkg_version_tag
500
+
501
+ # Offer to push
502
+ Rake::Task['hg:push'].invoke
503
+ end
504
+
505
+
506
+ desc "Check for new files and offer to add/ignore/delete them."
507
+ task :newfiles do
508
+ log "Checking for new files..."
509
+
510
+ entries = get_unknown_files()
511
+
512
+ unless entries.empty?
513
+ files_to_add = []
514
+ files_to_ignore = []
515
+ files_to_delete = []
516
+
517
+ entries.each do |entry|
518
+ action = prompt_with_default( " #{entry}: (a)dd, (i)gnore, (s)kip (d)elete", 's' )
519
+ case action
520
+ when 'a'
521
+ files_to_add << entry
522
+ when 'i'
523
+ files_to_ignore << entry
524
+ when 'd'
525
+ files_to_delete << entry
526
+ end
527
+ end
528
+
529
+ unless files_to_add.empty?
530
+ run 'hg', 'add', *files_to_add
531
+ end
532
+
533
+ unless files_to_ignore.empty?
534
+ hg_ignore_files( *files_to_ignore )
535
+ end
536
+
537
+ unless files_to_delete.empty?
538
+ delete_extra_files( files_to_delete )
539
+ end
540
+ end
541
+ end
542
+ task :add => :newfiles
543
+
544
+
545
+ desc "Pull and update from the default repo"
546
+ task :pull do
547
+ paths = get_repo_paths()
548
+ if origin_url = paths['default']
549
+ ask_for_confirmation( "Pull and update from '#{origin_url}'?", false ) do
550
+ Rake::Task['hg:pull_without_confirmation'].invoke
551
+ end
552
+ else
553
+ trace "Skipping pull: No 'default' path."
554
+ end
555
+ end
556
+
557
+
558
+ desc "Pull and update without confirmation"
559
+ task :pull_without_confirmation do
560
+ run 'hg', 'pull', '-u'
561
+ end
562
+
563
+
564
+ desc "Update to tip"
565
+ task :update do
566
+ run 'hg', 'update'
567
+ end
568
+
569
+
570
+ desc "Clobber all changes (hg up -C)"
571
+ task :update_and_clobber do
572
+ run 'hg', 'update', '-C'
573
+ end
574
+
575
+
576
+ task :precheckin do
577
+ trace "Pre-checkin hooks"
578
+ end
579
+
580
+
581
+ desc "Check the current code in if tests pass"
582
+ task :checkin => ['hg:pull', 'hg:newfiles', :precheckin, COMMIT_MSG_FILE] do
583
+ targets = get_target_args()
584
+ $stderr.puts '---', File.read( COMMIT_MSG_FILE ), '---'
585
+ ask_for_confirmation( "Continue with checkin?" ) do
586
+ run 'hg', 'ci', '-l', COMMIT_MSG_FILE, targets
587
+ rm_f COMMIT_MSG_FILE
588
+ end
589
+ Rake::Task['hg:push'].invoke
590
+ end
591
+ task :commit => :checkin
592
+ task :ci => :checkin
593
+
594
+ CLEAN.include( COMMIT_MSG_FILE )
595
+
596
+ desc "Push to the default origin repo (if there is one)"
597
+ task :push do
598
+ paths = get_repo_paths()
599
+ if origin_url = paths['default']
600
+ ask_for_confirmation( "Push to '#{origin_url}'?", false ) do
601
+ Rake::Task['hg:push_without_confirmation'].invoke
602
+ end
603
+ else
604
+ trace "Skipping push: No 'default' path."
605
+ end
606
+ end
607
+
608
+ desc "Push to the default repo without confirmation"
609
+ task :push_without_confirmation do
610
+ run 'hg', 'push'
611
+ end
612
+ end
613
+
614
+ # Add a top-level 'ci' task for checkin
615
+ task :ci => 'hg:checkin'
616
+
617
+ # Hook the release task and prep the repo first
618
+ task :prerelease => 'hg:prep_release'
619
+
620
+ rescue Exception => err
621
+ $stderr.puts "%s while defining Mercurial tasks: %s" % [ err.class.name, err.message ]
622
+ raise
623
+ end
624
+
625
+ end
626
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hoe-mercurial
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 0
10
+ version: 1.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Michael Granger
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDLDCCAhSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANnZWQx
20
+ FzAVBgoJkiaJk/IsZAEZFgdfYWVyaWVfMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4X
21
+ DTEwMDkxNjE0NDg1MVoXDTExMDkxNjE0NDg1MVowPDEMMAoGA1UEAwwDZ2VkMRcw
22
+ FQYKCZImiZPyLGQBGRYHX2FlcmllXzETMBEGCgmSJomT8ixkARkWA29yZzCCASIw
23
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy//BFxC1f/cPSnwtJBWoFiFrir
24
+ h7RicI+joq/ocVXQqI4TDWPyF/8tqkvt+rD99X9qs2YeR8CU/YiIpLWrQOYST70J
25
+ vDn7Uvhb2muFVqq6+vobeTkILBEO6pionWDG8jSbo3qKm1RjKJDwg9p4wNKhPuu8
26
+ KGue/BFb67KflqyApPmPeb3Vdd9clspzqeFqp7cUBMEpFS6LWxy4Gk+qvFFJBJLB
27
+ BUHE/LZVJMVzfpC5Uq+QmY7B+FH/QqNndn3tOHgsPadLTNimuB1sCuL1a4z3Pepd
28
+ TeLBEFmEao5Dk3K/Q8o8vlbIB/jBDTUx6Djbgxw77909x6gI9doU4LD5XMcCAwEA
29
+ AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJeoGkOr9l4B
30
+ +saMkW/ZXT4UeSvVMA0GCSqGSIb3DQEBBQUAA4IBAQBG2KObvYI2eHyyBUJSJ3jN
31
+ vEnU3d60znAXbrSd2qb3r1lY1EPDD3bcy0MggCfGdg3Xu54z21oqyIdk8uGtWBPL
32
+ HIa9EgfFGSUEgvcIvaYqiN4jTUtidfEFw+Ltjs8AP9gWgSIYS6Gr38V0WGFFNzIH
33
+ aOD2wmu9oo/RffW4hS/8GuvfMzcw7CQ355wFR4KB/nyze+EsZ1Y5DerCAagMVuDQ
34
+ U0BLmWDFzPGGWlPeQCrYHCr+AcJz+NRnaHCKLZdSKj/RHuTOt+gblRex8FAh8NeA
35
+ cmlhXe46pZNJgWKbxZah85jIjx95hR8vOI+NAM5iH9kOqK13DrxacTKPhqj5PjwF
36
+ -----END CERTIFICATE-----
37
+
38
+ date: 2010-12-21 00:00:00 -08:00
39
+ default_executable:
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: hoe
43
+ prerelease: false
44
+ requirement: &id001 !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ hash: 47
50
+ segments:
51
+ - 2
52
+ - 8
53
+ - 0
54
+ version: 2.8.0
55
+ type: :runtime
56
+ version_requirements: *id001
57
+ - !ruby/object:Gem::Dependency
58
+ name: hoe
59
+ prerelease: false
60
+ requirement: &id002 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 47
66
+ segments:
67
+ - 2
68
+ - 8
69
+ - 0
70
+ version: 2.8.0
71
+ type: :development
72
+ version_requirements: *id002
73
+ description: |-
74
+ This is a fork of the [hoe-hg](https://bitbucket.org/mml/hoe-hg)
75
+ plugin. I forked it because I use quite a few additional Mercurial
76
+ tasks for my development workflow than are provided by the original,
77
+ and I thought they'd possibly be useful to someone else.
78
+
79
+ I've offered to push my changes back up to the original, but I gave
80
+ up waiting for a response.
81
+ email:
82
+ - ged@FaerieMUD.org
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files: []
88
+
89
+ files:
90
+ - lib/hoe/mercurial.rb
91
+ - ChangeLog
92
+ - History.md
93
+ - README.md
94
+ - Rakefile
95
+ has_rdoc: true
96
+ homepage: http://bitbucket.org/ged/hoe-mercurial
97
+ licenses: []
98
+
99
+ post_install_message:
100
+ rdoc_options:
101
+ - --main
102
+ - README.md
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirements: []
124
+
125
+ rubyforge_project: hoe-mercurial
126
+ rubygems_version: 1.3.7
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: This is a fork of the [hoe-hg](https://bitbucket.org/mml/hoe-hg) plugin
130
+ test_files: []
131
+
metadata.gz.sig ADDED
Binary file