sfp 0.2.1 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/sfp/Sfplib.rb CHANGED
@@ -82,6 +82,13 @@ module Sfp
82
82
  c.inherits( sclass )
83
83
  c['_super'] = (sclass.has_key?('_super') ? sclass['_super'].clone : Array.new)
84
84
  c['_super'] << c['_extends']
85
+ if sclass['_finals'].is_a?(Array)
86
+ if c['_finals'].is_a?(Array)
87
+ c['_finals'].concat(sclass['_finals'])
88
+ else
89
+ c['_finals'] = sclass['_finals']
90
+ end
91
+ end
85
92
  }
86
93
  end
87
94
 
@@ -91,22 +98,7 @@ module Sfp
91
98
  end
92
99
 
93
100
  def deep_clone(value)
94
- if value.is_a?(Hash)
95
- result = value.clone
96
- value.each { |k,v|
97
- if k != '_parent'
98
- result[k] = deep_clone(v)
99
- result[k]['_parent'] = result if result[k].is_a?(Hash) and result[k].has_key?('_parent')
100
- end
101
- }
102
- result
103
- elsif value.is_a?(Array)
104
- result = Array.new
105
- value.each { |v| result << deep_clone(v) }
106
- result
107
- else
108
- value
109
- end
101
+ Sfp::Helper.deep_clone(value)
110
102
  end
111
103
  end
112
104
 
@@ -147,11 +139,20 @@ module Sfp
147
139
  not obj.has_key?('_isa') or obj['_isa'] == nil
148
140
  objclass = root.at?(obj['_isa'])
149
141
  if objclass.nil? or objclass.is_a?(Sfp::Unknown) or objclass.is_a?(Sfp::Undefined)
150
- raise Exception, 'Super class is not found: ' + obj['_self'] + ' < ' + obj['_isa']
142
+ raise Exception, "Schema #{obj['_isa']} of object #{obj['_self']} is not found!"
151
143
  end
152
144
  obj.inherits( objclass )
153
145
  obj['_classes'] = (objclass.has_key?('_super') ? objclass['_super'].clone : Array.new)
154
146
  obj['_classes'] << obj['_isa']
147
+
148
+ if objclass['_finals'].is_a?(Array)
149
+ if obj['_finals'].is_a?(Array)
150
+ obj['_finals'].concat(objclass['_finals'])
151
+ else
152
+ obj['_finals'] = objclass['_finals']
153
+ end
154
+ end
155
+
155
156
  return true
156
157
  end
157
158
  end
@@ -163,9 +164,14 @@ module Sfp
163
164
 
164
165
  # Instance of this class will be returned as the value of a non-exist variable
165
166
  class Undefined
166
- attr_accessor :path
167
- def initialize(path=nil); @path = path; end
168
- def to_s; (@path.nil? ? "<sfp::undefined>" : "<sfp::undefined[#{@path}]>"); end
167
+ attr_accessor :path, :type
168
+ def initialize(path=nil, type=nil)
169
+ @path = path
170
+ @type = type
171
+ end
172
+ def to_s
173
+ (@path.nil? ? "<sfp::undefined>" : "<sfp::undefined[#{@path}]>")
174
+ end
169
175
  end
170
176
 
171
177
  # Instance of this class will be return as the value of an unknown variable
@@ -175,6 +181,10 @@ module Sfp
175
181
  def initialize(path=nil); @path = path; end
176
182
  def to_s; (@path.nil? ? "<sfp::unknown>" : "<sfp::unknown[#{@path}]>"); end
177
183
  end
184
+
185
+ class Any
186
+ def to_s; '<sfp::any>'; end
187
+ end
178
188
  end
179
189
 
180
190
  # return a fullpath of reference of this context
data/lib/sfp/parser.rb CHANGED
@@ -6,6 +6,7 @@ module Sfp
6
6
  include Sfp::SasTranslator
7
7
 
8
8
  attr_accessor :root_dir, :home_dir, :conformant
9
+ attr_reader :root
9
10
 
10
11
  def initialize(params={})
11
12
  @root_dir = (params[:root_dir].is_a?(String) ?
@@ -31,6 +32,19 @@ module Sfp
31
32
  @parser_arrays = parser.arrays
32
33
  end
33
34
 
35
+ def to_json(params={})
36
+ return 'null' if @root.nil?
37
+ return Sfp::Helper.to_pretty_json(@root) if params[:pretty]
38
+ return Sfp::Helper.to_json(@root)
39
+ end
40
+
41
+ def self.parse_file(filepath)
42
+ homedir = File.expand_path(File.dirname(filepath))
43
+ parser = Sfp::Parser.new({:home_dir => homedir})
44
+ parser.parse(File.read(filepath))
45
+ parser.root
46
+ end
47
+
34
48
  =begin
35
49
  # Parse SFP file and return its JSON representation
36
50
  def self.parse_file(file)
@@ -103,12 +117,6 @@ module Sfp
103
117
  return Nuri::Sfp.to_json(root)
104
118
  end
105
119
  =end
106
-
107
- def to_json(params={})
108
- return '' if @root.nil?
109
- return Sfp::Helper.to_pretty_json(@root) if params[:pretty]
110
- return Sfp::Helper.to_json(@root)
111
- end
112
120
  end
113
121
 
114
122
  =begin
@@ -1346,7 +1346,7 @@ module Sfp
1346
1346
  value = @init.at?(value) if isref
1347
1347
  type = (isfinal ? self.isa?(value) : self.get_type(name, value, parent))
1348
1348
  if type == nil
1349
- raise Exception, "Unrecognized type of variable: #{var_name}"
1349
+ raise Exception, "Unrecognized type of variable: #{var_name}:#{value.class}"
1350
1350
  else
1351
1351
  value = null_value(type) if value == nil
1352
1352
  isset = true if type[0,1] == '('
@@ -1375,6 +1375,8 @@ module Sfp
1375
1375
  return type if type != nil
1376
1376
  end
1377
1377
  =end
1378
+ return value.type if value.is_a?(Sfp::Undefined)
1379
+
1378
1380
  type = nil
1379
1381
  if parent.has_key?('_isa')
1380
1382
  isa = @main.root.at?(parent['_isa'])
data/lib/sfp.rb CHANGED
@@ -14,8 +14,3 @@ require libdir + '/sfp/SfpLangLexer'
14
14
  require libdir + '/sfp/visitors'
15
15
  require libdir + '/sfp/sas_translator'
16
16
  require libdir + '/sfp/parser'
17
-
18
- require libdir + '/sfp/sas'
19
- require libdir + '/sfp/planner'
20
-
21
- require libdir + '/sfp/executor.rb'
data/sfp.gemspec CHANGED
@@ -1,23 +1,17 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'sfp'
3
- s.version = '0.2.1'
4
- s.date = '2013-05-15'
5
- s.summary = 'SFP Parser and Planner'
6
- s.description = 'A Ruby gem that provides a Ruby API to SFP language parser and ' +
7
- 'SFP planner. It also provides a planner sript to solve a planning problem ' +
8
- 'written in SFP language.'
3
+ s.version = '0.3.4'
4
+ s.date = '2013-07-14'
5
+ s.summary = 'SFP Parser'
6
+ s.description = 'A Ruby API and script for SFP language parser'
9
7
  s.authors = ['Herry']
10
8
  s.email = 'herry13@gmail.com'
11
9
 
12
10
  s.executables << 'sfp'
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- test/*`.split("\n")
15
-
16
- s.files.delete_if { |f| f =~ /linux\-arm/ }
17
-
18
- `git ls-files --exclude=bin/solver/linux-arm/* -- bin/*`.split("\n") { |f| s.executables << f }
11
+ s.files = `git ls-files`.split("\n").select { |n| !(n =~ /^test\/.*/) }
19
12
 
20
13
  s.require_paths = ['lib']
14
+ s.license = 'BSD'
21
15
 
22
16
  s.homepage = 'https://github.com/herry13/sfp-ruby'
23
17
  s.rubyforge_project = 'sfp'
data/src/SfpLang.g CHANGED
@@ -40,11 +40,11 @@ sfp
40
40
  : { self.init }
41
41
  NL* include* header*
42
42
  { self.expand_classes }
43
- (mmutation | object_def NL* | state | constraint | goal_constraint | composite)*
43
+ (object_def NL* | state | constraint | goal_constraint | composite)*
44
44
  ;
45
45
 
46
46
 
47
- mmutation
47
+ /*mmutation
48
48
  : reference equals_op value NL+
49
49
  {
50
50
  path, var = $reference.val.extract
@@ -60,6 +60,7 @@ mmutation
60
60
  parent[var] = self.null_value
61
61
  }
62
62
  ;
63
+ */
63
64
 
64
65
  include
65
66
  : 'include' include_file NL+
@@ -136,6 +137,17 @@ extends_class returns [val]
136
137
  ;
137
138
 
138
139
  attribute
140
+ : {
141
+ @is_final = false
142
+ @now['_finals'] = [] if !@now.has_key? '_finals'
143
+ }
144
+ ('final' { @is_final = true })? attribute_stmt
145
+ {
146
+ @now['_finals'] << $attribute_stmt.id if @is_final and !$attribute_stmt.id.nil?
147
+ }
148
+ ;
149
+
150
+ attribute_stmt returns [id]
139
151
  : ID equals_op value NL+
140
152
  {
141
153
  if @now.has_key?($ID.text) and @now[$ID.text].is_a?(Hash) and
@@ -144,11 +156,18 @@ attribute
144
156
  else
145
157
  @now[$ID.text] = $value.val
146
158
  end
159
+ $id = $ID.text
147
160
  }
148
161
  | ID reference_type NL+
149
- { @now[$ID.text] = $reference_type.val }
162
+ {
163
+ @now[$ID.text] = $reference_type.val
164
+ $id = $ID.text
165
+ }
150
166
  | ID set_type NL+
151
- { @now[$ID.text] = $set_type.val }
167
+ {
168
+ @now[$ID.text] = $set_type.val
169
+ $id = $ID.text
170
+ }
152
171
  | ID probability_op set_value NL+
153
172
  {
154
173
  @conformant = true
@@ -157,27 +176,72 @@ attribute
157
176
  '_parent' => @now,
158
177
  '_values' => $set_value.val
159
178
  }
179
+ $id = $ID.text
180
+ }
181
+ | ID ':' path NL+
182
+ {
183
+ case $path.text
184
+ when 'String'
185
+ @now[$ID.text] = { '_context' => 'any_value',
186
+ '_isa' => '$.String'
187
+ }
188
+ when 'Bool'
189
+ @now[$ID.text] = { '_context' => 'any_value',
190
+ '_isa' => '$.Boolean'
191
+ }
192
+ when 'Int'
193
+ @now[$ID.text] = { '_context' => 'any_value',
194
+ '_isa' => '$.Number'
195
+ }
196
+ else
197
+ raise Exception, "Use isa/isref for any non-primitive type (#{$path.text})."
198
+ end
199
+ $id = $ID.text
160
200
  }
161
201
  | object_def NL+
202
+ { $id = nil }
203
+ ;
204
+
205
+ object_schema
206
+ : path('[' NUMBER { @now['_is_array'] = true } ']')?
207
+ {
208
+ @now['_isa'] = self.to_ref($path.text)
209
+ self.expand_object(@now)
210
+ }
211
+ ;
212
+
213
+ object_schemata
214
+ : ',' object_schema
162
215
  ;
163
216
 
164
217
  object_def
165
- : ID
218
+ : { @use_template = false }
219
+ ID
220
+ ('extends' path
221
+ {
222
+ template = @root.at?($path.text)
223
+ raise Exception, "Object template #{$path.text} is not found!" if
224
+ template.is_a?(Sfp::Unknown) or template.is_a?(Sfp::Undefined)
225
+ raise Exception, "#{$path.text} is not an object!" if
226
+ !template.is_a?(Hash) or template['_context'] != 'object'
227
+ @now[$ID.text] = Sfp::Helper.deep_clone(template)
228
+ @now[$ID.text].accept(Sfp::Visitor::ParentEliminator.new)
229
+ @now[$ID.text]['_parent'] = @now
230
+ @now[$ID.text]['_self'] = $ID.text
231
+ @now[$ID.text].accept(Sfp::Visitor::SfpGenerator.new(@root))
232
+ @use_template = true
233
+ }
234
+ )?
166
235
  {
167
236
  @now[$ID.text] = { '_self' => $ID.text,
168
237
  '_context' => 'object',
169
238
  '_parent' => @now,
170
239
  '_isa' => '$.Object'
171
- }
240
+ } if not @use_template
172
241
  @now = @now[$ID.text]
173
242
  @now['_is_array'] = false
174
243
  }
175
- ('isa' path('[' NUMBER { @now['_is_array'] = true } ']')?
176
- {
177
- @now['_isa'] = self.to_ref($path.text)
178
- self.expand_object(@now)
179
- }
180
- )?
244
+ ('isa' object_schema (object_schemata)* )?
181
245
  object_body?
182
246
  {
183
247
  if @now['_is_array']
@@ -280,7 +344,7 @@ op_statement
280
344
  ;
281
345
 
282
346
  procedure
283
- : 'procedure' ID
347
+ : ('procedure'|'sub') ID
284
348
  {
285
349
  @now[$ID.text] = { '_self' => $ID.text,
286
350
  '_context' => 'procedure',
@@ -862,6 +926,11 @@ value returns [val, type]
862
926
  $val = $set_value.val
863
927
  $type = 'Set'
864
928
  }
929
+ | 'any'
930
+ {
931
+ $val = Sfp::Any.new
932
+ $type = 'Any'
933
+ }
865
934
  ;
866
935
 
867
936
  primitive_value returns [val, type]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-15 00:00:00.000000000 Z
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &7789060 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 1.7.5
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *7789060
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.7.5
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: antlr3
27
- requirement: &7788020 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
@@ -32,9 +37,13 @@ dependencies:
32
37
  version: 1.8.12
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *7788020
36
- description: A Ruby gem that provides a Ruby API to SFP language parser and SFP planner.
37
- It also provides a planner sript to solve a planning problem written in SFP language.
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.8.12
46
+ description: A Ruby API and script for SFP language parser
38
47
  email: herry13@gmail.com
39
48
  executables:
40
49
  - sfp
@@ -45,18 +54,11 @@ files:
45
54
  - LICENSE
46
55
  - README.md
47
56
  - bin/sfp
48
- - bin/solver/linux-x86/downward
49
- - bin/solver/linux-x86/preprocess
50
- - bin/solver/macos/downward
51
- - bin/solver/macos/preprocess
52
57
  - lib/sfp.rb
53
58
  - lib/sfp/SfpLangLexer.rb
54
59
  - lib/sfp/SfpLangParser.rb
55
60
  - lib/sfp/Sfplib.rb
56
- - lib/sfp/executor.rb
57
61
  - lib/sfp/parser.rb
58
- - lib/sfp/planner.rb
59
- - lib/sfp/sas.rb
60
62
  - lib/sfp/sas_translator.rb
61
63
  - lib/sfp/sfw2graph.rb
62
64
  - lib/sfp/trollop.rb
@@ -65,27 +67,9 @@ files:
65
67
  - sfp.gemspec
66
68
  - src/SfpLang.g
67
69
  - src/build.sh
68
- - test/cloud-schemas.sfp
69
- - test/future/test1.sfp
70
- - test/nd-cloud1.sfp
71
- - test/nd-cloud2.sfp
72
- - test/nd-cloud3.sfp
73
- - test/nd-service1.sfp
74
- - test/nd-service2.sfp
75
- - test/run.sh
76
- - test/s.sfp
77
- - test/service-schemas.sfp
78
- - test/test-module1-scripts.tgz
79
- - test/test-module1.sfp
80
- - test/test1.inc
81
- - test/test1.sfp
82
- - test/test2.sfp
83
- - test/test3.inc
84
- - test/test3.sfp
85
- - test/test4.inc
86
- - test/test4.sfp
87
70
  homepage: https://github.com/herry13/sfp-ruby
88
- licenses: []
71
+ licenses:
72
+ - BSD
89
73
  post_install_message:
90
74
  rdoc_options: []
91
75
  require_paths:
@@ -104,27 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
88
  version: '0'
105
89
  requirements: []
106
90
  rubyforge_project: sfp
107
- rubygems_version: 1.8.11
91
+ rubygems_version: 1.8.23
108
92
  signing_key:
109
93
  specification_version: 3
110
- summary: SFP Parser and Planner
111
- test_files:
112
- - test/cloud-schemas.sfp
113
- - test/future/test1.sfp
114
- - test/nd-cloud1.sfp
115
- - test/nd-cloud2.sfp
116
- - test/nd-cloud3.sfp
117
- - test/nd-service1.sfp
118
- - test/nd-service2.sfp
119
- - test/run.sh
120
- - test/s.sfp
121
- - test/service-schemas.sfp
122
- - test/test-module1-scripts.tgz
123
- - test/test-module1.sfp
124
- - test/test1.inc
125
- - test/test1.sfp
126
- - test/test2.sfp
127
- - test/test3.inc
128
- - test/test3.sfp
129
- - test/test4.inc
130
- - test/test4.sfp
94
+ summary: SFP Parser
95
+ test_files: []
Binary file
Binary file
Binary file
Binary file
data/lib/sfp/executor.rb DELETED
@@ -1,207 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'json'
4
- require 'thread'
5
-
6
- module Sfp
7
- module Executor
8
- class ExecutionException < Exception; end
9
- class ParallelExecutionException < Exception; end
10
- class SequentialExecutionException < Exception; end
11
-
12
- # @param :plan the plan to be executed
13
- # @param :owner an object that implement the action
14
- # @param :retry number of retries (default: 2) when execution is failed
15
- #
16
- def execute_plan(params={})
17
- if params[:plan].nil? or not params[:plan].is_a?(Hash)
18
- raise ExecutionException, 'Plan is not available.'
19
- elsif params[:plan]['type'].to_s == 'parallel' or
20
- params[:plan][:type].to_s == 'parallel'
21
- return self.execute_parallel_plan(params)
22
- elsif params[:plan]['type'].to_s == 'sequential' or
23
- params[:plan][:type].to_s == 'sequential'
24
- return self.execute_sequential_plan(params)
25
- else
26
- raise ExecutionException, 'Unknown type of plan!'
27
- end
28
- false
29
- end
30
-
31
- # @param :plan the plan to be executed
32
- # @param :owner an object that implement the action
33
- # @param :retry number of retries (default: 2) when execution is failed
34
- #
35
- def execute_parallel_plan(params={})
36
- def assign_action_with_id(id)
37
- thread_id = next_thread_id
38
- action = @actions[id]
39
- action[:executor] = thread_id
40
- self.thread_execute_action(thread_id, action)
41
- end
42
-
43
- def next_thread_id
44
- id = 0
45
- @mutex.synchronize { @thread_id = id = @thread_id + 1 }
46
- id
47
- end
48
-
49
- def action_to_string(action)
50
- "#{action['id']}:#{action['name']}#{JSON.generate(action['parameters'])}"
51
- end
52
-
53
- def thread_execute_action(tid, action)
54
- t = Thread.new {
55
- @mutex.synchronize { @threads << tid }
56
-
57
- while not @failed and not action[:executed]
58
- # execute the action
59
- op_str = action_to_string(action)
60
- #Nuri::Util.puts "[ExecutorThread: #{tid}] #{op_str}"
61
- success = false
62
- num = @retry
63
- begin
64
- success = @owner.execute_action { action }
65
- num -= 1
66
- end while not success and num > 0
67
-
68
- # check if execution failed
69
- if success
70
- next_actions = []
71
- @mutex.synchronize {
72
- # set executed
73
- action[:executed] = true
74
- # select next action to be executed from all predecessor actions
75
- # if each action has not been assigned to any thread yet
76
- if action['successors'].length > 0
77
- action['successors'].each { |id|
78
- if @actions[id][:executor].nil?
79
- predecessors_ok = true
80
- @actions[id]['predecessors'].each { |pid|
81
- predecessors_ok = (predecessors_ok and @actions[pid][:executed])
82
- }
83
- next_actions << id if predecessors_ok
84
- end
85
- }
86
- end
87
- next_actions.each { |id| @actions[id][:executor] = tid }
88
- }
89
- if next_actions.length > 0
90
- # execute next actions
91
- action = @actions[next_actions[0]]
92
- if next_actions.length > 1
93
- for i in 1..(next_actions.length-1)
94
- assign_action_with_id(next_actions[i])
95
- end
96
- end
97
- end
98
-
99
- else
100
- Nuri::Util.error "Failed executing #{op_str}!"
101
- @mutex.synchronize {
102
- @failed = true # set global flag
103
- @actions_failed << action
104
- }
105
- end
106
- end
107
-
108
- @mutex.synchronize { @threads.delete(tid) }
109
- }
110
- end
111
-
112
- if params[:plan].nil? or not params[:plan].is_a?(Hash)
113
- raise ParallelExecutionException, 'Plan is not available.'
114
- elsif params[:plan]['type'].to_s == 'parallel' or
115
- params[:plan][:type].to_s == 'parallel'
116
- else
117
- raise ParallelExecutionException, 'Not a parallel plan.'
118
- end
119
-
120
- @owner = params[:owner]
121
- @retry = (params[:retry].nil? ? 2 : params[:retry].to_i)
122
-
123
- @actions = params[:plan]['workflow']
124
- @actions.sort! { |x,y| x['id'] <=> y['id'] }
125
- @actions.each { |op| op[:executed] = false; op[:executor] = nil; }
126
-
127
- @threads = []
128
- @actions_failed = []
129
- @mutex = Mutex.new
130
- @failed = false
131
- @thread_id = 0
132
-
133
- params[:plan]['init'].each { |op_id| assign_action_with_id(op_id) }
134
-
135
- begin
136
- sleep 1
137
- end while @threads.length > 0
138
-
139
- Nuri::Util.log "Using #{@thread_id} threads in execution."
140
-
141
- return (not @failed)
142
- end
143
-
144
- # @param :plan the plan to be executed
145
- # @param :owner an object that implement the action
146
- # @param :retry number of retries (default: 2) when execution is failed
147
- #
148
- def execute_sequential_plan(params={})
149
- if params[:plan].nil? or not params[:plan].is_a?(Hash)
150
- raise ParallelExecutionException, 'Plan is not available.'
151
- elsif params[:plan]['type'].to_s == 'sequential' or
152
- params[:plan][:type].to_s == 'sequential'
153
- else
154
- raise ParallelExecutionException, 'Not a parallel plan.'
155
- end
156
-
157
- @owner = params[:owner]
158
- @retry = (params[:retry].nil? ? 2 : params[:retry].to_i)
159
- params[:plan]['workflow'].each { |action|
160
- success = false
161
- num = @retry
162
- begin
163
- success, data = @owner.execute_action { action }
164
- puts data.to_s if params[:print_output]
165
- num -= 1
166
- end while not success and num > 0
167
- return false if not success
168
- }
169
- true
170
- end
171
- end
172
-
173
- class RubyExecutor
174
- def execute_plan(params={})
175
- exec = Object.new
176
- exec.extend(Sfp::Executor)
177
- params[:owner] = self
178
- exec.execute_plan(params)
179
- end
180
-
181
- def execute_action
182
- # TODO
183
- action = yield
184
- puts "Exec: #{action.inspect}"
185
- [true, nil]
186
- end
187
- end
188
-
189
- class BashExecutor < RubyExecutor
190
- def execute_action
191
- # TODO
192
- action = yield
193
- module_dir = (ENV.has_key?("SFP_HOME") ? ENV['SFP_HOME'] : ".")
194
- script_path = "#{action['name'].sub!(/^\$\./, '')}"
195
- script_path = "#{module_dir}/#{script_path.gsub!(/\./, '/')}"
196
- cmd = "/bin/bash #{script_path}"
197
- action['parameters'].each { |p| cmd += " '#{p}'" }
198
- begin
199
- data = `#{cmd}`
200
- rescue Exception => exp
201
- $stderr.puts "#{exp}\n#{exp.backtrace}"
202
- [false, nil]
203
- end
204
- [true, data]
205
- end
206
- end
207
- end