gorp 0.16.0 → 0.16.1
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.
- data/Manifest +9 -0
- data/gorp.gemspec +1 -1
- data/lib/gorp.rb +2 -266
- data/lib/gorp/edit.rb +64 -44
- data/lib/gorp/test.rb +12 -8
- data/lib/version.rb +1 -1
- metadata +1 -1
data/Manifest
CHANGED
data/gorp.gemspec
CHANGED
data/lib/gorp.rb
CHANGED
@@ -5,14 +5,13 @@
|
|
5
5
|
|
6
6
|
require 'fileutils'
|
7
7
|
require 'open3'
|
8
|
-
require 'net/http'
|
9
8
|
require 'builder'
|
10
|
-
require 'stringio'
|
11
9
|
require 'time'
|
12
|
-
require 'cgi'
|
13
10
|
|
14
11
|
require 'gorp/env'
|
15
12
|
require 'gorp/edit'
|
13
|
+
require 'gorp/net'
|
14
|
+
require 'gorp/rails'
|
16
15
|
|
17
16
|
require 'rbconfig'
|
18
17
|
$ruby = File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])
|
@@ -32,12 +31,6 @@ def section number, title, &steps
|
|
32
31
|
$sections << [number, title, steps]
|
33
32
|
end
|
34
33
|
|
35
|
-
# verify that port is available for testing
|
36
|
-
if (Net::HTTP.get_response('localhost','/',$PORT).code == '200' rescue false)
|
37
|
-
STDERR.puts "local server already running on port #{$PORT}"
|
38
|
-
exit
|
39
|
-
end
|
40
|
-
|
41
34
|
$x = Builder::XmlMarkup.new(:indent => 2)
|
42
35
|
$toc = Builder::XmlMarkup.new(:indent => 2)
|
43
36
|
$todos = Builder::XmlMarkup.new(:indent => 2)
|
@@ -289,263 +282,6 @@ rescue LoadError
|
|
289
282
|
Comment = REXML::Comment
|
290
283
|
end
|
291
284
|
|
292
|
-
def snap response, form=nil
|
293
|
-
if response.content_type == 'text/plain' or response.content_type =~ /xml/
|
294
|
-
$x.div :class => 'body' do
|
295
|
-
response.body.split("\n").each do |line|
|
296
|
-
$x.pre line.chomp, :class=>'stdout'
|
297
|
-
end
|
298
|
-
end
|
299
|
-
return
|
300
|
-
end
|
301
|
-
|
302
|
-
if response.body =~ /<body/
|
303
|
-
body = response.body
|
304
|
-
else
|
305
|
-
body = "<body>#{response.body}</body>"
|
306
|
-
end
|
307
|
-
|
308
|
-
begin
|
309
|
-
doc = xhtmlparse(body)
|
310
|
-
rescue
|
311
|
-
body.split("\n").each {|line| $x.pre line.chomp, :class=>'hilight'}
|
312
|
-
raise
|
313
|
-
end
|
314
|
-
|
315
|
-
title = doc.at('html/head/title').text rescue ''
|
316
|
-
body = doc.at('//body')
|
317
|
-
doc.search('//link[@rel="stylesheet"]').each do |sheet|
|
318
|
-
body.children.first.add_previous_sibling(sheet)
|
319
|
-
end
|
320
|
-
|
321
|
-
if form
|
322
|
-
body.search('//input[@name]').each do |input|
|
323
|
-
input['value'] ||= form[input['name']].to_s
|
324
|
-
end
|
325
|
-
body.search('//textarea[@name]').each do |textarea|
|
326
|
-
textarea.text = form[textarea['name']].to_s if textarea.text.to_s.empty?
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
%w{ a[@href] form[@action] }.each do |xpath|
|
331
|
-
name = xpath[/@(\w+)/,1]
|
332
|
-
body.search("//#{xpath}").each do |element|
|
333
|
-
next if element[name] =~ /^http:\/\//
|
334
|
-
element[name] = URI.join("http://localhost:#{$PORT}/", element[name]).to_s
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
%w{ img[@src] }.each do |xpath|
|
339
|
-
name = xpath[/@(\w+)/,1]
|
340
|
-
body.search("//#{xpath}").each do |element|
|
341
|
-
if element[name][0] == ?/
|
342
|
-
element[name] = 'data' + element[name]
|
343
|
-
end
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
body.search('//textarea').each do |element|
|
348
|
-
element.content=''
|
349
|
-
end
|
350
|
-
|
351
|
-
attrs = {:class => 'body', :title => title}
|
352
|
-
attrs[:class] = 'traceback' if response.code == '500'
|
353
|
-
attrs[:id] = body['id'] if body['id']
|
354
|
-
$x.div(attrs) do
|
355
|
-
body.children.each do |child|
|
356
|
-
$x << child.to_xml unless child.instance_of?(Comment)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
$x.div '', :style => "clear: both"
|
360
|
-
end
|
361
|
-
|
362
|
-
def get path
|
363
|
-
post path, nil
|
364
|
-
end
|
365
|
-
|
366
|
-
def post path, form, options={}
|
367
|
-
$x.pre "get #{path}", :class=>'stdin' unless options[:snapget] == false
|
368
|
-
|
369
|
-
if path.include? ':'
|
370
|
-
host, port, path = URI.parse(path).select(:host, :port, :path)
|
371
|
-
else
|
372
|
-
host, port = '127.0.0.1', $PORT
|
373
|
-
end
|
374
|
-
|
375
|
-
Net::HTTP.start(host, port) do |http|
|
376
|
-
get = Net::HTTP::Get.new(path)
|
377
|
-
get['Cookie'] = $COOKIE if $COOKIE
|
378
|
-
response = http.request(get)
|
379
|
-
snap response, form unless options[:snapget] == false
|
380
|
-
$COOKIE = response.response['set-cookie'] if response.response['set-cookie']
|
381
|
-
|
382
|
-
if form
|
383
|
-
body = xhtmlparse(response.body).at('//body')
|
384
|
-
body = xhtmlparse(response.body).root unless body
|
385
|
-
xforms = body.search('//form')
|
386
|
-
|
387
|
-
# find matching button by action
|
388
|
-
xform = xforms.find do |element|
|
389
|
-
next unless element.attribute('action').to_s.include?('?')
|
390
|
-
query = CGI.parse(URI.parse(element.attribute('action').to_s).query)
|
391
|
-
query.all? {|key,values| values.include?(form[key].to_s)}
|
392
|
-
end
|
393
|
-
|
394
|
-
# find matching button by input names
|
395
|
-
xform ||= xforms.find do |element|
|
396
|
-
form.all? do |name, value|
|
397
|
-
element.search('.//input | .//textarea | ..//select').any? do |input|
|
398
|
-
input.attribute('name').to_s==name.to_s
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
# match based on action itself
|
404
|
-
xform ||= xforms.find do |element|
|
405
|
-
form.all? do |name, value|
|
406
|
-
element.attribute('action').to_s.include?(path)
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
# look for a commit button
|
411
|
-
xform ||= xforms.find {|element| element.at('.//input[@name="commit"]')}
|
412
|
-
|
413
|
-
return unless xform
|
414
|
-
|
415
|
-
path = xform.attribute('action').to_s unless
|
416
|
-
xform.attribute('action').to_s.empty?
|
417
|
-
$x.pre "post #{path}", :class=>'stdin'
|
418
|
-
|
419
|
-
$x.ul do
|
420
|
-
form.each do |name, value|
|
421
|
-
$x.li "#{name} => #{value}"
|
422
|
-
end
|
423
|
-
|
424
|
-
xform.search('.//input[@type="hidden"]').each do |element|
|
425
|
-
# $x.li "#{element['name']} => #{element['value']}"
|
426
|
-
form[element['name']] ||= element['value']
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
post = Net::HTTP::Post.new(path)
|
431
|
-
post.form_data = form
|
432
|
-
post['Cookie'] = $COOKIE
|
433
|
-
response=http.request(post)
|
434
|
-
snap response
|
435
|
-
end
|
436
|
-
|
437
|
-
if response.code == '302'
|
438
|
-
$COOKIE=response.response['set-cookie'] if response.response['set-cookie']
|
439
|
-
path = response['Location']
|
440
|
-
$x.pre "get #{path}", :class=>'stdin'
|
441
|
-
get = Net::HTTP::Get.new(path)
|
442
|
-
get['Cookie'] = $COOKIE if $COOKIE
|
443
|
-
response = http.request(get)
|
444
|
-
snap response
|
445
|
-
$COOKIE=response.response['set-cookie'] if response.response['set-cookie']
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
|
-
# select a version of Rails
|
451
|
-
if ARGV.first =~ /^_\d[.\d]*_$/
|
452
|
-
$rails = "rails #{ARGV.first}"
|
453
|
-
elsif File.directory?(ARGV.first.to_s)
|
454
|
-
$rails = ARGV.first
|
455
|
-
$rails = File.join($rails,'rails') if
|
456
|
-
File.directory?(File.join($rails,'rails'))
|
457
|
-
$rails = File.expand_path($rails)
|
458
|
-
else
|
459
|
-
$rails = 'rails'
|
460
|
-
end
|
461
|
-
|
462
|
-
def which_rails rails
|
463
|
-
railties = File.join(rails, 'railties', 'bin', 'rails')
|
464
|
-
rails = railties if File.exists?(railties)
|
465
|
-
if File.exists?(rails)
|
466
|
-
firstline = open(rails) {|file| file.readlines.first}
|
467
|
-
rails = 'ruby ' + rails unless firstline =~ /^#!/
|
468
|
-
end
|
469
|
-
rails
|
470
|
-
end
|
471
|
-
|
472
|
-
def rails name, app=nil
|
473
|
-
Dir.chdir($WORK)
|
474
|
-
FileUtils.rm_rf name
|
475
|
-
log :rails, name
|
476
|
-
|
477
|
-
# determine how to invoke rails
|
478
|
-
rails = which_rails $rails
|
479
|
-
|
480
|
-
$x.pre "#{rails} #{name}", :class=>'stdin'
|
481
|
-
popen3 "#{rails} #{name}"
|
482
|
-
|
483
|
-
# canonicalize the reference to Ruby
|
484
|
-
Dir["#{name}/script/**/*"].each do |script|
|
485
|
-
next if File.directory? script
|
486
|
-
code = open(script) {|file| file.read}
|
487
|
-
code.sub! /^#!.*/, '#!/usr/bin/env ruby'
|
488
|
-
open(script,'w') {|file| file.write code}
|
489
|
-
end
|
490
|
-
|
491
|
-
cmd "mkdir #{name}" unless File.exist?(name)
|
492
|
-
Dir.chdir(name)
|
493
|
-
FileUtils.rm_rf 'public/.htaccess'
|
494
|
-
|
495
|
-
cmd 'rake rails:freeze:edge' if ARGV.include? 'edge'
|
496
|
-
|
497
|
-
if $rails != 'rails' and File.directory?($rails)
|
498
|
-
cmd "mkdir vendor" unless File.exist?('vendor')
|
499
|
-
cmd "ln -s #{$rails} vendor/rails"
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
def restart_server
|
504
|
-
log :server, 'restart'
|
505
|
-
if $server
|
506
|
-
$x.h3 'Restart the server.'
|
507
|
-
Process.kill "INT", $server
|
508
|
-
Process.wait($server)
|
509
|
-
else
|
510
|
-
$x.h3 'Start the server.'
|
511
|
-
end
|
512
|
-
|
513
|
-
$server = fork
|
514
|
-
if $server
|
515
|
-
# wait for server to start
|
516
|
-
60.times do
|
517
|
-
sleep 0.5
|
518
|
-
begin
|
519
|
-
status = Net::HTTP.get_response('localhost','/',$PORT).code
|
520
|
-
break if %(200 404).include? status
|
521
|
-
rescue Errno::ECONNREFUSED
|
522
|
-
end
|
523
|
-
end
|
524
|
-
else
|
525
|
-
begin
|
526
|
-
if File.exist?('config.ru')
|
527
|
-
require 'rack'
|
528
|
-
server = Rack::Builder.new {eval open('config.ru').read}
|
529
|
-
Rack::Handler::WEBrick.run(server, :Port => $PORT)
|
530
|
-
else
|
531
|
-
# start server, redirecting stdout to a string
|
532
|
-
$stdout = StringIO.open('','w')
|
533
|
-
require './config/boot'
|
534
|
-
if Rails::VERSION::MAJOR == 2
|
535
|
-
require 'commands/server'
|
536
|
-
else
|
537
|
-
require 'rails/commands/server'
|
538
|
-
end
|
539
|
-
end
|
540
|
-
rescue
|
541
|
-
STDERR.puts $!
|
542
|
-
$!.backtrace.each {|method| STDERR.puts "\tfrom " + method}
|
543
|
-
ensure
|
544
|
-
Process.exit!
|
545
|
-
end
|
546
|
-
end
|
547
|
-
end
|
548
|
-
|
549
285
|
def secsplit section
|
550
286
|
section.to_s.split('.').map {|n| n.to_i}
|
551
287
|
end
|
data/lib/gorp/edit.rb
CHANGED
@@ -7,61 +7,81 @@ class String
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
module
|
11
|
-
|
12
|
-
|
13
|
-
self[
|
14
|
-
|
15
|
-
|
10
|
+
module Gorp
|
11
|
+
module StringEditingFunctions
|
12
|
+
def highlight
|
13
|
+
if self =~ /^\s*<[%!\w].*>/
|
14
|
+
start = '<!-- START_HIGHLIGHT -->'
|
15
|
+
close = '<!-- END_HIGHLIGHT -->'
|
16
|
+
else
|
17
|
+
start = '#START_HIGHLIGHT'
|
18
|
+
close = '#END_HIGHLIGHT'
|
19
|
+
end
|
20
|
+
|
21
|
+
if self =~ /\n\z/
|
22
|
+
self[/(.*)/m,1] = "#{start}\n#{self}#{close}\n"
|
23
|
+
else
|
24
|
+
self[/(.*)/m,1] = "#{start}\n#{self}\n#{close}"
|
25
|
+
end
|
16
26
|
end
|
17
|
-
end
|
18
27
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
def mark name
|
29
|
+
return unless name
|
30
|
+
|
31
|
+
if self =~ /^\s*<[%!\w].*>/
|
32
|
+
start = "<!-- START:#{name} -->"
|
33
|
+
close = "<!-- END:#{name} -->"
|
34
|
+
else
|
35
|
+
start = "#START:#{name}"
|
36
|
+
close = "#END:#{name}"
|
37
|
+
end
|
23
38
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
from = Regexp.new('.*' + Regexp.escape(from) + '.*')
|
39
|
+
if self =~ /\n\z/
|
40
|
+
self[/(.*)/m,1] = "#{start}\n#{self}#{close}\n"
|
41
|
+
else
|
42
|
+
self[/(.*)/m,1] = "#{start}\n#{self}\n#{close}"
|
43
|
+
end
|
30
44
|
end
|
31
45
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
base
|
46
|
+
def edit(from, *options)
|
47
|
+
if from.instance_of? String
|
48
|
+
from = Regexp.new('.*' + Regexp.escape(from) + '.*')
|
49
|
+
end
|
50
|
+
|
51
|
+
sub!(from) do |base|
|
52
|
+
base.extend Gorp::StringEditingFunctions
|
53
|
+
yield base if block_given?
|
54
|
+
base.highlight if options.include? :highlight
|
55
|
+
base.mark(options.last[:mark]) if options.last.respond_to? :key
|
56
|
+
base
|
57
|
+
end
|
38
58
|
end
|
39
|
-
end
|
40
59
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
60
|
+
def dcl(name, *options)
|
61
|
+
self.sub!(/(\s*)(class|def|test)\s+"?#{name}"?.*?\n\1end\n/mo) do |lines|
|
62
|
+
lines.extend Gorp::StringEditingFunctions
|
63
|
+
yield lines
|
64
|
+
lines.mark(options.last[:mark]) if options.last.respond_to? :[]
|
65
|
+
lines
|
66
|
+
end
|
47
67
|
end
|
48
|
-
end
|
49
68
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
69
|
+
def clear_highlights
|
70
|
+
self.gsub! /^\s*(#|<!--)\s*(START|END)_HIGHLIGHT(\s*-->)?\n/, ''
|
71
|
+
self.gsub! /^\s*(#|<!--)\s*(START|END)_HIGHLIGHT(\s*-->)?\n/, ''
|
72
|
+
end
|
54
73
|
|
55
|
-
|
56
|
-
|
57
|
-
|
74
|
+
def clear_all_marks
|
75
|
+
self.gsub! /^ *#\s?(START|END)(_HIGHLIGHT|:\w+)\n/, ''
|
76
|
+
end
|
58
77
|
|
59
|
-
|
60
|
-
|
61
|
-
|
78
|
+
def msub pattern, replacement
|
79
|
+
self[pattern, 1] = replacement
|
80
|
+
end
|
62
81
|
|
63
|
-
|
64
|
-
|
82
|
+
def all=replacement
|
83
|
+
self[/(.*)/m,1]=replacement
|
84
|
+
end
|
65
85
|
end
|
66
86
|
end
|
67
87
|
|
@@ -73,7 +93,7 @@ def edit filename, tag=nil
|
|
73
93
|
before = data.split("\n")
|
74
94
|
|
75
95
|
begin
|
76
|
-
data.extend
|
96
|
+
data.extend Gorp::StringEditingFunctions
|
77
97
|
yield data
|
78
98
|
|
79
99
|
now = Time.now
|
data/lib/gorp/test.rb
CHANGED
@@ -34,7 +34,18 @@ class Book::TestCase < ActiveSupport::TestCase
|
|
34
34
|
return if @@omit.include? number.to_s
|
35
35
|
test "#{number} #{title}" do
|
36
36
|
instance_eval {select number}
|
37
|
-
|
37
|
+
begin
|
38
|
+
instance_eval &tests
|
39
|
+
ensure
|
40
|
+
unless $!.instance_of? RuntimeError
|
41
|
+
@raw =~ /<pre\sclass="stdin">edit\s([\w\/.]+)<\/pre>\s+
|
42
|
+
<pre\sclass="traceback">\s+
|
43
|
+
\#<IndexError:\sregexp\snot\smatched>\s+
|
44
|
+
(.*gorp\/lib\/gorp\/edit.rb.*\n\s+)*
|
45
|
+
([\w\/.]+:\d+)/x
|
46
|
+
fail "Edit #{$1} failed at #{$3}" if $1
|
47
|
+
end
|
48
|
+
end
|
38
49
|
end
|
39
50
|
end
|
40
51
|
|
@@ -91,13 +102,6 @@ class Book::TestCase < ActiveSupport::TestCase
|
|
91
102
|
raise "Section #{number} not found" unless @@sections.has_key? number.to_s
|
92
103
|
@raw = @@sections[number.to_s]
|
93
104
|
@selected = HTML::Document.new(@raw).root.children
|
94
|
-
|
95
|
-
@raw =~ /<pre\sclass="stdin">edit\s([\w\/.]+)<\/pre>\s+
|
96
|
-
<pre\sclass="traceback">\s+
|
97
|
-
\#<IndexError:\sregexp\snot\smatched>\s+
|
98
|
-
(.*gorp\/lib\/gorp\/edit.rb.*\n\s+)*
|
99
|
-
([\w\/.]+:\d+)/x
|
100
|
-
fail "Edit #{$1} failed at #{$3}" if $1
|
101
105
|
end
|
102
106
|
|
103
107
|
attr_reader :raw
|
data/lib/version.rb
CHANGED