jackbox 0.9.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +5 -0
- data/CHANGES.txt +108 -0
- data/LICENSE.lic +0 -0
- data/LICENSE.txt +13 -0
- data/README.md +1395 -0
- data/Rakefile +6 -0
- data/bin/jackup +248 -0
- data/jackbox.gemspec +27 -0
- data/jackbox.jpg +0 -0
- data/lib/.document +0 -0
- data/lib/jackbox.rb +2 -0
- data/lib/jackbox/examples/dir.rb +80 -0
- data/lib/jackbox/examples/dx.rb +182 -0
- data/lib/jackbox/examples/transformers.rb +101 -0
- data/lib/jackbox/injectors.rb +2 -0
- data/lib/jackbox/rake.rb +2 -0
- data/lib/jackbox/tools/prefs.rb +2 -0
- data/lib/jackbox/version.rb +4 -0
- data/rgloader/loader.rb +23 -0
- data/rgloader/rgloader.darwin.bundle +0 -0
- data/rgloader/rgloader.freebsd.so +0 -0
- data/rgloader/rgloader.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader.linux.so +0 -0
- data/rgloader/rgloader.linux.x86_64.so +0 -0
- data/rgloader/rgloader.mingw.so +0 -0
- data/rgloader/rgloader19.darwin.bundle +0 -0
- data/rgloader/rgloader19.freebsd.so +0 -0
- data/rgloader/rgloader19.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader19.linux.so +0 -0
- data/rgloader/rgloader19.linux.x86_64.so +0 -0
- data/rgloader/rgloader19.mingw.so +0 -0
- data/rgloader/rgloader191.mingw.so +0 -0
- data/rgloader/rgloader192.darwin.bundle +0 -0
- data/rgloader/rgloader192.freebsd.so +0 -0
- data/rgloader/rgloader192.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader192.linux.so +0 -0
- data/rgloader/rgloader192.linux.x86_64.so +0 -0
- data/rgloader/rgloader192.mingw.so +0 -0
- data/rgloader/rgloader193.darwin.bundle +0 -0
- data/rgloader/rgloader193.freebsd.so +0 -0
- data/rgloader/rgloader193.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader193.linux.so +0 -0
- data/rgloader/rgloader193.linux.x86_64.so +0 -0
- data/rgloader/rgloader193.mingw.so +0 -0
- data/rgloader/rgloader20.darwin.bundle +0 -0
- data/rgloader/rgloader20.freebsd.so +0 -0
- data/rgloader/rgloader20.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader20.linux.so +0 -0
- data/rgloader/rgloader20.linux.x86_64.so +0 -0
- data/rgloader/rgloader20.mingw.so +0 -0
- data/rgloader/rgloader20.mingw.x64.so +0 -0
- data/rgloader/rgloader21.darwin.bundle +0 -0
- data/rgloader/rgloader21.freebsd.so +0 -0
- data/rgloader/rgloader21.freebsd.x86_64.so +0 -0
- data/rgloader/rgloader21.linux.so +0 -0
- data/rgloader/rgloader21.linux.x86_64.so +0 -0
- data/rgloader/rgloader21.mingw.so +0 -0
- data/rgloader/rgloader21.mingw.x64.so +0 -0
- data/rgloader/rgloader22.darwin.bundle +0 -0
- data/rgloader/rgloader22.freebsd.so +0 -0
- data/rgloader/rgloader22.linux.so +0 -0
- data/rgloader/rgloader22.linux.x86_64.so +0 -0
- data/rgloader/rgloader22.mingw.so +0 -0
- data/rgloader/rgloader22.mingw.x64.so +0 -0
- data/spec/bin/jackup_cmd_shared.rb +176 -0
- data/spec/bin/jackup_cmd_spec.rb +292 -0
- data/spec/lib/abtract_spec.rb +56 -0
- data/spec/lib/jackbox/examples/dir_spec.rb +112 -0
- data/spec/lib/jackbox/examples/dx_spec.rb +346 -0
- data/spec/lib/jackbox/examples/result.xml +15 -0
- data/spec/lib/jackbox/examples/source1.xml +11 -0
- data/spec/lib/jackbox/examples/source2.xml +15 -0
- data/spec/lib/jackbox/examples/source3.xml +11 -0
- data/spec/lib/jackbox/examples/trasnformers_spec.rb +35 -0
- data/spec/lib/jackbox/injector_composition_spec.rb +950 -0
- data/spec/lib/jackbox/injector_directives_spec.rb +266 -0
- data/spec/lib/jackbox/injector_inheritance_spec.rb +799 -0
- data/spec/lib/jackbox/injector_introspection_spec.rb +614 -0
- data/spec/lib/jackbox/injector_namespacing_spec.rb +345 -0
- data/spec/lib/jackbox/injector_spec.rb +847 -0
- data/spec/lib/jackbox/injector_versioning_spec.rb +334 -0
- data/spec/lib/jackbox/patterns_spec.rb +410 -0
- data/spec/lib/jackbox/prefs_spec.rb +212 -0
- data/spec/lib/jackbox/reclassing_spec.rb +394 -0
- data/spec/lib/jackbox_spec.rb +595 -0
- data/spec/spec_helper.rb +139 -0
- metadata +218 -0
data/Rakefile
ADDED
data/bin/jackup
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
#
|
4
|
+
# author: LHA
|
5
|
+
#
|
6
|
+
######
|
7
|
+
require 'thor'
|
8
|
+
require 'jackbox'
|
9
|
+
require_relative '../lib/jackbox/examples/dir'
|
10
|
+
|
11
|
+
include Injectors
|
12
|
+
#
|
13
|
+
# Tests to determine foder structuree
|
14
|
+
#
|
15
|
+
injector :structure_tests do
|
16
|
+
def simple?
|
17
|
+
!gem? && !Dir.ls('**/*.rb').empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def bundle?
|
21
|
+
File.exists?('Gemfile') #&& File.exists?('Rakefile')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
Dir.singleton_class.inject structure_tests
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# This class adds the jackbox support to a project
|
29
|
+
#
|
30
|
+
class Jackup < Thor
|
31
|
+
|
32
|
+
desc 'stage', 'Stage jackbox support to project files'
|
33
|
+
long_desc <<-HELP
|
34
|
+
\x5--
|
35
|
+
Stage jackbox support to project files:
|
36
|
+
\x5Use with argument: jackup stage [name] to create a new staged project. Use --no-[option] prefix to exclude features/files.
|
37
|
+
\x5--
|
38
|
+
HELP
|
39
|
+
method_option :bundle, :default => true, :desc => 'Use Bundler'
|
40
|
+
method_option :gem, :default => true, :desc => 'Gem Project'
|
41
|
+
# method_option :testing, :default => true, :desc => 'Testing Framework'
|
42
|
+
method_option :git, :default => true, :desc => 'Use git source control'
|
43
|
+
def stage target=Dir.pwd
|
44
|
+
|
45
|
+
decorate :no_bundle do
|
46
|
+
options[:bundle].in? [false, nil]
|
47
|
+
end
|
48
|
+
|
49
|
+
decorate :no_gem do
|
50
|
+
options[:gem].in? [false, nil]
|
51
|
+
end
|
52
|
+
|
53
|
+
# decorate :no_testing do
|
54
|
+
# options[:testing].in? [false, nil]
|
55
|
+
# end
|
56
|
+
|
57
|
+
decorate :no_git do
|
58
|
+
options[:git].in? [false, nil]
|
59
|
+
end
|
60
|
+
|
61
|
+
unless Dir.exists? target
|
62
|
+
FileUtils.mkpath target
|
63
|
+
end
|
64
|
+
Dir.chdir target
|
65
|
+
self.bundler_gem = File.basename(target)
|
66
|
+
|
67
|
+
case
|
68
|
+
when (no_gem and no_bundle)
|
69
|
+
add_basics if Dir.empty?
|
70
|
+
when no_gem
|
71
|
+
case
|
72
|
+
when Dir.empty?
|
73
|
+
add_basics and add_bundle
|
74
|
+
else
|
75
|
+
add_basics
|
76
|
+
add_bundle unless Dir.bundle?
|
77
|
+
end
|
78
|
+
|
79
|
+
when no_bundle
|
80
|
+
case
|
81
|
+
when Dir.empty?
|
82
|
+
no_bundle_gem
|
83
|
+
when Dir.simple?
|
84
|
+
if Dir.bundle?
|
85
|
+
bundle_gem
|
86
|
+
else
|
87
|
+
no_bundle_gem
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
case
|
92
|
+
when Dir.empty?
|
93
|
+
bundle_gem
|
94
|
+
else
|
95
|
+
no_bundle_gem unless Dir.gem?
|
96
|
+
add_bundle unless Dir.bundle?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
add_rakefile unless rakefile
|
100
|
+
add_git unless Dir.exists?('.git') or no_git
|
101
|
+
|
102
|
+
if Dir.bundle?
|
103
|
+
add_line to: gemfile, format: bundler
|
104
|
+
end
|
105
|
+
add_line to: topfile if topfile
|
106
|
+
add_line to: rakefile, format: rake
|
107
|
+
add_line to: rakefile, format: bundle_rake if Dir.gem?
|
108
|
+
end
|
109
|
+
default_task :stage
|
110
|
+
|
111
|
+
|
112
|
+
no_commands {
|
113
|
+
|
114
|
+
# file specifiers
|
115
|
+
def gemfile
|
116
|
+
'Gemfile' if File.exists?('Gemfile')
|
117
|
+
end
|
118
|
+
def rakefile
|
119
|
+
'Rakefile' if File.exists?('Rakefile')
|
120
|
+
end
|
121
|
+
def topfile
|
122
|
+
(
|
123
|
+
[] <<
|
124
|
+
File.join('lib', File.basename(Dir.pwd)+'.rb') <<
|
125
|
+
Dir['**/*.rb'].group_by {|g| g.scan('/').size}.values.sort <<
|
126
|
+
File.basename(Dir.pwd) <<
|
127
|
+
File.join('bin', File.basename(Dir.pwd))
|
128
|
+
)
|
129
|
+
.flatten.select { |file| File.exists?(file) and file }.first
|
130
|
+
end
|
131
|
+
|
132
|
+
# format specifiers
|
133
|
+
def bundler
|
134
|
+
["\ngem 'rspec'\ngem 'jackbox'\n\n", "\ngem \"rspec\"\ngem \"jackbox\"\n\n"]
|
135
|
+
end
|
136
|
+
def required
|
137
|
+
["\nrequire 'jackbox'\n", "\nrequire \"jackbox\"\n"]
|
138
|
+
end
|
139
|
+
def rake
|
140
|
+
["\nrequire 'jackbox/rake'\n", "\nrequire \"jackbox/rake\"\n"]
|
141
|
+
end
|
142
|
+
def bundle_rake
|
143
|
+
["require 'bundler/gem_tasks'\n", "require \"bundler/gem_tasks\"\n"]
|
144
|
+
end
|
145
|
+
|
146
|
+
# helpers
|
147
|
+
def rfolder
|
148
|
+
"#{ENV['HOME']}/tmp/jackup/#{(0...10).map { ('a'..'z').to_a[rand(26)] }.join}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def bundler_gem= basename
|
152
|
+
tdir = rfolder()
|
153
|
+
@bundler_gem = File.join(tdir, basename)
|
154
|
+
Dir.new(tdir) do
|
155
|
+
current = Dir.pwd
|
156
|
+
Dir.chdir tdir
|
157
|
+
system "bundle gem #{basename}", :out => "#{ENV['HOME']}/tmp/nul", :err => :out
|
158
|
+
Dir.chdir current
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def bundler_gem
|
163
|
+
@bundler_gem
|
164
|
+
end
|
165
|
+
|
166
|
+
# actions
|
167
|
+
def bundle_gem
|
168
|
+
# move gemfile to target unless target gemfile
|
169
|
+
FileUtils.cp "#{bundler_gem}/Gemfile", '.' unless File.exists?("Gemfile")
|
170
|
+
no_bundle_gem
|
171
|
+
end
|
172
|
+
|
173
|
+
def no_bundle_gem
|
174
|
+
basename = File.basename(self.bundler_gem)
|
175
|
+
# move gemspec to target unless target gemspec
|
176
|
+
FileUtils.cp "#{bundler_gem}/#{basename}.gemspec", '.' unless File.exists?("#{basename}.gemspec")
|
177
|
+
add_basics
|
178
|
+
end
|
179
|
+
|
180
|
+
def add_basics
|
181
|
+
basename = File.basename(self.bundler_gem)
|
182
|
+
# make lib unless lib
|
183
|
+
Dir.new("lib") unless Dir.exists?("lib")
|
184
|
+
# write lib/target.rb unless lib/target.rb
|
185
|
+
FileUtils.cp "#{bundler_gem}/lib/#{basename}.rb", "lib/#{basename}.rb" unless File.exists?("lib/#{basename}.rb")
|
186
|
+
# make lib/target unless lib/target
|
187
|
+
Dir.new("lib/#{basename}") unless Dir.exists?("lib/#{basename}")
|
188
|
+
# write lib/target/version.rb unless lib/target/version.rb
|
189
|
+
FileUtils.cp "#{bundler_gem}/lib/#{basename}/version.rb", "lib/#{basename}/version.rb" unless File.exists?("lib/#{basename}/version.rb")
|
190
|
+
# make bin and write bin/target if --bin unless bin or bin/target
|
191
|
+
|
192
|
+
# make test dir and wrtie test_helper
|
193
|
+
framework = `gem list`.match(/rspec/).nil? ? 'test' : 'spec'
|
194
|
+
Dir.new(framework) and open "#{framework}/#{framework}_helper.rb", 'w+' do |file|
|
195
|
+
file.puts "\n# Insert your #{framework} helpers here"
|
196
|
+
end unless Dir.exists?('spec') or Dir.exists?('test') #or no_testing
|
197
|
+
framework
|
198
|
+
end
|
199
|
+
|
200
|
+
def add_bundle
|
201
|
+
FileUtils.cp "#{bundler_gem}/Gemfile", '.'
|
202
|
+
end
|
203
|
+
|
204
|
+
def add_rakefile
|
205
|
+
FileUtils.touch 'Rakefile'
|
206
|
+
end
|
207
|
+
|
208
|
+
def add_git
|
209
|
+
# move git directory if git unless existing
|
210
|
+
FileUtils.cp_r "#{bundler_gem}/.git/.", '.git' if `git`.match('usage: git') unless Dir.exists?('.git') #or no_git
|
211
|
+
end
|
212
|
+
|
213
|
+
def add_line(spec)
|
214
|
+
open spec[:to], 'r+' do |file|
|
215
|
+
lines = file.readlines
|
216
|
+
file.rewind
|
217
|
+
|
218
|
+
index = 0
|
219
|
+
# look for the first 'require' line in file
|
220
|
+
lines.each_with_index { |line, i|
|
221
|
+
if line.match(/^require/).nil?
|
222
|
+
break if index != i
|
223
|
+
index = i + 1
|
224
|
+
next
|
225
|
+
else
|
226
|
+
index = i
|
227
|
+
end
|
228
|
+
}
|
229
|
+
# insert our line after check to see not already there
|
230
|
+
with lines do
|
231
|
+
format = spec[:format] || required
|
232
|
+
unless join.match(Regexp.new(format.join('|')))
|
233
|
+
insert(
|
234
|
+
index && index + 1 || 0, format.last
|
235
|
+
)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
file.write lines.join
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
}
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
Jackup.start(ARGV) #if $0 == __FILE__
|
248
|
+
|
data/jackbox.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jackbox/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
|
8
|
+
spec.name = "jackbox"
|
9
|
+
spec.version = Jackbox::VERSION
|
10
|
+
spec.authors = ["Lou Henry Alvarez (LHA)"]
|
11
|
+
spec.email = ["luisealvarezb@yahoo.com"]
|
12
|
+
spec.description = %q{Main gem for Ruby Code Injectors: Closures as Modules}
|
13
|
+
spec.summary = %q{Jackbox is a set of programming tools which enhance the Ruby language and provide some additional software constructs. The main library function at this time centers around the concept of code injectors. }
|
14
|
+
spec.homepage = "http://jackbox.us"
|
15
|
+
spec.license = %Q{Copyright © 2014, 2015 LHA. All rights reserved. See LICENSE.txt}
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_runtime_dependency "bundler", '>= 1.6.1', "~> 1.6"
|
23
|
+
spec.add_runtime_dependency 'thor', '>= 0.18.1', '~> 0.18'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'rspec', '>= 3.1.0', '~> 3.1'
|
26
|
+
|
27
|
+
end
|
data/jackbox.jpg
ADDED
Binary file
|
data/lib/.document
ADDED
File without changes
|
data/lib/jackbox.rb
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
# RubyEncoder v2.2.1
|
2
|
+
_d = _d0 = File.expand_path(File.dirname(__FILE__)); while 1 do _f = _d + '/rgloader/loader.rb'; break if File.exist?(_f); _d1 = File.dirname(_d); if _d1 == _d then raise "Ruby script '"+__FILE__+"' is protected by RubyEncoder and requires a RubyEncoder loader to be installed. Please visit the http://www.rubyencoder.com/loaders/ RubyEncoder web site to download the required loader and unpack it into '"+_d0+"/rgloader/' directory in order to run this protected file."; exit; else _d = _d1; end; end; require _f; RGLoader_load('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');
|
@@ -0,0 +1,80 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Copyright © 2014 LHA. All rights reserved.
|
4
|
+
|
5
|
+
Dir class extensions
|
6
|
+
|
7
|
+
=end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Modifies Dir to include some methods found useful by the author
|
11
|
+
# * New now really means #new, aka a new directory is created
|
12
|
+
# * Adds some more predicates to Dir class
|
13
|
+
# * Adds more contents listing methods and changes some defaults
|
14
|
+
# * #entries has a default to listing entries in pwd
|
15
|
+
class Dir
|
16
|
+
|
17
|
+
#
|
18
|
+
# Methods for Dir singleton
|
19
|
+
#
|
20
|
+
with singleton_class do
|
21
|
+
|
22
|
+
#:doc:
|
23
|
+
decorate :entries do |name='.', opts=nil|
|
24
|
+
super name, opts # use of super
|
25
|
+
end
|
26
|
+
|
27
|
+
#:doc:
|
28
|
+
decorate :new do |name, &code|
|
29
|
+
FileUtils.mkpath name unless exists?(name)
|
30
|
+
return Dir.open(name, &code) if code
|
31
|
+
Dir.open name
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns true when a <dir> exists
|
35
|
+
def exists? dir
|
36
|
+
File.exists? dir and File.directory? dir
|
37
|
+
end
|
38
|
+
alias exist? exists?
|
39
|
+
|
40
|
+
# return true when reciver has a gem layout
|
41
|
+
def gem?
|
42
|
+
Dir['*.gemspec'].size > 0 &&
|
43
|
+
Dir.exists?( 'lib' )&&
|
44
|
+
File.exists?( File.join('lib', File.basename(pwd) + '.rb') )&&
|
45
|
+
Dir.exists?( File.join('lib', File.basename(pwd)) )&&
|
46
|
+
File.exists?( File.join('lib', File.basename(pwd), 'version.rb'))
|
47
|
+
end
|
48
|
+
|
49
|
+
# true if receiver is completely clear of all entries (including .files)
|
50
|
+
def clear?
|
51
|
+
Dir.entries('.') == ['.', '..']
|
52
|
+
end
|
53
|
+
|
54
|
+
# true when receiver is empty of normal files and dirs
|
55
|
+
def empty?
|
56
|
+
Dir['*'].empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
lets patherize =->(pattern){
|
60
|
+
pattern = "#{pattern}/*" if Dir.exists?(pattern)
|
61
|
+
pattern
|
62
|
+
}
|
63
|
+
|
64
|
+
# lists files and dirs in receiver as [array]
|
65
|
+
lets :ls do |pattern='*'|
|
66
|
+
Dir.glob patherize[pattern]
|
67
|
+
end
|
68
|
+
|
69
|
+
# alias for ls used with pry name clash
|
70
|
+
alias :list :ls
|
71
|
+
|
72
|
+
# lists all files and dir in receiver (including .files) as [array]
|
73
|
+
lets :la do |pattern='*'|
|
74
|
+
Dir.glob patherize[pattern], File::FNM_DOTMATCH
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
require 'shellwords'
|
3
|
+
=begin rdoc
|
4
|
+
|
5
|
+
Copyright © 2014 LHA. All rights reserved.
|
6
|
+
|
7
|
+
Debugger Extras:
|
8
|
+
|
9
|
+
We want a methodology to load some very basic debugging help over and beyond the trickery of print and puts statements
|
10
|
+
under current normal use or that somehow crystalizes those current practices and enhances them with some helpful
|
11
|
+
additions like printing program state info and line number. We also want the ability to call on the debugger at any
|
12
|
+
point without much a-do, or to even automatically break into the debugger on Exception or other condition, and it has
|
13
|
+
to be system independent, working with all versions of ruby.
|
14
|
+
|
15
|
+
=end
|
16
|
+
require "jackbox/injectors"
|
17
|
+
|
18
|
+
|
19
|
+
include Injectors
|
20
|
+
|
21
|
+
|
22
|
+
require 'logger'
|
23
|
+
if RUBY_VERSION < '2.0.0'
|
24
|
+
DEBUGGER = 'debugger'
|
25
|
+
else
|
26
|
+
DEBUGGER = 'byebug'
|
27
|
+
end
|
28
|
+
require DEBUGGER
|
29
|
+
|
30
|
+
module Jackbox
|
31
|
+
module Examples
|
32
|
+
#
|
33
|
+
# Debugging Extras
|
34
|
+
#
|
35
|
+
module DX
|
36
|
+
#
|
37
|
+
# Methods to log program or system level information
|
38
|
+
#
|
39
|
+
injector :logger do
|
40
|
+
|
41
|
+
# open a logger
|
42
|
+
def log= log
|
43
|
+
@xd_log = log or raise Exception
|
44
|
+
end
|
45
|
+
# set the logger level
|
46
|
+
def level= level
|
47
|
+
@so_log.level = level rescue @xd_log.level = level
|
48
|
+
end
|
49
|
+
# print to logger with DEBUG level
|
50
|
+
def log file=true, frame=0, msg
|
51
|
+
with "#{msg}\n \@\[#{$0}\:#{caller[frame]}\]\n#{@_trace}" do
|
52
|
+
xd_out(file).debug(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
# logs to the system log
|
56
|
+
case
|
57
|
+
when OS.windows?
|
58
|
+
def syslog file=false, frame=1, msg
|
59
|
+
raise ArgumentError unless system(
|
60
|
+
"eventcreate /T ERROR /ID #{rand(1000)} /L APPLICATION /SO #{File.basename $0} /D \"#{self.log(file, frame, msg)}\"")
|
61
|
+
end
|
62
|
+
else
|
63
|
+
def syslog file=false, frame=1, msg
|
64
|
+
raise ArgumentError unless system("logger -i #{self.log(file, frame, msg).shellescape}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
# asserts a file was loaded
|
68
|
+
def assert_loaded file=__FILE__
|
69
|
+
self.log file + ' was loaded!!'
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def xd_out file
|
74
|
+
unless $DEBUG == true or file == false
|
75
|
+
@xd_log ||= Logger.new("#{File.basename($0)}.log")
|
76
|
+
else
|
77
|
+
@so_log ||= Logger.new($stdout)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
enrich logger
|
83
|
+
|
84
|
+
#
|
85
|
+
# Methods to stop normal execution and enter the debugger
|
86
|
+
#
|
87
|
+
injector :splatter do
|
88
|
+
|
89
|
+
extend DX.logger
|
90
|
+
# break to debugger on Excetion type
|
91
|
+
def seize log=false, type
|
92
|
+
type.decorate :initialize do |*args|
|
93
|
+
step_up = 1
|
94
|
+
step_up = 3 unless caller.grep(/injectors.rb.+?method_missing/).empty?
|
95
|
+
if log
|
96
|
+
DX.syslog( false, step_up + 1, type )
|
97
|
+
end
|
98
|
+
DX.debug(step_up)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#call the debugger
|
103
|
+
if RUBY_VERSION < '2.0.0'
|
104
|
+
alias _debug debugger
|
105
|
+
else
|
106
|
+
alias _debug byebug
|
107
|
+
end
|
108
|
+
private :_debug
|
109
|
+
def debug *args
|
110
|
+
puts "\n\n", @_trace
|
111
|
+
_debug(2 + args.first) rescue _debug(2)
|
112
|
+
end
|
113
|
+
alias splat debug
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
enrich splatter
|
118
|
+
|
119
|
+
#
|
120
|
+
# singleton methods
|
121
|
+
#
|
122
|
+
class << self
|
123
|
+
|
124
|
+
attr_accessor :tracer
|
125
|
+
|
126
|
+
def included(klass)
|
127
|
+
# raise TypeError, 'DX not allowed in: Object' if klass == Object
|
128
|
+
set_trace_func proc { |event, file, line, id, binding, classname|
|
129
|
+
DX.tracer.resume(binding) if event == 'call' and id.in?(klass.instance_methods) rescue nil
|
130
|
+
}
|
131
|
+
|
132
|
+
klass.instance_methods(false).each do |existing_method|
|
133
|
+
wrap(klass, existing_method)
|
134
|
+
end
|
135
|
+
|
136
|
+
def klass.method_added(method) # note: nested definition
|
137
|
+
unless @trace_calls_internal
|
138
|
+
@trace_calls_internal = true
|
139
|
+
DX.wrap(self, method)
|
140
|
+
@trace_calls_internal = false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def wrap(klass, method)
|
146
|
+
klass.instance_eval do
|
147
|
+
method_object = instance_method(method)
|
148
|
+
|
149
|
+
define_method(method) do |*args, &block|
|
150
|
+
DX.tracer = Fiber.new do |binding|
|
151
|
+
Fiber.yield
|
152
|
+
lnames, inames = binding.eval("local_variables"), binding.eval("instance_variables")
|
153
|
+
lvars, ivars = [lnames, inames].map{ |names|
|
154
|
+
names.inject({}) { |vars, name| vars[name] = binding.eval(name.to_s) and vars } rescue nil
|
155
|
+
}
|
156
|
+
@_trace = %{ -local variables: #{lvars}\n -instance variables: #{ivars}\n }
|
157
|
+
end
|
158
|
+
result = method_object.bind(self).call(*args, &block)
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
inject logger
|
167
|
+
inject splatter
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
include Jackbox::Examples
|
173
|
+
|
174
|
+
def splat *args
|
175
|
+
DX.splat( 1 + args.first ) rescue DX.splat(1)
|
176
|
+
end
|
177
|
+
|
178
|
+
# def log *args
|
179
|
+
# DX.log
|
180
|
+
# end
|
181
|
+
|
182
|
+
DX.assert_loaded
|