xpflow 0.1b
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/xpflow +96 -0
- data/lib/colorado.rb +198 -0
- data/lib/json/add/core.rb +243 -0
- data/lib/json/add/rails.rb +8 -0
- data/lib/json/common.rb +423 -0
- data/lib/json/editor.rb +1369 -0
- data/lib/json/ext.rb +28 -0
- data/lib/json/pure/generator.rb +442 -0
- data/lib/json/pure/parser.rb +320 -0
- data/lib/json/pure.rb +15 -0
- data/lib/json/version.rb +8 -0
- data/lib/json.rb +62 -0
- data/lib/mime/types.rb +881 -0
- data/lib/mime-types.rb +3 -0
- data/lib/restclient/abstract_response.rb +106 -0
- data/lib/restclient/exceptions.rb +193 -0
- data/lib/restclient/net_http_ext.rb +55 -0
- data/lib/restclient/payload.rb +235 -0
- data/lib/restclient/raw_response.rb +34 -0
- data/lib/restclient/request.rb +316 -0
- data/lib/restclient/resource.rb +169 -0
- data/lib/restclient/response.rb +24 -0
- data/lib/restclient.rb +174 -0
- data/lib/xpflow/bash.rb +341 -0
- data/lib/xpflow/bundle.rb +113 -0
- data/lib/xpflow/cmdline.rb +249 -0
- data/lib/xpflow/collection.rb +122 -0
- data/lib/xpflow/concurrency.rb +79 -0
- data/lib/xpflow/data.rb +393 -0
- data/lib/xpflow/dsl.rb +816 -0
- data/lib/xpflow/engine.rb +574 -0
- data/lib/xpflow/ensemble.rb +135 -0
- data/lib/xpflow/events.rb +56 -0
- data/lib/xpflow/experiment.rb +65 -0
- data/lib/xpflow/exts/facter.rb +30 -0
- data/lib/xpflow/exts/g5k.rb +931 -0
- data/lib/xpflow/exts/g5k_use.rb +50 -0
- data/lib/xpflow/exts/gui.rb +140 -0
- data/lib/xpflow/exts/model.rb +155 -0
- data/lib/xpflow/graph.rb +1603 -0
- data/lib/xpflow/graph_xpflow.rb +251 -0
- data/lib/xpflow/import.rb +196 -0
- data/lib/xpflow/library.rb +349 -0
- data/lib/xpflow/logging.rb +153 -0
- data/lib/xpflow/manager.rb +147 -0
- data/lib/xpflow/nodes.rb +1250 -0
- data/lib/xpflow/runs.rb +773 -0
- data/lib/xpflow/runtime.rb +125 -0
- data/lib/xpflow/scope.rb +168 -0
- data/lib/xpflow/ssh.rb +186 -0
- data/lib/xpflow/stat.rb +50 -0
- data/lib/xpflow/stdlib.rb +381 -0
- data/lib/xpflow/structs.rb +369 -0
- data/lib/xpflow/taktuk.rb +193 -0
- data/lib/xpflow/templates/ssh-config.basic +14 -0
- data/lib/xpflow/templates/ssh-config.inria +18 -0
- data/lib/xpflow/templates/ssh-config.proxy +13 -0
- data/lib/xpflow/templates/taktuk +6590 -0
- data/lib/xpflow/templates/utils/batch +4 -0
- data/lib/xpflow/templates/utils/bootstrap +12 -0
- data/lib/xpflow/templates/utils/hostname +3 -0
- data/lib/xpflow/templates/utils/ping +3 -0
- data/lib/xpflow/templates/utils/rsync +12 -0
- data/lib/xpflow/templates/utils/scp +17 -0
- data/lib/xpflow/templates/utils/scp_many +8 -0
- data/lib/xpflow/templates/utils/ssh +3 -0
- data/lib/xpflow/templates/utils/ssh-interactive +4 -0
- data/lib/xpflow/templates/utils/taktuk +19 -0
- data/lib/xpflow/threads.rb +187 -0
- data/lib/xpflow/utils.rb +569 -0
- data/lib/xpflow/visual.rb +230 -0
- data/lib/xpflow/with_g5k.rb +7 -0
- data/lib/xpflow.rb +349 -0
- metadata +135 -0
data/bin/xpflow
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# Runs xpflow script
|
4
|
+
|
5
|
+
require('pathname')
|
6
|
+
|
7
|
+
def realpath(x)
|
8
|
+
Pathname.new(x).realpath.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
# code that magically switches ruby interpreter
|
12
|
+
if ENV.key?("__RUBY__")
|
13
|
+
__ruby__ = ENV["__RUBY__"]
|
14
|
+
__here__ = realpath(__FILE__)
|
15
|
+
ENV.delete("__RUBY__") # avoid infinite loop
|
16
|
+
begin
|
17
|
+
exec(__ruby__, __here__, *ARGV)
|
18
|
+
rescue Errno::ENOENT => e
|
19
|
+
puts "Could not launch with custom Ruby (#{e})."
|
20
|
+
end
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_lib_dir
|
25
|
+
f = __FILE__
|
26
|
+
f = File.readlink(f) if File.symlink?(f)
|
27
|
+
p = Pathname.new(File.dirname(f))
|
28
|
+
lib = File.join(p.realpath, '..', 'lib')
|
29
|
+
return Pathname.new(lib).realpath.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
$:.unshift(get_lib_dir)
|
33
|
+
|
34
|
+
#XSTART
|
35
|
+
require 'xpflow'
|
36
|
+
#XEND
|
37
|
+
|
38
|
+
def usage
|
39
|
+
puts "XPFlow (running on Ruby #{RUBY_VERSION})"
|
40
|
+
puts
|
41
|
+
puts "Usage:"
|
42
|
+
puts " xpflow <cmd> <workflow> [OPTIONS]"
|
43
|
+
puts
|
44
|
+
puts "Standard commands:"
|
45
|
+
puts " xpflow run <workflow> - run a workflow"
|
46
|
+
puts
|
47
|
+
end
|
48
|
+
|
49
|
+
def use(*args)
|
50
|
+
|
51
|
+
# TODO: this should be more sophisticated
|
52
|
+
# for now it's so so
|
53
|
+
|
54
|
+
args.each do |lib|
|
55
|
+
require "xpflow/exts/#{lib.to_s}_use"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if true
|
60
|
+
|
61
|
+
$original_argv = ARGV.clone
|
62
|
+
|
63
|
+
begin
|
64
|
+
$cmdline_options = XPFlow::Options.new(ARGV.dup)
|
65
|
+
$variables = $cmdline_options.vars
|
66
|
+
$engine.init_from_options($cmdline_options)
|
67
|
+
rescue XPFlow::CmdlineError => e
|
68
|
+
if e.ignore?
|
69
|
+
exit 0
|
70
|
+
else
|
71
|
+
Kernel.puts "Error while parsing cmdline: #{e}"
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
$cmdline_options.includes.each do |filename|
|
77
|
+
filename = realpath(filename)
|
78
|
+
require(filename)
|
79
|
+
end
|
80
|
+
|
81
|
+
ok = nil
|
82
|
+
begin
|
83
|
+
XPFlow::TerminalThread.start_thread
|
84
|
+
_, ok = $cmdline_options.dispatch($engine)
|
85
|
+
rescue => e
|
86
|
+
Kernel.puts "Error while running : #{e}."
|
87
|
+
if $cmdline_options.verbose?
|
88
|
+
Kernel.puts "Backtrace:"
|
89
|
+
e.backtrace.each do |line|
|
90
|
+
Kernel.puts(" " + line)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ok = false
|
94
|
+
end
|
95
|
+
exit(ok ? 0 : 1)
|
96
|
+
end
|
data/lib/colorado.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
|
2
|
+
# This simple library allows you to use
|
3
|
+
# colors with strings
|
4
|
+
|
5
|
+
module Colorado
|
6
|
+
|
7
|
+
COLORS = {
|
8
|
+
:red => 31,
|
9
|
+
:green => 32,
|
10
|
+
:yellow => 33,
|
11
|
+
:blue => 34,
|
12
|
+
:violet => 35,
|
13
|
+
:magenta => 36,
|
14
|
+
:white => 37,
|
15
|
+
:normal => 0
|
16
|
+
}
|
17
|
+
|
18
|
+
KEYS = COLORS.keys + COLORS.keys.map { |c| "#{c}!" }
|
19
|
+
|
20
|
+
module StringMix
|
21
|
+
|
22
|
+
Colorado::KEYS.each do |color|
|
23
|
+
define_method(color) do
|
24
|
+
return Colorado::Str.new(self, color)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
module BaseMix
|
31
|
+
|
32
|
+
Colorado::KEYS.each do |color|
|
33
|
+
define_method(color) do
|
34
|
+
return self.plain.send(:color)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class Color
|
41
|
+
|
42
|
+
attr_reader :bold
|
43
|
+
attr_reader :color
|
44
|
+
|
45
|
+
def initialize(c)
|
46
|
+
@color = (c.is_a?(Color) ? c.color : c)
|
47
|
+
@bold = @color.to_s.end_with?('!')
|
48
|
+
@index = @color.to_s.chomp('!').to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
def code
|
52
|
+
return COLORS[@index]
|
53
|
+
end
|
54
|
+
|
55
|
+
def prefix
|
56
|
+
return '' if @index == :normal
|
57
|
+
return (@bold ? "\e[#{code};1m" : "\e[#{code}m")
|
58
|
+
end
|
59
|
+
|
60
|
+
def suffix
|
61
|
+
return '' if @index == :normal
|
62
|
+
return "\e[0m"
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
return @color.to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
def normal?
|
70
|
+
return @index == :normal
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
class Base
|
76
|
+
|
77
|
+
include BaseMix
|
78
|
+
|
79
|
+
attr_reader :color
|
80
|
+
|
81
|
+
def initialize(color)
|
82
|
+
@color = Color.new(color)
|
83
|
+
end
|
84
|
+
|
85
|
+
def +(s)
|
86
|
+
s = Str.new(s) if s.is_a?(String)
|
87
|
+
return Group.new(self.parts + s.parts)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
class Str < Base
|
93
|
+
|
94
|
+
def initialize(s, color = :normal)
|
95
|
+
super(color)
|
96
|
+
raise "Already colorized: #{s}" if Colorado.colorized(s)
|
97
|
+
@s = s.to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
def inspect
|
101
|
+
"<'#{@s}' in #{@color}>"
|
102
|
+
end
|
103
|
+
|
104
|
+
def plain
|
105
|
+
return @s
|
106
|
+
end
|
107
|
+
|
108
|
+
def parts
|
109
|
+
return [ self ]
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_s
|
113
|
+
return "#{color.prefix}#{@s}#{color.suffix}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Group < Base
|
118
|
+
|
119
|
+
def initialize(array)
|
120
|
+
super(:normal)
|
121
|
+
@array = array
|
122
|
+
end
|
123
|
+
|
124
|
+
def exec(method)
|
125
|
+
return @array.map { |it| it.send(method) }
|
126
|
+
end
|
127
|
+
|
128
|
+
def parts
|
129
|
+
return exec(:parts).reduce(:+)
|
130
|
+
end
|
131
|
+
|
132
|
+
def plain
|
133
|
+
return exec(:plain).reduce(:+)
|
134
|
+
end
|
135
|
+
|
136
|
+
def inspect
|
137
|
+
return parts.inspect
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_s
|
141
|
+
return exec(:to_s).reduce(:+)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.substitute(fmt, array)
|
147
|
+
parts = fmt.split(/%(.)/)
|
148
|
+
strings = []
|
149
|
+
idx = 0
|
150
|
+
parts.each_index do |i|
|
151
|
+
s = parts[i]
|
152
|
+
if i.even? # normal string
|
153
|
+
next if s == ''
|
154
|
+
strings.push(Str.new(s))
|
155
|
+
else
|
156
|
+
if s == 's'
|
157
|
+
strings.push(fix(array[idx]))
|
158
|
+
idx += 1
|
159
|
+
elsif s == '%'
|
160
|
+
strings.push(fix('%'))
|
161
|
+
else
|
162
|
+
raise "Error!"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
return Group.new(strings)
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.fix(x)
|
170
|
+
return x if x.is_a?(Base)
|
171
|
+
return Str.new(x.to_s)
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.colorized(s)
|
175
|
+
return (!s.is_a?(Base) && s.to_s.include?("\e"))
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
class String
|
181
|
+
|
182
|
+
include Colorado::StringMix
|
183
|
+
|
184
|
+
alias old_addition :+
|
185
|
+
alias old_modulo :%
|
186
|
+
|
187
|
+
def +(x)
|
188
|
+
return Colorado::Str.new(self) + x if x.is_a?(Colorado::Base)
|
189
|
+
return old_addition(x)
|
190
|
+
end
|
191
|
+
|
192
|
+
def %(x)
|
193
|
+
return Colorado.substitute(self, [x]) if x.is_a?(Colorado::Base)
|
194
|
+
return Colorado.substitute(self, x) if (x.is_a?(Array) && x.any? { |el| el.is_a?(Colorado::Base) } )
|
195
|
+
return old_modulo(x)
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# This file contains implementations of ruby core's custom objects for
|
2
|
+
# serialisation/deserialisation.
|
3
|
+
|
4
|
+
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
5
|
+
require 'json'
|
6
|
+
end
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
# Symbol serialization/deserialization
|
10
|
+
class Symbol
|
11
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
12
|
+
# object.
|
13
|
+
def as_json(*)
|
14
|
+
{
|
15
|
+
JSON.create_id => self.class.name,
|
16
|
+
's' => to_s,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Stores class name (Symbol) with String representation of Symbol as a JSON string.
|
21
|
+
def to_json(*a)
|
22
|
+
as_json.to_json(*a)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol
|
26
|
+
def self.json_create(o)
|
27
|
+
o['s'].to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Time serialization/deserialization
|
32
|
+
class Time
|
33
|
+
|
34
|
+
# Deserializes JSON string by converting time since epoch to Time
|
35
|
+
def self.json_create(object)
|
36
|
+
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
|
37
|
+
object['n'] = usec * 1000
|
38
|
+
end
|
39
|
+
if respond_to?(:tv_nsec)
|
40
|
+
at(*object.values_at('s', 'n'))
|
41
|
+
else
|
42
|
+
at(object['s'], object['n'] / 1000)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
47
|
+
# object.
|
48
|
+
def as_json(*)
|
49
|
+
{
|
50
|
+
JSON.create_id => self.class.name,
|
51
|
+
's' => tv_sec,
|
52
|
+
'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
# Stores class name (Time) with number of seconds since epoch and number of
|
57
|
+
# microseconds for Time as JSON string
|
58
|
+
def to_json(*args)
|
59
|
+
as_json.to_json(*args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Date serialization/deserialization
|
64
|
+
class Date
|
65
|
+
|
66
|
+
# Deserializes JSON string by converting Julian year <tt>y</tt>, month
|
67
|
+
# <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
|
68
|
+
def self.json_create(object)
|
69
|
+
civil(*object.values_at('y', 'm', 'd', 'sg'))
|
70
|
+
end
|
71
|
+
|
72
|
+
alias start sg unless method_defined?(:start)
|
73
|
+
|
74
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
75
|
+
# object.
|
76
|
+
def as_json(*)
|
77
|
+
{
|
78
|
+
JSON.create_id => self.class.name,
|
79
|
+
'y' => year,
|
80
|
+
'm' => month,
|
81
|
+
'd' => day,
|
82
|
+
'sg' => start,
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
# Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
|
87
|
+
# <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
|
88
|
+
def to_json(*args)
|
89
|
+
as_json.to_json(*args)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# DateTime serialization/deserialization
|
94
|
+
class DateTime
|
95
|
+
|
96
|
+
# Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
|
97
|
+
# day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
|
98
|
+
# offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
|
99
|
+
def self.json_create(object)
|
100
|
+
args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
|
101
|
+
of_a, of_b = object['of'].split('/')
|
102
|
+
if of_b and of_b != '0'
|
103
|
+
args << Rational(of_a.to_i, of_b.to_i)
|
104
|
+
else
|
105
|
+
args << of_a
|
106
|
+
end
|
107
|
+
args << object['sg']
|
108
|
+
civil(*args)
|
109
|
+
end
|
110
|
+
|
111
|
+
alias start sg unless method_defined?(:start)
|
112
|
+
|
113
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
114
|
+
# object.
|
115
|
+
def as_json(*)
|
116
|
+
{
|
117
|
+
JSON.create_id => self.class.name,
|
118
|
+
'y' => year,
|
119
|
+
'm' => month,
|
120
|
+
'd' => day,
|
121
|
+
'H' => hour,
|
122
|
+
'M' => min,
|
123
|
+
'S' => sec,
|
124
|
+
'of' => offset.to_s,
|
125
|
+
'sg' => start,
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
# Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
|
130
|
+
# day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
|
131
|
+
# offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
|
132
|
+
def to_json(*args)
|
133
|
+
as_json.to_json(*args)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Range serialization/deserialization
|
138
|
+
class Range
|
139
|
+
|
140
|
+
# Deserializes JSON string by constructing new Range object with arguments
|
141
|
+
# <tt>a</tt> serialized by <tt>to_json</tt>.
|
142
|
+
def self.json_create(object)
|
143
|
+
new(*object['a'])
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
147
|
+
# object.
|
148
|
+
def as_json(*)
|
149
|
+
{
|
150
|
+
JSON.create_id => self.class.name,
|
151
|
+
'a' => [ first, last, exclude_end? ]
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
# Stores class name (Range) with JSON array of arguments <tt>a</tt> which
|
156
|
+
# include <tt>first</tt> (integer), <tt>last</tt> (integer), and
|
157
|
+
# <tt>exclude_end?</tt> (boolean) as JSON string.
|
158
|
+
def to_json(*args)
|
159
|
+
as_json.to_json(*args)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Struct serialization/deserialization
|
164
|
+
class Struct
|
165
|
+
|
166
|
+
# Deserializes JSON string by constructing new Struct object with values
|
167
|
+
# <tt>v</tt> serialized by <tt>to_json</tt>.
|
168
|
+
def self.json_create(object)
|
169
|
+
new(*object['v'])
|
170
|
+
end
|
171
|
+
|
172
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
173
|
+
# object.
|
174
|
+
def as_json(*)
|
175
|
+
klass = self.class.name
|
176
|
+
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
|
177
|
+
{
|
178
|
+
JSON.create_id => klass,
|
179
|
+
'v' => values,
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
# Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string.
|
184
|
+
# Only named structs are supported.
|
185
|
+
def to_json(*args)
|
186
|
+
as_json.to_json(*args)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Exception serialization/deserialization
|
191
|
+
class Exception
|
192
|
+
|
193
|
+
# Deserializes JSON string by constructing new Exception object with message
|
194
|
+
# <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
|
195
|
+
def self.json_create(object)
|
196
|
+
result = new(object['m'])
|
197
|
+
result.set_backtrace object['b']
|
198
|
+
result
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
202
|
+
# object.
|
203
|
+
def as_json(*)
|
204
|
+
{
|
205
|
+
JSON.create_id => self.class.name,
|
206
|
+
'm' => message,
|
207
|
+
'b' => backtrace,
|
208
|
+
}
|
209
|
+
end
|
210
|
+
|
211
|
+
# Stores class name (Exception) with message <tt>m</tt> and backtrace array
|
212
|
+
# <tt>b</tt> as JSON string
|
213
|
+
def to_json(*args)
|
214
|
+
as_json.to_json(*args)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Regexp serialization/deserialization
|
219
|
+
class Regexp
|
220
|
+
|
221
|
+
# Deserializes JSON string by constructing new Regexp object with source
|
222
|
+
# <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by
|
223
|
+
# <tt>to_json</tt>
|
224
|
+
def self.json_create(object)
|
225
|
+
new(object['s'], object['o'])
|
226
|
+
end
|
227
|
+
|
228
|
+
# Returns a hash, that will be turned into a JSON object and represent this
|
229
|
+
# object.
|
230
|
+
def as_json(*)
|
231
|
+
{
|
232
|
+
JSON.create_id => self.class.name,
|
233
|
+
'o' => options,
|
234
|
+
's' => source,
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
# Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
|
239
|
+
# (Regexp or String) as JSON string
|
240
|
+
def to_json(*)
|
241
|
+
as_json.to_json
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# This file used to implementations of rails custom objects for
|
2
|
+
# serialisation/deserialisation and is obsoleted now.
|
3
|
+
|
4
|
+
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
5
|
+
require 'json'
|
6
|
+
end
|
7
|
+
|
8
|
+
$DEBUG and warn "required json/add/rails which is obsolete now!"
|