bluecloth 2.0.10 → 2.0.11pre158

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gemtest +0 -0
  3. data/History.md +4 -0
  4. data/LICENSE +1 -1
  5. data/Manifest.txt +103 -0
  6. data/README.md +103 -0
  7. data/Rakefile +95 -324
  8. data/ext/VERSION +1 -1
  9. data/ext/bluecloth.c +1 -1
  10. data/ext/bluecloth.h +1 -1
  11. data/ext/extconf.rb +7 -9
  12. data/ext/generate.c +5 -6
  13. data/ext/markdown.c +12 -8
  14. data/lib/bluecloth.rb +14 -11
  15. data/spec/bluecloth/101_changes_spec.rb +0 -4
  16. data/spec/bluecloth/TEMPLATE +36 -0
  17. data/spec/bluecloth/autolinks_spec.rb +2 -6
  18. data/spec/bluecloth/blockquotes_spec.rb +1 -5
  19. data/spec/bluecloth/code_spans_spec.rb +0 -4
  20. data/spec/bluecloth/emphasis_spec.rb +0 -4
  21. data/spec/bluecloth/entities_spec.rb +0 -4
  22. data/spec/bluecloth/hrules_spec.rb +0 -4
  23. data/spec/bluecloth/images_spec.rb +0 -4
  24. data/spec/bluecloth/inline_html_spec.rb +0 -4
  25. data/spec/bluecloth/links_spec.rb +0 -4
  26. data/spec/bluecloth/lists_spec.rb +0 -4
  27. data/spec/bluecloth/paragraphs_spec.rb +0 -4
  28. data/spec/bluecloth/titles_spec.rb +0 -4
  29. data/spec/bluecloth_spec.rb +3 -5
  30. data/spec/bugfix_spec.rb +6 -8
  31. data/spec/contributions_spec.rb +0 -2
  32. data/spec/discount_spec.rb +2 -6
  33. data/spec/lib/helpers.rb +24 -0
  34. data/spec/lib/matchers.rb +1 -0
  35. data/spec/markdowntest_spec.rb +0 -4
  36. metadata +222 -139
  37. metadata.gz.sig +0 -0
  38. data/ChangeLog +0 -444
  39. data/README +0 -81
  40. data/Rakefile.local +0 -48
  41. data/rake/191_compat.rb +0 -26
  42. data/rake/dependencies.rb +0 -76
  43. data/rake/documentation.rb +0 -123
  44. data/rake/helpers.rb +0 -502
  45. data/rake/hg.rb +0 -318
  46. data/rake/manual.rb +0 -787
  47. data/rake/packaging.rb +0 -129
  48. data/rake/publishing.rb +0 -341
  49. data/rake/style.rb +0 -62
  50. data/rake/svn.rb +0 -668
  51. data/rake/testing.rb +0 -152
  52. data/rake/verifytask.rb +0 -64
data/Rakefile.local DELETED
@@ -1,48 +0,0 @@
1
- #!rake
2
-
3
- require 'rbconfig'
4
- require 'rake/extensiontask'
5
-
6
- # C extension constants
7
- ARCH = Config::CONFIG['arch']
8
- ARCHLIBDIR = LIBDIR + ARCH
9
-
10
- EXT_MAKEFILE = EXTDIR + 'Makefile'
11
- EXT_SOURCES = FileList[ EXTDIR + '*.c' ]
12
- EXT_SO = EXTDIR + "bluecloth_ext.#{CONFIG['DLEXT']}"
13
-
14
-
15
-
16
- GEMSPEC.extra_rdoc_files << 'LICENSE.discount'
17
- DOCFILES << 'LICENSE.discount'
18
-
19
-
20
- #####################################################################
21
- ### T A S K S
22
- #####################################################################
23
-
24
- # Make both the default task and the spec task depend on building the extension
25
- task :local => :compile
26
- task :spec => :compile
27
- namespace :spec do
28
- task :doc => [ :compile ]
29
- task :quiet => [ :compile ]
30
- task :html => [ :compile ]
31
- task :text => [ :compile ]
32
- end
33
-
34
-
35
- ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.2'
36
-
37
- Rake::ExtensionTask.new do |ext|
38
- ext.name = 'bluecloth_ext'
39
- ext.gem_spec = GEMSPEC
40
- ext.ext_dir = EXTDIR.to_s
41
- ext.lib_dir = LIBDIR.to_s
42
- ext.source_pattern = "*.{c,h}"
43
- ext.cross_compile = true
44
- ext.cross_platform = %w[i386-mswin32 i386-mingw32]
45
- end
46
-
47
- CLEAN.include( "#{LIBDIR + '1.8'}", "#{LIBDIR + '1.9'}" )
48
-
data/rake/191_compat.rb DELETED
@@ -1,26 +0,0 @@
1
- # 1.9.1 fixes
2
-
3
-
4
- # Make Pathname compatible with 1.8.7 Pathname.
5
- unless Pathname.instance_methods.include?( :=~ )
6
- class Pathname
7
- def self::glob( *args ) # :yield: p
8
- args = args.collect {|p| p.to_s }
9
- if block_given?
10
- Dir.glob(*args) {|f| yield self.new(f) }
11
- else
12
- Dir.glob(*args).map {|f| self.new(f) }
13
- end
14
- end
15
-
16
- def =~( other )
17
- self.to_s =~ other
18
- end
19
-
20
- def to_str
21
- self.to_s
22
- end
23
- end
24
- end
25
-
26
-
data/rake/dependencies.rb DELETED
@@ -1,76 +0,0 @@
1
- #
2
- # Dependency-checking and Installation Rake Tasks
3
-
4
- #
5
-
6
- require 'rubygems/dependency_installer'
7
- require 'rubygems/source_index'
8
- require 'rubygems/requirement'
9
- require 'rubygems/doc_manager'
10
-
11
- ### Install the specified +gems+ if they aren't already installed.
12
- def install_gems( gems )
13
-
14
- defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
15
- :generate_rdoc => true,
16
- :generate_ri => true,
17
- :install_dir => Gem.dir,
18
- :format_executable => false,
19
- :test => false,
20
- :version => Gem::Requirement.default,
21
- })
22
-
23
- # Check for root
24
- if Process.euid != 0
25
- $stderr.puts "This probably won't work, as you aren't root, but I'll try anyway"
26
- end
27
-
28
- gemindex = Gem::SourceIndex.from_installed_gems
29
-
30
- gems.each do |gemname, reqstring|
31
- requirement = Gem::Requirement.new( reqstring )
32
- trace "requirement is: %p" % [ requirement ]
33
-
34
- trace "Searching for an installed #{gemname}..."
35
- specs = gemindex.find_name( gemname )
36
- trace "...found %d specs: %s" %
37
- [ specs.length, specs.collect {|s| "%s %s" % [s.name, s.version] }.join(', ') ]
38
-
39
- if spec = specs.find {|spec| requirement.satisfied_by?(spec.version) }
40
- log "Version %s of %s is already installed (needs %s); skipping..." %
41
- [ spec.version, spec.name, requirement ]
42
- next
43
- end
44
-
45
- rgv = Gem::Version.new( Gem::RubyGemsVersion )
46
- installer = nil
47
-
48
- log "Trying to install #{gemname.inspect} #{requirement}..."
49
- if rgv >= Gem::Version.new( '1.1.1' )
50
- installer = Gem::DependencyInstaller.new
51
- installer.install( gemname, requirement )
52
- else
53
- installer = Gem::DependencyInstaller.new( gemname )
54
- installer.install
55
- end
56
-
57
- installer.installed_gems.each do |spec|
58
- log "Installed: %s" % [ spec.full_name ]
59
- end
60
-
61
- end
62
- end
63
-
64
-
65
- ### Task: install runtime dependencies
66
- desc "Install runtime dependencies as gems"
67
- task :install_dependencies do
68
- install_gems( DEPENDENCIES )
69
- end
70
-
71
- ### Task: install gems for development tasks
72
- desc "Install development dependencies as gems"
73
- task :install_dev_dependencies do
74
- install_gems( DEVELOPMENT_DEPENDENCIES )
75
- end
76
-
@@ -1,123 +0,0 @@
1
- #
2
- # Documentation Rake tasks
3
- #
4
-
5
- require 'rake/clean'
6
-
7
-
8
- # Append docs/lib to the load path if it exists for documentation
9
- # helpers.
10
- DOCSLIB = DOCSDIR + 'lib'
11
- $LOAD_PATH.unshift( DOCSLIB.to_s ) if DOCSLIB.exist?
12
-
13
- # Make relative string paths of all the stuff we need to generate docs for
14
- DOCFILES = Rake::FileList[ LIB_FILES + EXT_FILES + GEMSPEC.extra_rdoc_files ]
15
-
16
- # Documentation coverage constants
17
- COVERAGE_DIR = BASEDIR + 'coverage'
18
- COVERAGE_REPORT = COVERAGE_DIR + 'documentation.txt'
19
-
20
-
21
- # Prefer YARD, fallback to RDoc
22
- begin
23
- require 'yard'
24
- require 'yard/rake/yardoc_task'
25
-
26
- # Undo the lazy-assed monkeypatch yard/globals.rb installs and
27
- # re-install them as mixins as they should have been from the
28
- # start
29
- # <metamonkeypatch>
30
- class Object
31
- remove_method :log
32
- remove_method :P
33
- end
34
-
35
- module YardGlobals
36
- def P(namespace, name = nil)
37
- namespace, name = nil, namespace if name.nil?
38
- YARD::Registry.resolve(namespace, name, false, true)
39
- end
40
-
41
- def log
42
- YARD::Logger.instance
43
- end
44
- end
45
-
46
- class YARD::CLI::Base; include YardGlobals; end
47
- class YARD::CLI::Command; include YardGlobals; end
48
- class YARD::Parser::SourceParser; extend YardGlobals; include YardGlobals; end
49
- class YARD::Parser::CParser; include YardGlobals; end
50
- class YARD::CodeObjects::Base; include YardGlobals; end
51
- class YARD::Handlers::Base; include YardGlobals; end
52
- class YARD::Handlers::Processor; include YardGlobals; end
53
- class YARD::Serializers::Base; include YardGlobals; end
54
- class YARD::RegistryStore; include YardGlobals; end
55
- class YARD::Docstring; include YardGlobals; end
56
- module YARD::Templates::Helpers::ModuleHelper; include YardGlobals; end
57
- module YARD::Templates::Helpers::HtmlHelper; include YardGlobals; end
58
-
59
- if vvec(RUBY_VERSION) >= vvec("1.9.1")
60
- # Monkeypatched to allow more than two '#' characters at the beginning
61
- # of the comment line.
62
- # Patched from yard-0.5.8
63
- require 'yard/parser/ruby/ruby_parser'
64
- class YARD::Parser::Ruby::RipperParser < Ripper
65
- def on_comment(comment)
66
- visit_ns_token(:comment, comment)
67
- case comment
68
- when /\A# @group\s+(.+)\s*\Z/
69
- @groups.unshift [lineno, $1]
70
- return
71
- when /\A# @endgroup\s*\Z/
72
- @groups.unshift [lineno, nil]
73
- return
74
- end
75
-
76
- comment = comment.gsub(/^\#+\s{0,1}/, '').chomp
77
- append_comment = @comments[lineno - 1]
78
-
79
- if append_comment && @comments_last_column == column
80
- @comments.delete(lineno - 1)
81
- comment = append_comment + "\n" + comment
82
- end
83
-
84
- @comments[lineno] = comment
85
- @comments_last_column = column
86
- end
87
- end # class YARD::Parser::Ruby::RipperParser
88
- end
89
-
90
- # </metamonkeypatch>
91
-
92
- YARD_OPTIONS = [] unless defined?( YARD_OPTIONS )
93
-
94
- yardoctask = YARD::Rake::YardocTask.new( :apidocs ) do |task|
95
- task.files = DOCFILES
96
- task.options = YARD_OPTIONS
97
- task.options << '--debug' << '--verbose' if $trace
98
- end
99
- yardoctask.before = lambda {
100
- trace "Calling yardoc like:",
101
- " yardoc %s" % [ quotelist(yardoctask.options + yardoctask.files).join(' ') ]
102
- }
103
-
104
- YARDOC_CACHE = BASEDIR + '.yardoc'
105
- CLOBBER.include( YARDOC_CACHE.to_s )
106
-
107
- rescue LoadError
108
- require 'rdoc/task'
109
-
110
- desc "Build API documentation in #{API_DOCSDIR}"
111
- RDoc::Task.new( :apidocs ) do |task|
112
- task.main = "README"
113
- task.rdoc_files.include( DOCFILES )
114
- task.rdoc_dir = API_DOCSDIR.to_s
115
- task.options = RDOC_OPTIONS
116
- end
117
- end
118
-
119
- # Need the DOCFILES to exist to build the API docs
120
- task :apidocs => DOCFILES
121
-
122
- CLEAN.include( API_DOCSDIR.to_s )
123
-
data/rake/helpers.rb DELETED
@@ -1,502 +0,0 @@
1
- # encoding: utf-8
2
-
3
- #####################################################################
4
- ### G L O B A L H E L P E R F U N C T I O N S
5
- #####################################################################
6
-
7
-
8
- require 'pathname'
9
- require 'uri'
10
-
11
- begin
12
- require 'readline'
13
- include Readline
14
- rescue LoadError
15
- # Fall back to a plain prompt
16
- def readline( text )
17
- $stderr.print( text.chomp )
18
- return $stdin.gets
19
- end
20
- end
21
-
22
- module RakefileHelpers
23
- # Set some ANSI escape code constants (Shamelessly stolen from Perl's
24
- # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
25
- ANSI_ATTRIBUTES = {
26
- 'clear' => 0,
27
- 'reset' => 0,
28
- 'bold' => 1,
29
- 'dark' => 2,
30
- 'underline' => 4,
31
- 'underscore' => 4,
32
- 'blink' => 5,
33
- 'reverse' => 7,
34
- 'concealed' => 8,
35
-
36
- 'black' => 30, 'on_black' => 40,
37
- 'red' => 31, 'on_red' => 41,
38
- 'green' => 32, 'on_green' => 42,
39
- 'yellow' => 33, 'on_yellow' => 43,
40
- 'blue' => 34, 'on_blue' => 44,
41
- 'magenta' => 35, 'on_magenta' => 45,
42
- 'cyan' => 36, 'on_cyan' => 46,
43
- 'white' => 37, 'on_white' => 47
44
- }
45
-
46
-
47
- MULTILINE_PROMPT = <<-'EOF'
48
- Enter one or more values for '%s'.
49
- A blank line finishes input.
50
- EOF
51
-
52
-
53
- CLEAR_TO_EOL = "\e[K"
54
- CLEAR_CURRENT_LINE = "\e[2K"
55
-
56
-
57
- TAR_OPTS = { :compression => :gzip }
58
-
59
-
60
- ###############
61
- module_function
62
- ###############
63
-
64
- ### Output a logging message
65
- def log( *msg )
66
- output = colorize( msg.flatten.join(' '), 'cyan' )
67
- $stderr.puts( output )
68
- end
69
-
70
-
71
- ### Output a logging message if tracing is on
72
- def trace( *msg )
73
- return unless $trace
74
- output = colorize( msg.flatten.join(' '), 'yellow' )
75
- $stderr.puts( output )
76
- end
77
-
78
-
79
- ### Return the specified args as a string, quoting any that have a space.
80
- def quotelist( *args )
81
- return args.flatten.collect {|part| part =~ /\s/ ? part.inspect : part}
82
- end
83
-
84
-
85
- ### Run the specified command +cmd+ with system(), failing if the execution
86
- ### fails.
87
- def run( *cmd )
88
- cmd.flatten!
89
-
90
- if cmd.length > 1
91
- trace( quotelist(*cmd) )
92
- else
93
- trace( cmd )
94
- end
95
-
96
- if $dryrun
97
- $stderr.puts "(dry run mode)"
98
- else
99
- system( *cmd )
100
- unless $?.success?
101
- fail "Command failed: [%s]" % [cmd.join(' ')]
102
- end
103
- end
104
- end
105
-
106
-
107
- ### Run the given +cmd+ with the specified +args+ without interpolation by the shell and
108
- ### return anything written to its STDOUT.
109
- def read_command_output( cmd, *args )
110
- trace "Reading output from: %s" % [ cmd, quotelist(cmd, *args) ]
111
- output = IO.read( '|-' ) or exec cmd, *args
112
- return output
113
- end
114
-
115
-
116
- ### Run a subordinate Rake process with the same options and the specified +targets+.
117
- def rake( *targets )
118
- opts = ARGV.select {|arg| arg[0,1] == '-' }
119
- args = opts + targets.map {|t| t.to_s }
120
- run 'rake', '-N', *args
121
- end
122
-
123
-
124
- ### Open a pipe to a process running the given +cmd+ and call the given block with it.
125
- def pipeto( *cmd )
126
- $DEBUG = true
127
-
128
- cmd.flatten!
129
- log( "Opening a pipe to: ", cmd.collect {|part| part =~ /\s/ ? part.inspect : part} )
130
- if $dryrun
131
- $stderr.puts "(dry run mode)"
132
- else
133
- open( '|-', 'w+' ) do |io|
134
-
135
- # Parent
136
- if io
137
- yield( io )
138
-
139
- # Child
140
- else
141
- exec( *cmd )
142
- fail "Command failed: [%s]" % [cmd.join(' ')]
143
- end
144
- end
145
- end
146
- end
147
-
148
-
149
- ### Download the file at +sourceuri+ via HTTP and write it to +targetfile+.
150
- def download( sourceuri, targetfile=nil )
151
- oldsync = $stdout.sync
152
- $stdout.sync = true
153
- require 'open-uri'
154
-
155
- targetpath = Pathname.new( targetfile )
156
-
157
- log "Downloading %s to %s" % [sourceuri, targetfile]
158
- trace " connecting..."
159
- ifh = open( sourceuri ) do |ifh|
160
- trace " connected..."
161
- targetpath.open( File::WRONLY|File::TRUNC|File::CREAT, 0644 ) do |ofh|
162
- log "Downloading..."
163
- buf = ''
164
-
165
- while ifh.read( 16384, buf )
166
- until buf.empty?
167
- bytes = ofh.write( buf )
168
- buf.slice!( 0, bytes )
169
- end
170
- end
171
-
172
- log "Done."
173
- end
174
-
175
- end
176
-
177
- return targetpath
178
- ensure
179
- $stdout.sync = oldsync
180
- end
181
-
182
-
183
- ### Return the fully-qualified path to the specified +program+ in the PATH.
184
- def which( program )
185
- return nil unless ENV['PATH']
186
- ENV['PATH'].split(/:/).
187
- collect {|dir| Pathname.new(dir) + program }.
188
- find {|path| path.exist? && path.executable? }
189
- end
190
-
191
-
192
- ### Create a string that contains the ANSI codes specified and return it
193
- def ansi_code( *attributes )
194
- attributes.flatten!
195
- attributes.collect! {|at| at.to_s }
196
- # $stderr.puts "Returning ansicode for TERM = %p: %p" %
197
- # [ ENV['TERM'], attributes ]
198
- return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
199
- attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
200
-
201
- # $stderr.puts " attr is: %p" % [attributes]
202
- if attributes.empty?
203
- return ''
204
- else
205
- return "\e[%sm" % attributes
206
- end
207
- end
208
-
209
-
210
- ### Colorize the given +string+ with the specified +attributes+ and return it, handling
211
- ### line-endings, color reset, etc.
212
- def colorize( *args )
213
- string = ''
214
-
215
- if block_given?
216
- string = yield
217
- else
218
- string = args.shift
219
- end
220
-
221
- ending = string[/(\s)$/] || ''
222
- string = string.rstrip
223
-
224
- return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
225
- end
226
-
227
-
228
- ### Output the specified <tt>msg</tt> as an ANSI-colored error message
229
- ### (white on red).
230
- def error_message( msg, details='' )
231
- $stderr.puts colorize( 'bold', 'white', 'on_red' ) { msg } + details
232
- end
233
- alias :error :error_message
234
-
235
-
236
- ### Highlight and embed a prompt control character in the given +string+ and return it.
237
- def make_prompt_string( string )
238
- return CLEAR_CURRENT_LINE + colorize( 'bold', 'green' ) { string + ' ' }
239
- end
240
-
241
-
242
- ### Output the specified <tt>prompt_string</tt> as a prompt (in green) and
243
- ### return the user's input with leading and trailing spaces removed. If a
244
- ### test is provided, the prompt will repeat until the test returns true.
245
- ### An optional failure message can also be passed in.
246
- def prompt( prompt_string, failure_msg="Try again." ) # :yields: response
247
- prompt_string.chomp!
248
- prompt_string << ":" unless /\W$/.match( prompt_string )
249
- response = nil
250
-
251
- begin
252
- prompt = make_prompt_string( prompt_string )
253
- response = readline( prompt ) || ''
254
- response.strip!
255
- if block_given? && ! yield( response )
256
- error_message( failure_msg + "\n\n" )
257
- response = nil
258
- end
259
- end while response.nil?
260
-
261
- return response
262
- end
263
-
264
-
265
- ### Prompt the user with the given <tt>prompt_string</tt> via #prompt,
266
- ### substituting the given <tt>default</tt> if the user doesn't input
267
- ### anything. If a test is provided, the prompt will repeat until the test
268
- ### returns true. An optional failure message can also be passed in.
269
- def prompt_with_default( prompt_string, default, failure_msg="Try again." )
270
- response = nil
271
-
272
- begin
273
- default ||= '~'
274
- response = prompt( "%s [%s]" % [ prompt_string, default ] )
275
- response = default.to_s if !response.nil? && response.empty?
276
-
277
- trace "Validating response %p" % [ response ]
278
-
279
- # the block is a validator. We need to make sure that the user didn't
280
- # enter '~', because if they did, it's nil and we should move on. If
281
- # they didn't, then call the block.
282
- if block_given? && response != '~' && ! yield( response )
283
- error_message( failure_msg + "\n\n" )
284
- response = nil
285
- end
286
- end while response.nil?
287
-
288
- return nil if response == '~'
289
- return response
290
- end
291
-
292
-
293
- ### Prompt for an array of values
294
- def prompt_for_multiple_values( label, default=nil )
295
- $stderr.puts( MULTILINE_PROMPT % [label] )
296
- if default
297
- $stderr.puts "Enter a single blank line to keep the default:\n %p" % [ default ]
298
- end
299
-
300
- results = []
301
- result = nil
302
-
303
- begin
304
- result = readline( make_prompt_string("> ") )
305
- if result.nil? || result.empty?
306
- results << default if default && results.empty?
307
- else
308
- results << result
309
- end
310
- end until result.nil? || result.empty?
311
-
312
- return results.flatten
313
- end
314
-
315
-
316
- ### Turn echo and masking of input on/off.
317
- def noecho( masked=false )
318
- require 'termios'
319
-
320
- rval = nil
321
- term = Termios.getattr( $stdin )
322
-
323
- begin
324
- newt = term.dup
325
- newt.c_lflag &= ~Termios::ECHO
326
- newt.c_lflag &= ~Termios::ICANON if masked
327
-
328
- Termios.tcsetattr( $stdin, Termios::TCSANOW, newt )
329
-
330
- rval = yield
331
- ensure
332
- Termios.tcsetattr( $stdin, Termios::TCSANOW, term )
333
- end
334
-
335
- return rval
336
- end
337
-
338
-
339
- ### Prompt the user for her password, turning off echo if the 'termios' module is
340
- ### available.
341
- def prompt_for_password( prompt="Password: " )
342
- return noecho( true ) do
343
- $stderr.print( prompt )
344
- ($stdin.gets || '').chomp
345
- end
346
- end
347
-
348
-
349
- ### Display a description of a potentially-dangerous task, and prompt
350
- ### for confirmation. If the user answers with anything that begins
351
- ### with 'y', yield to the block. If +abort_on_decline+ is +true+,
352
- ### any non-'y' answer will fail with an error message.
353
- def ask_for_confirmation( description, abort_on_decline=true )
354
- puts description
355
-
356
- answer = prompt_with_default( "Continue?", 'n' ) do |input|
357
- input =~ /^[yn]/i
358
- end
359
-
360
- if answer =~ /^y/i
361
- return yield
362
- elsif abort_on_decline
363
- error "Aborted."
364
- fail
365
- end
366
-
367
- return false
368
- end
369
- alias :prompt_for_confirmation :ask_for_confirmation
370
-
371
-
372
- ### Search line-by-line in the specified +file+ for the given +regexp+, returning the
373
- ### first match, or nil if no match was found. If the +regexp+ has any capture groups,
374
- ### those will be returned in an Array, else the whole matching line is returned.
375
- def find_pattern_in_file( regexp, file )
376
- rval = nil
377
-
378
- File.open( file, 'r' ).each do |line|
379
- if (( match = regexp.match(line) ))
380
- rval = match.captures.empty? ? match[0] : match.captures
381
- break
382
- end
383
- end
384
-
385
- return rval
386
- end
387
-
388
-
389
- ### Search line-by-line in the output of the specified +cmd+ for the given +regexp+,
390
- ### returning the first match, or nil if no match was found. If the +regexp+ has any
391
- ### capture groups, those will be returned in an Array, else the whole matching line
392
- ### is returned.
393
- def find_pattern_in_pipe( regexp, *cmd )
394
- require 'open3'
395
- output = []
396
-
397
- log( cmd.collect {|part| part =~ /\s/ ? part.inspect : part} )
398
- Open3.popen3( *cmd ) do |stdin, stdout, stderr|
399
- stdin.close
400
-
401
- output << stdout.gets until stdout.eof?
402
- output << stderr.gets until stderr.eof?
403
- end
404
-
405
- result = output.find { |line| regexp.match(line) }
406
- return $1 || result
407
- end
408
-
409
-
410
- ### Invoke the user's editor on the given +filename+ and return the exit code
411
- ### from doing so.
412
- def edit( filename )
413
- editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR
414
- system editor, filename
415
- unless $?.success? || editor =~ /vim/i
416
- fail "Editor exited uncleanly."
417
- end
418
- end
419
-
420
-
421
- ### Extract all the non Rake-target arguments from ARGV and return them.
422
- def get_target_args
423
- args = ARGV.reject {|arg| arg =~ /^-/ || Rake::Task.task_defined?(arg) }
424
- return args
425
- end
426
-
427
-
428
- ### Log a subdirectory change, execute a block, and exit the subdirectory
429
- def in_subdirectory( subdir )
430
- block = Proc.new
431
-
432
- log "Entering #{subdir}"
433
- Dir.chdir( subdir, &block )
434
- log "Leaving #{subdir}"
435
- end
436
-
437
-
438
- ### Make an easily-comparable version vector out of +ver+ and return it.
439
- def vvec( ver )
440
- return ver.split('.').collect {|char| char.to_i }.pack('N*')
441
- end
442
-
443
-
444
- ### Archive::Tar::Reader#extract (as of 0.9.0) is broken w.r.t.
445
- ### permissions, so we have to do this ourselves.
446
- def untar( tarfile, targetdir )
447
- require 'archive/tar'
448
- targetdir = Pathname( targetdir )
449
- raise "No such directory: #{targetdir}" unless targetdir.directory?
450
-
451
- reader = Archive::Tar::Reader.new( tarfile.to_s, TAR_OPTS )
452
-
453
- mkdir_p( targetdir )
454
- reader.each( true ) do |header, body|
455
- path = targetdir + header[:path]
456
- # trace "Header is: %p" % [ header ]
457
-
458
- case header[:type]
459
- when :file
460
- trace " #{path}"
461
- path.open( File::WRONLY|File::EXCL|File::CREAT|File::TRUNC, header[:mode] ) do |fio|
462
- bytesize = header[:size]
463
- fio.write( body[0,bytesize] )
464
- end
465
-
466
- when :directory
467
- trace " #{path}"
468
- path.mkpath
469
-
470
- when :link
471
- linktarget = targetdir + header[:dest]
472
- trace " #{path} => #{linktarget}"
473
- path.make_link( linktarget.to_s )
474
-
475
- when :symlink
476
- linktarget = targetdir + header[:dest]
477
- trace " #{path} -> #{linktarget}"
478
- path.make_symlink( linktarget )
479
- end
480
- end
481
-
482
- end
483
-
484
-
485
- ### Extract the contents of the specified +zipfile+ into the given +targetdir+.
486
- def unzip( zipfile, targetdir, *files )
487
- require 'zip/zip'
488
- targetdir = Pathname( targetdir )
489
- raise "No such directory: #{targetdir}" unless targetdir.directory?
490
-
491
- Zip::ZipFile.foreach( zipfile ) do |entry|
492
- # trace " entry is: %p" % [ entry ]
493
- next unless files.empty? || files.include?( entry.name )
494
- target_path = targetdir + entry.name
495
- # trace " would extract to: %s" % [ target_path ]
496
- entry.extract( target_path ) { true }
497
- end
498
- end
499
-
500
- end # module Rakefile::Helpers
501
-
502
-