utils 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/chroot-exec +12 -0
- data/bin/chroot-libs +18 -0
- data/bin/classify +37 -0
- data/bin/discover +137 -0
- data/bin/edit +74 -0
- data/bin/errf +32 -0
- data/bin/git-empty +8 -0
- data/bin/myex +90 -0
- data/bin/number_files +26 -0
- data/bin/same_files +37 -0
- data/bin/search +205 -0
- data/bin/sedit +3 -0
- data/bin/sshscreen +68 -0
- data/bin/term +21 -0
- data/bin/unquarantine_apps +8 -0
- data/bin/untest +17 -0
- data/bin/utils-install-config +10 -0
- data/bin/vacuum_firefox_sqlite +22 -0
- data/bin/xmp +74 -0
- data/lib/utils.rb +8 -0
- data/lib/utils/config.rb +23 -0
- data/lib/utils/config/gdb/asm +179 -0
- data/lib/utils/config/gdb/ruby +528 -0
- data/lib/utils/config/gdbinit +8 -0
- data/lib/utils/config/irbrc +455 -0
- data/lib/utils/config/rdebugrc +2 -0
- data/lib/utils/config/screenrc +143 -0
- data/lib/utils/config/vim/autoload/Align.vim +1029 -0
- data/lib/utils/config/vim/autoload/AlignMaps.vim +330 -0
- data/lib/utils/config/vim/autoload/rails.vim +4744 -0
- data/lib/utils/config/vim/autoload/rubycomplete.vim +801 -0
- data/lib/utils/config/vim/autoload/sqlcomplete.vim +741 -0
- data/lib/utils/config/vim/autoload/vimball.vim +750 -0
- data/lib/utils/config/vim/colors/flori.vim +113 -0
- data/lib/utils/config/vim/compiler/eruby.vim +40 -0
- data/lib/utils/config/vim/compiler/ruby.vim +67 -0
- data/lib/utils/config/vim/compiler/rubyunit.vim +34 -0
- data/lib/utils/config/vim/ftdetect/ragel.vim +2 -0
- data/lib/utils/config/vim/ftdetect/ruby.vim +17 -0
- data/lib/utils/config/vim/ftplugin/eruby.vim +100 -0
- data/lib/utils/config/vim/ftplugin/ruby.vim +260 -0
- data/lib/utils/config/vim/ftplugin/xml.vim +941 -0
- data/lib/utils/config/vim/indent/IndentAnything_html.vim +35 -0
- data/lib/utils/config/vim/indent/eruby.vim +77 -0
- data/lib/utils/config/vim/indent/javascript.vim +116 -0
- data/lib/utils/config/vim/indent/ruby.vim +377 -0
- data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +242 -0
- data/lib/utils/config/vim/plugin/AlignPlugin.vim +41 -0
- data/lib/utils/config/vim/plugin/Decho.vim +592 -0
- data/lib/utils/config/vim/plugin/IndentAnything.vim +675 -0
- data/lib/utils/config/vim/plugin/bufexplorer.vim +1144 -0
- data/lib/utils/config/vim/plugin/cecutil.vim +482 -0
- data/lib/utils/config/vim/plugin/fugitive.vim +1703 -0
- data/lib/utils/config/vim/plugin/lusty-explorer.vim +1509 -0
- data/lib/utils/config/vim/plugin/rails.vim +340 -0
- data/lib/utils/config/vim/plugin/rubyextra.vim +193 -0
- data/lib/utils/config/vim/plugin/surround.vim +628 -0
- data/lib/utils/config/vim/plugin/taglist.vim +4546 -0
- data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +131 -0
- data/lib/utils/config/vim/plugin/vimballPlugin.vim +40 -0
- data/lib/utils/config/vim/syntax/Decho.vim +101 -0
- data/lib/utils/config/vim/syntax/eruby.vim +73 -0
- data/lib/utils/config/vim/syntax/javascript.vim +246 -0
- data/lib/utils/config/vim/syntax/ragel.vim +165 -0
- data/lib/utils/config/vim/syntax/ruby.vim +367 -0
- data/lib/utils/config/vimrc +461 -0
- data/lib/utils/file.rb +49 -0
- data/lib/utils/find.rb +54 -0
- data/lib/utils/md5.rb +23 -0
- data/lib/utils/patterns.rb +34 -0
- data/lib/utils/version.rb +8 -0
- data/utils.gemspec +33 -0
- metadata +183 -0
data/bin/number_files
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils::Verbose
|
5
|
+
|
6
|
+
def usage
|
7
|
+
STDERR.puts "Usage: #$0 prefix"
|
8
|
+
end
|
9
|
+
|
10
|
+
ARGV.empty? and usage
|
11
|
+
prefix = ARGV.shift
|
12
|
+
files = ARGV.sort_by do |x|
|
13
|
+
if m = /(\d+)/.match(x)
|
14
|
+
[ m.pre_match == prefix ? -1 : 0, m[1].to_i ]
|
15
|
+
else
|
16
|
+
[ -1, 0 ]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
for f in files
|
20
|
+
mv f, f + '.tmp'
|
21
|
+
end
|
22
|
+
i = 1
|
23
|
+
for f in files
|
24
|
+
mv f + '.tmp', sprintf("%s%03u", prefix, i)
|
25
|
+
i += 1
|
26
|
+
end
|
data/bin/same_files
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'utils'
|
4
|
+
include Utils::MD5
|
5
|
+
|
6
|
+
def find_same(*pathes)
|
7
|
+
files = Hash.new { |h,k| h[k] = {} }
|
8
|
+
Utils::Find.find(*pathes) do |filename|
|
9
|
+
file_stat = File.stat(filename)
|
10
|
+
if file_stat.file?
|
11
|
+
size = file_stat.size
|
12
|
+
$DEBUG and warn "Encountered '#{filename}' (#{size} bytes)."
|
13
|
+
files[size][filename] = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
files = files.inject({}) do |h, (_,fs)|
|
18
|
+
keys = fs.keys
|
19
|
+
if keys.size >= 2
|
20
|
+
keys.each { |k| h[k] = true }
|
21
|
+
end
|
22
|
+
h
|
23
|
+
end.keys
|
24
|
+
|
25
|
+
md5s = Hash.new { |h,k| h[k] = [] }
|
26
|
+
for filename in files
|
27
|
+
md5sum = md5 filename
|
28
|
+
md5s[md5sum] << filename
|
29
|
+
end
|
30
|
+
files = md5s.values
|
31
|
+
files.reject! { |fs| fs.size < 2 }
|
32
|
+
files
|
33
|
+
end
|
34
|
+
|
35
|
+
puts find_same(*ARGV).map { |fs| [ fs.size, fs ] }.sort.map { |c, fs|
|
36
|
+
"#{c}\t#{fs.sort.map { |f| "'#{f}'" } * "\t"}"
|
37
|
+
}
|
data/bin/search
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require 'utils'
|
5
|
+
include Utils::Patterns
|
6
|
+
require 'term/ansicolor'
|
7
|
+
require 'spruz/xt'
|
8
|
+
|
9
|
+
class ::String
|
10
|
+
include Term::ANSIColor
|
11
|
+
end
|
12
|
+
|
13
|
+
class ::File
|
14
|
+
include Utils::FileXt
|
15
|
+
end
|
16
|
+
|
17
|
+
class Grepper
|
18
|
+
PRUNE = /\A(\.svn|\.git|CVS|tmp)\Z/
|
19
|
+
SKIP = /(\A\.|\.sw[pon]\Z|~\Z)/
|
20
|
+
|
21
|
+
class Queue
|
22
|
+
def initialize(max_size)
|
23
|
+
@max_size, @data = max_size, []
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :max_size
|
27
|
+
|
28
|
+
def data
|
29
|
+
@data.dup
|
30
|
+
end
|
31
|
+
|
32
|
+
def push(x)
|
33
|
+
@data.shift if @data.size > @max_size
|
34
|
+
@data << x
|
35
|
+
self
|
36
|
+
end
|
37
|
+
alias << push
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(opts = {})
|
41
|
+
@args = opts[:args] || {}
|
42
|
+
@roots = opts[:roots] || []
|
43
|
+
if n = @args.values_at(*%w[A B C]).compact.first
|
44
|
+
if n.to_s =~ /\A\d+\Z/ and (n = n.to_i) >= 1
|
45
|
+
@queue = Queue.new n
|
46
|
+
else
|
47
|
+
raise ArgumentError, "needs to be an integer number >= 1"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@pathes = []
|
51
|
+
pattern_opts = opts.subhash(:pattern) | {
|
52
|
+
:cset => @args['a'],
|
53
|
+
:icase => @args['i'],
|
54
|
+
}
|
55
|
+
@pattern = @args['R'] ?
|
56
|
+
FuzzyPattern.new(pattern_opts) :
|
57
|
+
RegexpPattern.new(pattern_opts)
|
58
|
+
@name_pattern =
|
59
|
+
if name_pattern = @args['N']
|
60
|
+
RegexpPattern.new(:pattern => name_pattern)
|
61
|
+
elsif name_pattern = @args['n']
|
62
|
+
FuzzyPattern.new(:pattern => name_pattern)
|
63
|
+
end
|
64
|
+
@skip_pattern =
|
65
|
+
if skip_pattern = @args['S']
|
66
|
+
RegexpPattern.new(:pattern => skip_pattern)
|
67
|
+
elsif skip_pattern = @args['s']
|
68
|
+
FuzzyPattern.new(:pattern => skip_pattern)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_reader :pathes
|
73
|
+
|
74
|
+
def match(filename)
|
75
|
+
@filename = filename
|
76
|
+
bn = File.basename(filename)
|
77
|
+
@output = []
|
78
|
+
s = File.stat(filename)
|
79
|
+
if s.directory? && bn =~ PRUNE
|
80
|
+
$DEBUG and warn "Pruning '#{filename}'."
|
81
|
+
Utils::Find.prune
|
82
|
+
end
|
83
|
+
if s.file? && bn !~ SKIP && (!@name_pattern || @name_pattern.match(bn))
|
84
|
+
File.open(filename, 'rb') do |file|
|
85
|
+
if file.binary? != true
|
86
|
+
$DEBUG and warn "Matching '#{filename}'."
|
87
|
+
match_lines file
|
88
|
+
else
|
89
|
+
$DEBUG and warn "Skipping binary file '#{filename}'."
|
90
|
+
end
|
91
|
+
end
|
92
|
+
else
|
93
|
+
$DEBUG and warn "Skipping '#{filename}'."
|
94
|
+
end
|
95
|
+
unless @output.empty?
|
96
|
+
case
|
97
|
+
when @args['l'], @args['e']
|
98
|
+
@output.uniq!
|
99
|
+
@pathes.concat @output
|
100
|
+
else
|
101
|
+
STDOUT.puts @output
|
102
|
+
end
|
103
|
+
@output.clear
|
104
|
+
end
|
105
|
+
self
|
106
|
+
rescue SystemCallError => e
|
107
|
+
warn "Caught #{e.class}: #{e}"
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def match_lines(file)
|
112
|
+
for line in file
|
113
|
+
if m = @pattern.match(line)
|
114
|
+
@skip_pattern and @skip_pattern =~ line and next
|
115
|
+
line[m.begin(0)...m.end(0)] = m[0].on_yellow
|
116
|
+
@queue and @queue << line
|
117
|
+
if @args['l'] or @args['e']
|
118
|
+
@output << @filename
|
119
|
+
elsif @args['L']
|
120
|
+
@output << "#{@filename}:#{file.lineno}"
|
121
|
+
else
|
122
|
+
@output << "#{@filename}:#{file.lineno}".red
|
123
|
+
if @args['B'] or @args['C']
|
124
|
+
@output.concat @queue.data
|
125
|
+
else
|
126
|
+
@output << line
|
127
|
+
end
|
128
|
+
if @args['A'] or @args['C']
|
129
|
+
where = file.tell
|
130
|
+
@queue.max_size.times do
|
131
|
+
file.eof? and break
|
132
|
+
line = file.readline
|
133
|
+
@queue << line
|
134
|
+
@output << line
|
135
|
+
end
|
136
|
+
file.seek where
|
137
|
+
end
|
138
|
+
end
|
139
|
+
else
|
140
|
+
@queue and @queue << line
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def search
|
146
|
+
for dir in @roots
|
147
|
+
Utils::Find.find(dir) { |filename| match(filename) }
|
148
|
+
end
|
149
|
+
@pathes.sort!
|
150
|
+
self
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
include Spruz::GO
|
155
|
+
|
156
|
+
def edit_files(pathes)
|
157
|
+
system "edit #{pathes.map { |x| "'#{x}'" } * ' '}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def usage
|
161
|
+
puts <<-EOT
|
162
|
+
Usage: #{File.basename($0)} [OPTS] PATTERN [PATHES]
|
163
|
+
|
164
|
+
PATTERN is a pattern expression which is used to match against the content of
|
165
|
+
the files. PATHES are the directory and file pathes that are searched.
|
166
|
+
|
167
|
+
Options are
|
168
|
+
|
169
|
+
-n PATTERN only search files whose names match fuzzy PATTERN
|
170
|
+
-N PATTERN only search files whose names match regex PATTERN
|
171
|
+
-s PATTERN skip lines that match fuzzy PATTERN
|
172
|
+
-S PATTERN skip lines that match regex PATTERN
|
173
|
+
-A NUMBER displays NUMBER lines of context after the match
|
174
|
+
-B NUMBER displays NUMBER lines of context before the match
|
175
|
+
-C NUMBER displays NUMBER lines of context around the match
|
176
|
+
-l just list the pathes of the files with matches
|
177
|
+
-L list only the path:linenumber of the files with matches
|
178
|
+
-R interpret PATTERN argument as fuzzy not regex
|
179
|
+
-c disable color output
|
180
|
+
-i use case insensitive matches
|
181
|
+
-e open the matching files with edit command
|
182
|
+
-a CSET use only character set CSET from PATTERN
|
183
|
+
-h display this help
|
184
|
+
|
185
|
+
EOT
|
186
|
+
exit 1
|
187
|
+
end
|
188
|
+
|
189
|
+
args = go 'A:B:C:s:S:n:N:a:RcilLeh'
|
190
|
+
args['h'] and usage
|
191
|
+
pattern = ARGV.shift or usage
|
192
|
+
roots = (ARGV.empty? ? [ Dir.pwd ] : ARGV).map { |f| File.expand_path(f) }
|
193
|
+
|
194
|
+
Term::ANSIColor.coloring = (STDIN.tty? && ENV['TERM'] !~ /dumb/) && !args['c']
|
195
|
+
STDOUT.sync = true
|
196
|
+
|
197
|
+
grepper = Grepper.new(
|
198
|
+
:pattern => pattern,
|
199
|
+
:args => args,
|
200
|
+
:roots => roots
|
201
|
+
).search
|
202
|
+
case
|
203
|
+
when args['e'] then edit_files grepper.pathes
|
204
|
+
when args['l'] then puts grepper.pathes
|
205
|
+
end
|
data/bin/sedit
ADDED
data/bin/sshscreen
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils::Verbose
|
5
|
+
require 'spruz/go'
|
6
|
+
include Spruz::GO
|
7
|
+
|
8
|
+
=begin
|
9
|
+
~/.ssh/config:
|
10
|
+
|
11
|
+
Host *
|
12
|
+
ForwardX11 = yes
|
13
|
+
ControlMaster auto
|
14
|
+
ControlPath ~/.ssh/%r@%h:%p.sock
|
15
|
+
=end
|
16
|
+
|
17
|
+
def usage
|
18
|
+
puts <<EOT
|
19
|
+
Usage: #{File.basename($0)} [OPTS] [user@]remote[:port]"
|
20
|
+
|
21
|
+
OPTS is one of
|
22
|
+
-N list all session names on the specified remote
|
23
|
+
-n NAME name of the screen session to attach to
|
24
|
+
-t [HOST[:PORT]] host:port to tunnel if different from LOCALPORT
|
25
|
+
-l LOCALPORT the localport to forward to
|
26
|
+
-h to display this help
|
27
|
+
|
28
|
+
EOT
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
arguments = ARGV.dup
|
33
|
+
opts = go 'l:t:n:hN', arguments
|
34
|
+
usage if opts['h'] or arguments.size != 1
|
35
|
+
user_remote = arguments.shift
|
36
|
+
user, remote, rport =
|
37
|
+
case user_remote
|
38
|
+
when /\A(?:([^@:]+)@)?([^@:]+)(?::(\d+))?\Z/
|
39
|
+
user = $1 || ENV['USER']
|
40
|
+
user.to_s.empty? and fail "user required to login"
|
41
|
+
[ user, $2, $3 || '22' ]
|
42
|
+
else
|
43
|
+
usage
|
44
|
+
end
|
45
|
+
lport = opts['l']
|
46
|
+
tunnel, tport = if tunnel_port = opts['t']
|
47
|
+
case tunnel_port
|
48
|
+
when /\A([^:]+)(?::(\d+))?\Z/
|
49
|
+
[ $1, $2 || '22' ]
|
50
|
+
else
|
51
|
+
usage
|
52
|
+
end
|
53
|
+
else
|
54
|
+
[ 'localhost', lport ]
|
55
|
+
end
|
56
|
+
ssh_dir = File.expand_path('~/.ssh')
|
57
|
+
mkdir_p ssh_dir
|
58
|
+
sock_file = "#{ssh_dir}/#{user}@#{remote}:#{rport}.sock"
|
59
|
+
if opts['N']
|
60
|
+
exec "ssh -p #{rport} -S #{sock_file} #{user}@#{remote} screen -ls"
|
61
|
+
elsif lport
|
62
|
+
File.exist? sock_file and rm_f sock_file
|
63
|
+
exec "ssh -p #{rport} -Mt -L localhost:#{lport}:#{tunnel}:#{tport}"\
|
64
|
+
" -S #{sock_file} #{user}@#{remote} screen -DUR #{opts['n']}"
|
65
|
+
else
|
66
|
+
File.exist? sock_file and rm_f sock_file
|
67
|
+
exec "ssh -p #{rport} -Mt -S #{sock_file} #{user}@#{remote} screen -DUR #{opts['n']}"
|
68
|
+
end
|
data/bin/term
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
if [ "x-x" = x"$1" ]; then
|
4
|
+
EXIT="; exit"; shift;
|
5
|
+
fi
|
6
|
+
|
7
|
+
if [[ -d "$1" ]]; then
|
8
|
+
WD=`cd "$1"; pwd`; shift;
|
9
|
+
else
|
10
|
+
WD="'`pwd`'";
|
11
|
+
fi
|
12
|
+
|
13
|
+
COMMAND="cd $WD; $@"
|
14
|
+
echo "$COMMAND $EXIT"
|
15
|
+
|
16
|
+
osascript 2>/dev/null <<EOF
|
17
|
+
tell application "Terminal"
|
18
|
+
activate
|
19
|
+
do script with command "$COMMAND $EXIT"
|
20
|
+
end tell
|
21
|
+
EOF
|
data/bin/untest
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spruz/xt/write'
|
4
|
+
|
5
|
+
for filename in ARGV
|
6
|
+
File.open(filename) do |input|
|
7
|
+
write(filename) do |output|
|
8
|
+
until input.eof?
|
9
|
+
line = input.readline
|
10
|
+
line.sub!(/^(\s*)test "(.+)" do\s*$/) do
|
11
|
+
"#$1def test_" << $2.downcase.gsub(/\A[^a-z]/, '').gsub(/[ -]/, '_').delete('^0-9a-z_')
|
12
|
+
end
|
13
|
+
output.puts line
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
case `uname -s` in
|
4
|
+
Darwin)
|
5
|
+
profiles="$HOME/Library/Application Support/Firefox/Profiles/"
|
6
|
+
;;
|
7
|
+
*)
|
8
|
+
profiles="$HOME/.mozilla/firefox/"
|
9
|
+
;;
|
10
|
+
esac
|
11
|
+
|
12
|
+
cd "$profiles"
|
13
|
+
for p in *.default
|
14
|
+
do
|
15
|
+
cd $p
|
16
|
+
for db in *.sqlite
|
17
|
+
do
|
18
|
+
echo "Vacuuming $db..."
|
19
|
+
sqlite3 $db VACUUM
|
20
|
+
done
|
21
|
+
cd -
|
22
|
+
done
|
data/bin/xmp
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
class String
|
5
|
+
unless method_defined?(:lines)
|
6
|
+
def lines
|
7
|
+
self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
MARKER = "!XMP#{Time.new.to_i}_#{rand(1000000)}!"
|
13
|
+
XMPRE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] => (.*)')
|
14
|
+
VAR = "_xmp_#{Time.new.to_i}_#{rand(1000000)}"
|
15
|
+
WARNING_RE = /-:([0-9]+): warning: (.*)/
|
16
|
+
interpreter = ARGV
|
17
|
+
interpreter << 'ruby' << '-w' if interpreter.empty?
|
18
|
+
|
19
|
+
IO.popen(interpreter.first, 'w') do |script|
|
20
|
+
script.write <<-TEST
|
21
|
+
begin
|
22
|
+
require 'rubygems'
|
23
|
+
rescue LoadError
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
exit 0
|
27
|
+
TEST
|
28
|
+
end
|
29
|
+
if $?.exitstatus == 1
|
30
|
+
ENV['RUBYOPT'] = ENV['RUBYOPT'].gsub(/-rr?ubygems/i, '')
|
31
|
+
end
|
32
|
+
code = STDIN.read
|
33
|
+
|
34
|
+
idx = 0
|
35
|
+
newcode = code.gsub(/^(.*) # =>.*/) do |l|
|
36
|
+
expr = $1
|
37
|
+
(/^\s*#/ =~ l) ? l :
|
38
|
+
%!((#{VAR} = (#{expr}); $stderr.puts("#{MARKER}[#{idx+=1}] => " + #{VAR}.inspect) || #{VAR}))!
|
39
|
+
end
|
40
|
+
stdin, stdout, stderr = Open3::popen3(*interpreter)
|
41
|
+
stdin.puts newcode
|
42
|
+
stdin.close
|
43
|
+
output = stderr.readlines
|
44
|
+
|
45
|
+
results = Hash.new{|h,k| h[k] = []}
|
46
|
+
output.grep(XMPRE).each do |line|
|
47
|
+
result_id, result = XMPRE.match(line).captures
|
48
|
+
results[result_id.to_i] << result
|
49
|
+
end
|
50
|
+
|
51
|
+
idx = 0
|
52
|
+
annotated = code.gsub(/^(.*) # =>.*/) do |l|
|
53
|
+
expr = $1
|
54
|
+
(/^\s*#/ =~ l) ? l : "#{expr} # => " + (results[idx+=1] || []).join(", ")
|
55
|
+
end.gsub(/ # !>.*/, '').gsub(/# (>>|~>)[^\n]*\n/m, "");
|
56
|
+
|
57
|
+
warnings = {}
|
58
|
+
output.join.lines.grep(WARNING_RE).map do |x|
|
59
|
+
md = WARNING_RE.match(x)
|
60
|
+
warnings[md[1].to_i] = md[2]
|
61
|
+
end
|
62
|
+
idx = 0
|
63
|
+
annotated = annotated.lines.map do |line|
|
64
|
+
w = warnings[idx+=1]
|
65
|
+
w ? (line.chomp + " # !> #{w}") : line
|
66
|
+
end
|
67
|
+
puts annotated
|
68
|
+
output.reject!{|x| /^-:[0-9]+: warning/.match(x)}
|
69
|
+
if exception = /^-:[0-9]+:.*/m.match(output.join)
|
70
|
+
puts exception[0].map{|line| "# ~> " + line }
|
71
|
+
end
|
72
|
+
if (s = stdout.read) != ""
|
73
|
+
puts "# >> #{s.inspect}"
|
74
|
+
end
|