coral_plan 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +674 -0
- data/README.rdoc +48 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/lib/coral_plan/action.rb +167 -0
- data/lib/coral_plan/base.rb +263 -0
- data/lib/coral_plan/command.rb +188 -0
- data/lib/coral_plan/event.rb +69 -0
- data/lib/coral_plan.rb +75 -0
- metadata +206 -0
@@ -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:
|