coral_plan 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,188 @@
1
+
2
+ module Coral
3
+ module Plan
4
+ class Command < Command
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Constructor / Destructor
8
+
9
+ def initialize(options = {})
10
+ super(options)
11
+ @plan = ( options.has_key?(:plan) ? options[:plan] : nil )
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Property accessors / modifiers
16
+
17
+ def command=command
18
+ super(command)
19
+ @plan.set_command(@name, "command", command) if @plan
20
+ end
21
+
22
+ #---
23
+
24
+ def vagrant=command
25
+ super(command)
26
+ @plan.set_command(@name, "vagrant", command) if @plan
27
+ end
28
+
29
+ #---
30
+
31
+ def cloud=command
32
+ super(command)
33
+ @plan.set_command(@name, "cloud", command) if @plan
34
+ end
35
+
36
+ #---
37
+
38
+ def args=args
39
+ super(args)
40
+ @plan.set_command(@name, "args", @properties[:args]) if @plan
41
+ end
42
+
43
+ #---
44
+
45
+ def flags=flags
46
+ super(flags)
47
+ @plan.set_command(@name, "flags", @properties[:flags]) if @plan
48
+ end
49
+
50
+ #---
51
+
52
+ def data=data
53
+ super(data)
54
+ @plan.set_command(@name, "data", @properties[:data]) if @plan
55
+ end
56
+
57
+ #---
58
+
59
+ def subcommand=subcommand
60
+ super(subcommand)
61
+ @plan.set_command(@name, "subcommand", @properties[:subcommand]) if @plan
62
+ end
63
+
64
+ #---
65
+
66
+ def events
67
+ events = {}
68
+ if @plan
69
+ event_types = @plan.command(@name, 'events', [], :array)
70
+ @plan.events.each do |name, event|
71
+ if event_types.include?(event.type)
72
+ events[name] = @plan.events[name]
73
+ end
74
+ end
75
+ end
76
+ return events
77
+ end
78
+
79
+ #---
80
+
81
+ def events=events
82
+ @plan.set_command(@name, "events", events) if @plan
83
+ end
84
+
85
+ #-----------------------------------------------------------------------------
86
+ # Command functions
87
+
88
+ def build(components = {}, overrides = nil, override_key = false)
89
+ if overrides && ! overrides.empty?
90
+ overrides = translate_events(overrides)
91
+ end
92
+ return super(translate_events(components), overrides, override_key)
93
+ end
94
+
95
+ #---
96
+
97
+ def exec!(options = {}, action = nil)
98
+ triggered_events = {}
99
+ action_info = action
100
+
101
+ if action && ! action.is_a?(Hash)
102
+ action_info = action.export
103
+ end
104
+
105
+ success = super(options, action_info) do |line|
106
+ result = true
107
+ prefix = false
108
+
109
+ if @plan
110
+ @plan.events.each do |name, event|
111
+ if events.has_key?(name) && event.check(line)
112
+ prefix = 'EVENT'
113
+ triggered_events[name] = event
114
+ end
115
+ end
116
+ end
117
+
118
+ if block_given?
119
+ result = yield(line)
120
+
121
+ if result && result.is_a?(Hash)
122
+ result = result[:success]
123
+ end
124
+ end
125
+ prefix ? { :success => result, :prefix => prefix } : result
126
+ end
127
+
128
+ if @plan && action
129
+ if success
130
+ action.trigger_success.each do |name|
131
+ triggered_events[name] = @plan.events[name]
132
+ end
133
+ else
134
+ action.trigger_failure.each do |name|
135
+ triggered_events[name] = @plan.events[name]
136
+ end
137
+ end
138
+ end
139
+
140
+ return ( success ? triggered_events : nil )
141
+ end
142
+
143
+ #-----------------------------------------------------------------------------
144
+ # Utilities
145
+
146
+ def translate_events(data, options = [ :exit ])
147
+ if @plan && data && data.is_a?(Hash) && data.has_key?(:data)
148
+ data[:data].each do |key, value|
149
+ # Action with command specific overrides
150
+ if value.is_a?(Hash)
151
+ value.each do |sub_key, sub_value|
152
+ if options.include?(sub_key) && @plan.command(key, 'coral', false)
153
+ events = []
154
+ array(sub_value.split(',')).each do |event_name|
155
+ if @plan.events.has_key?(event_name)
156
+ events << @plan.events[event_name].export
157
+ else
158
+ events << event_name
159
+ end
160
+ end
161
+ data[:data][key][sub_key] = events.join(',')
162
+ end
163
+ end
164
+ # Command or Action with overrides for all commands
165
+ elsif options.include?(key)
166
+ if data.has_key?(:commands)
167
+ array(data[:commands]).each do |command_name|
168
+ return data unless @plan.command(command_name, 'coral', false)
169
+ end
170
+ end
171
+
172
+ events = []
173
+ array(value.split(',')).each do |event_name|
174
+ if @plan.events.has_key?(event_name)
175
+ events << @plan.events[event_name].export
176
+ else
177
+ events << event_name
178
+ end
179
+ end
180
+ data[:data][key] = events.join(',')
181
+ end
182
+ end
183
+ end
184
+ return data
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,69 @@
1
+
2
+ module Coral
3
+ module Plan
4
+ class Event < Event
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Constructor / Destructor
8
+
9
+ def self.instance(options = {}, build_hash = false, keep_array = false)
10
+ return instance!(options, build_hash, keep_array) do |type, info|
11
+ type == :plan ? info[:object] : create(type, info)
12
+ end
13
+ end
14
+
15
+ #---
16
+
17
+ def initialize(options = {})
18
+ super(options)
19
+ @plan = ( options.has_key?(:plan) ? options[:plan] : nil )
20
+ end
21
+
22
+ #-----------------------------------------------------------------------------
23
+ # Property accessors / modifiers
24
+
25
+ def set_properties(data)
26
+ super(data)
27
+ @plan.set_event(@name, nil, @properties) if @plan
28
+ return self
29
+ end
30
+
31
+ #---
32
+
33
+ def set_property(name, value)
34
+ super(data)
35
+ @plan.set_event(@name, name, @properties[name]) if @plan
36
+ return self
37
+ end
38
+
39
+ #-----------------------------------------------------------------------------
40
+ # Utilities
41
+
42
+ def self.build_info(data = {})
43
+ return build_info!(data) do |element|
44
+ event = {}
45
+
46
+ case element
47
+ when String
48
+ if @plan && @plan.events.has_key?(element)
49
+ event[:type] = :plan
50
+ event[:object] = @plan.events[element]
51
+ else
52
+ event = split_event_string(element)
53
+ end
54
+ when Hash
55
+ event = element
56
+ end
57
+
58
+ if @plan
59
+ event[:delegate] = self.new({
60
+ :name => element[:name],
61
+ :plan => @plan,
62
+ })
63
+ end
64
+ event
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
data/lib/coral_plan.rb ADDED
@@ -0,0 +1,75 @@
1
+
2
+ home = File.dirname(__FILE__)
3
+
4
+ $:.unshift(home) unless
5
+ $:.include?(home) || $:.include?(File.expand_path(home))
6
+
7
+ #-------------------------------------------------------------------------------
8
+
9
+ require 'rubygems'
10
+ require 'coral_core'
11
+
12
+ #---
13
+
14
+ # Include data model
15
+ [ :event, :command, :action, :base ].each do |name|
16
+ require File.join('coral_plan', name.to_s + '.rb')
17
+ end
18
+
19
+ #*******************************************************************************
20
+ # Coral Execution Plan Library
21
+ #
22
+ # This provides the ability to create repeatable execution plans that can be
23
+ # loaded from and stored into files, among other things...
24
+ #
25
+ # Author:: Adrian Webb (mailto:adrian.webb@coraltech.net)
26
+ # License:: GPLv3
27
+ module Coral
28
+
29
+ #-----------------------------------------------------------------------------
30
+ # Constructor / Destructor
31
+
32
+ def self.create_plan(name, options = {})
33
+ return Coral::Plan.create(name, options)
34
+ end
35
+
36
+ #---
37
+
38
+ def self.delete_plan(name)
39
+ return Coral::Plan.delete(name)
40
+ end
41
+
42
+ #-----------------------------------------------------------------------------
43
+ # Accessors / Modifiers
44
+
45
+ def self.plan(name)
46
+ return Coral::Plan[name]
47
+ end
48
+
49
+ #*******************************************************************************
50
+
51
+ module Plan
52
+
53
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
54
+
55
+ #-----------------------------------------------------------------------------
56
+ # Constructor / Destructor
57
+
58
+ def self.create(name, options = {})
59
+ return Coral::Plan::Base.create(name, options)
60
+ end
61
+
62
+ #---
63
+
64
+ def self.delete(name)
65
+ return Coral::Plan::Base.delete(name)
66
+ end
67
+
68
+ #-----------------------------------------------------------------------------
69
+ # Accessors / Modifiers
70
+
71
+ def self.[](name)
72
+ return Coral::Plan::Base[name]
73
+ end
74
+ end
75
+ end
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: coral_plan
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Adrian Webb
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-02-07 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: coral_core
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 0
31
+ - 1
32
+ version: "0.1"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 11
44
+ segments:
45
+ - 1
46
+ - 2
47
+ version: "1.2"
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rspec
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ hash: 23
59
+ segments:
60
+ - 2
61
+ - 10
62
+ version: "2.10"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rdoc
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ hash: 31
74
+ segments:
75
+ - 3
76
+ - 12
77
+ version: "3.12"
78
+ type: :development
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: jeweler
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ hash: 31
89
+ segments:
90
+ - 1
91
+ - 8
92
+ version: "1.8"
93
+ type: :development
94
+ version_requirements: *id005
95
+ description: |-
96
+ = coral_plan
97
+
98
+ This library provides the ability to create, load, execute, and save
99
+ execution plans.
100
+
101
+ The Coral Plan library contains a system that defines execution plans of
102
+ CLI commands. The goal is to make it easy to create, edit, load, execute,
103
+ and save these plans in a machine readable format (ie; JSON). The system
104
+ is composed of Events, Commands, Actions, and of course Plans. There are a
105
+ few simple rules:
106
+
107
+ 1. All plans begin with a Command but may have more Commands defined
108
+ that act in sequence unless there are errors with previous commands.
109
+
110
+ 2. Commands can trigger Events of various types, where Events are reading
111
+ and checking (ie; Regular expressions) Command output line by line.
112
+
113
+ 3. Events have different criteria for measuring success and will have
114
+ different fields. For example, a Regexp event contains a 'pattern'
115
+ field.
116
+
117
+ 4. Actions listen for Events and run Commands, with the ability to override
118
+ default Command parameters. Actions may also generate Events on either
119
+ successful execution or failure which can trigger other Actions.
120
+
121
+ Note: This library is still very early in development!
122
+
123
+ == Contributing to coral_plan
124
+
125
+ * Check out the latest master to make sure the feature hasn't been implemented
126
+ or the bug hasn't been fixed yet.
127
+ * Check out the issue tracker to make sure someone already hasn't requested
128
+ it and/or contributed it.
129
+ * Fork the project.
130
+ * Start a feature/bugfix branch.
131
+ * Commit and push until you are happy with your contribution.
132
+ * Make sure to add tests for it. This is important so I don't break it in a
133
+ future version unintentionally.
134
+ * Please try not to mess with the Rakefile, version, or history. If you want
135
+ to have your own version, or is otherwise necessary, that is fine, but
136
+ please isolate to its own commit so I can cherry-pick around it.
137
+
138
+ == Copyright
139
+
140
+ Licensed under GPLv3. See LICENSE.txt for further details.
141
+
142
+ Copyright (c) 2013 Adrian Webb <adrian.webb@coraltech.net>
143
+ Coral Technology Group LLC
144
+ email: adrian.webb@coraltech.net
145
+ executables: []
146
+
147
+ extensions: []
148
+
149
+ extra_rdoc_files:
150
+ - LICENSE.txt
151
+ - README.rdoc
152
+ files:
153
+ - .document
154
+ - Gemfile
155
+ - Gemfile.lock
156
+ - LICENSE.txt
157
+ - README.rdoc
158
+ - Rakefile
159
+ - VERSION
160
+ - lib/coral_plan.rb
161
+ - lib/coral_plan/action.rb
162
+ - lib/coral_plan/base.rb
163
+ - lib/coral_plan/command.rb
164
+ - lib/coral_plan/event.rb
165
+ homepage: http://github.com/coraltech/ruby-coral_plan
166
+ licenses:
167
+ - GPLv3
168
+ post_install_message:
169
+ rdoc_options:
170
+ - --title
171
+ - Coral Execution Plan library
172
+ - --main
173
+ - README.rdoc
174
+ - --line-numbers
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ hash: 53
183
+ segments:
184
+ - 1
185
+ - 8
186
+ - 1
187
+ version: 1.8.1
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ none: false
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ hash: 3
194
+ segments:
195
+ - 0
196
+ version: "0"
197
+ requirements: []
198
+
199
+ rubyforge_project: coral_plan
200
+ rubygems_version: 1.8.15
201
+ signing_key:
202
+ specification_version: 3
203
+ summary: Provides the ability to create, load, execute, and save execution plans
204
+ test_files: []
205
+
206
+ has_rdoc: