coral_core 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = coral_core
2
+
3
+ This library provides core data elements and utilities used in other Coral gems.
4
+
5
+ The Coral core library contains functionality that is utilized by other
6
+ Coral gems by providing basic utilities like Git, Shell, Disk, and Data
7
+ manipulation libraries, a UI system, and a core data model that supports
8
+ Events, Commands, Repositories, and Memory (version controlled JSON
9
+ objects). This library is only used as a starting point for other systems.
10
+
11
+ Note: This library is still very early in development!
12
+
13
+ == Contributing to coral_core
14
+
15
+ * Check out the latest master to make sure the feature hasn't been implemented
16
+ or the bug hasn't been fixed yet.
17
+ * Check out the issue tracker to make sure someone already hasn't requested
18
+ it and/or contributed it.
19
+ * Fork the project.
20
+ * Start a feature/bugfix branch.
21
+ * Commit and push until you are happy with your contribution.
22
+ * Make sure to add tests for it. This is important so I don't break it in a
23
+ future version unintentionally.
24
+ * Please try not to mess with the Rakefile, version, or history. If you want
25
+ to have your own version, or is otherwise necessary, that is fine, but
26
+ please isolate to its own commit so I can cherry-pick around it.
27
+
28
+ == Copyright
29
+
30
+ Licensed under GPLv3. See LICENSE.txt for further details.
31
+
32
+ Copyright (c) 2013 Adrian Webb <adrian.webb@coraltech.net>
33
+ Coral Technology Group LLC
data/Rakefile ADDED
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'bundler'
6
+ require 'jeweler'
7
+ require 'rspec/core/rake_task'
8
+ require 'rdoc/task'
9
+ require 'yard'
10
+
11
+ require './lib/coral_core.rb'
12
+
13
+ #-------------------------------------------------------------------------------
14
+ # Dependencies
15
+
16
+ begin
17
+ Bundler.setup(:default, :development)
18
+ rescue Bundler::BundlerError => e
19
+ $stderr.puts e.message
20
+ $stderr.puts "Run `bundle install` to install missing gems"
21
+ exit e.status_code
22
+ end
23
+
24
+ #-------------------------------------------------------------------------------
25
+ # Gem specification
26
+
27
+ Jeweler::Tasks.new do |gem|
28
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
29
+ gem.name = "coral_core"
30
+ gem.homepage = "http://github.com/coraltech/ruby-coral_core"
31
+ gem.rubyforge_project = 'coral_core'
32
+ gem.license = "GPLv3"
33
+ gem.email = "adrian.webb@coraltech.net"
34
+ gem.authors = ["Adrian Webb"]
35
+ gem.summary = %Q{Provides core data elements and utilities used in other Coral gems}
36
+ gem.description = File.read('README.rdoc')
37
+ gem.required_ruby_version = '>= 1.8.1'
38
+ gem.has_rdoc = true
39
+ gem.rdoc_options << '--title' << 'Coral Core library' <<
40
+ '--main' << 'README.rdoc' <<
41
+ '--line-numbers'
42
+
43
+ # Dependencies defined in Gemfile
44
+ end
45
+
46
+ Jeweler::RubygemsDotOrgTasks.new
47
+
48
+ #-------------------------------------------------------------------------------
49
+ # Testing
50
+
51
+ RSpec::Core::RakeTask.new(:spec, :tag) do |spec, task_args|
52
+ options = []
53
+ options << "--tag #{task_args[:tag]}" if task_args.is_a?(Array) && ! task_args[:tag].to_s.empty?
54
+ spec.rspec_opts = options.join(' ')
55
+ end
56
+
57
+ task :default => :spec
58
+
59
+ #-------------------------------------------------------------------------------
60
+ # Documentation
61
+
62
+ version = Coral::VERSION
63
+ doc_title = "coral_core #{version}"
64
+
65
+ Rake::RDocTask.new do |rdoc|
66
+ rdoc.rdoc_dir = 'rdoc'
67
+ rdoc.title = doc_title
68
+ rdoc.rdoc_files.include('README*')
69
+ rdoc.rdoc_files.include('lib/**/*.rb')
70
+ end
71
+
72
+ #---
73
+
74
+ YARD::Rake::YardocTask.new do |ydoc|
75
+ ydoc.files = [ 'README*', 'lib/**/*.rb' ]
76
+ ydoc.options = [ "--output-dir yardoc", "--title '#{doc_title}'" ]
77
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,236 @@
1
+
2
+ module Coral
3
+ class Command < Core
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Properties
7
+
8
+ attr_accessor :name
9
+ attr_reader :subcommand
10
+
11
+ #-----------------------------------------------------------------------------
12
+ # Constructor / Destructor
13
+
14
+ def initialize(options = {})
15
+
16
+ if options.is_a?(String) || options.is_a?(Symbol)
17
+ options = string(options)
18
+ options = { :name => options, :command => options }
19
+ end
20
+
21
+ super(options)
22
+
23
+ @properties = {}
24
+
25
+ self.subcommand = options[:subcommand] if options.has_key?(:subcommand)
26
+
27
+ @name = ( options.has_key?(:name) ? string(options[:name]) : '' )
28
+
29
+ @properties = options
30
+ @properties[:command] = executable(options)
31
+ end
32
+
33
+ #-----------------------------------------------------------------------------
34
+ # Property accessors / modifiers
35
+
36
+ def command_base
37
+ return @properties[:command]
38
+ end
39
+
40
+ #---
41
+
42
+ def command=command
43
+ @properties[:command] = executable({ :command => command })
44
+ end
45
+
46
+ #---
47
+
48
+ def vagrant=command
49
+ @properties[:command] = executable({ :vagrant => command })
50
+ end
51
+
52
+ #---
53
+
54
+ def coral=command
55
+ @properties[:command] = executable({ :coral => command })
56
+ end
57
+
58
+ #---
59
+
60
+ def args
61
+ return array(@properties[:args])
62
+ end
63
+
64
+ #---
65
+
66
+ def args=args
67
+ @properties[:args] = array(args)
68
+ end
69
+
70
+ #---
71
+
72
+ def flags
73
+ return array(@properties[:flags])
74
+ end
75
+
76
+ #---
77
+
78
+ def flags=flags
79
+ @properties[:flags] = array(flags)
80
+ end
81
+
82
+ #---
83
+
84
+ def data
85
+ return hash(@properties[:data])
86
+ end
87
+
88
+ #---
89
+
90
+ def data=data
91
+ @properties[:data] = hash(data)
92
+ end
93
+
94
+ #---
95
+
96
+ def subcommand=subcommand
97
+ @properties[:subcommand] = hash(subcommand)
98
+ @subcommand = Module.const_get("Coral").const_get(self.class).new(@properties[:subcommand])
99
+ end
100
+
101
+ #-----------------------------------------------------------------------------
102
+ # Import / Export
103
+
104
+ def export
105
+ return symbol_map(@properties)
106
+ end
107
+
108
+ #-----------------------------------------------------------------------------
109
+ # Command functions
110
+
111
+ def build(components = {}, overrides = nil, override_key = false)
112
+
113
+ command = string(components[:command])
114
+ flags = array( components.has_key?(:flags) ? components[:flags] : [] )
115
+ data = string_map(hash( components.has_key?(:data) ? components[:data] : {} ))
116
+ args = array( components.has_key?(:args) ? components[:args] : [] )
117
+ subcommand = hash( components.has_key?(:subcommand) ? components[:subcommand] : {} )
118
+
119
+ override_key = command unless override_key
120
+ override_key = override_key.to_sym
121
+
122
+ command_string = command.dup
123
+ subcommand_string = ''
124
+
125
+ escape_characters = /[\'\"]+/
126
+ escape_replacement = '\"'
127
+
128
+ dash_pattern = /^([\-]+)/
129
+ assignment_pattern = /\=$/
130
+
131
+ # Flags
132
+ if overrides && overrides.has_key?(:flags)
133
+ if overrides[:flags].is_a?(Hash)
134
+ if overrides[:flags].has_key?(override_key)
135
+ flags = array(overrides[:flags][override_key])
136
+ end
137
+ else
138
+ flags = array(overrides[:flags])
139
+ end
140
+ end
141
+ flags.each do |flag|
142
+ if flag && ! flag.empty?
143
+ flag = string(flag)
144
+
145
+ if flag.match(dash_pattern)
146
+ dashes = $1
147
+ else
148
+ dashes = ( flag.size == 1 ? '-' : '--' )
149
+ end
150
+ command_string << " #{dashes}#{flag}"
151
+ end
152
+ end
153
+
154
+ # Data
155
+ if overrides && overrides.has_key?(:data)
156
+ if overrides[:data].has_key?(override_key)
157
+ data = hash(overrides[:data][override_key])
158
+ else
159
+ override = true
160
+ overrides[:data].each do |key, value|
161
+ if ! value.is_a?(String)
162
+ override = false
163
+ end
164
+ end
165
+ data = hash(overrides[:data]) if override
166
+ end
167
+ end
168
+ data.each do |key, value|
169
+ key = string(key)
170
+ value = string(value).strip.sub(escape_characters, escape_replacement)
171
+
172
+ if key.match(dash_pattern)
173
+ dashes = $1
174
+ else
175
+ dashes = ( key.size == 1 ? '-' : '--' )
176
+ end
177
+ space = ( key.match(assignment_pattern) ? '' : ' ' )
178
+
179
+ command_string << " #{dashes}#{key}#{space}'#{value}'"
180
+ end
181
+
182
+ # Arguments
183
+ if overrides && overrides.has_key?(:args)
184
+ if overrides[:args].is_a?(Hash)
185
+ if overrides[:args].has_key?(override_key)
186
+ args = array(overrides[:args][override_key])
187
+ end
188
+ else
189
+ args = array(overrides[:args])
190
+ end
191
+ end
192
+ args.each do |arg|
193
+ arg = string(arg).sub(escape_characters, escape_replacement)
194
+ command_string << " '#{arg}'"
195
+ end
196
+
197
+ # Subcommand
198
+ subcommand_overrides = ( overrides ? overrides[:subcommand] : nil )
199
+ if subcommand && subcommand.is_a?(Hash) && ! subcommand.empty?
200
+ subcommand_string = build(subcommand, subcommand_overrides)
201
+ end
202
+
203
+ return (command_string + ' ' + subcommand_string).strip
204
+ end
205
+
206
+ #-----------------------------------------------------------------------------
207
+
208
+ def exec!(options = {}, overrides = nil)
209
+ success = Coral::Util::Shell.exec!(build(export, overrides), options) do |line|
210
+ block_given? ? yield(line) : true
211
+ end
212
+ return success
213
+ end
214
+
215
+ #---
216
+
217
+ def exec(options = {}, overrides = nil)
218
+ return exec!(options, overrides)
219
+ end
220
+
221
+ #-----------------------------------------------------------------------------
222
+ # Utilities
223
+
224
+ def executable(options)
225
+ if options.has_key?(:coral)
226
+ return 'vagrant coral ' + options[:coral]
227
+
228
+ elsif options.has_key?(:vagrant)
229
+ return 'vagrant ' + options[:vagrant]
230
+
231
+ elsif options.has_key?(:command)
232
+ return options[:command]
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,200 @@
1
+
2
+ module Coral
3
+ class Core
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Constructor / Destructor
7
+
8
+ def initialize(options = {})
9
+ @ui = Coral::Interface.new(options)
10
+ end
11
+
12
+ #-----------------------------------------------------------------------------
13
+ # Accessor / Modifiers
14
+
15
+ attr_accessor :ui
16
+
17
+ #-----------------------------------------------------------------------------
18
+
19
+ def self.logger
20
+ return @ui.class.logger
21
+ end
22
+
23
+ #---
24
+
25
+ def logger
26
+ return @ui.logger
27
+ end
28
+
29
+ #---
30
+
31
+ def logger=logger
32
+ @ui.logger = logger
33
+ end
34
+
35
+ #-----------------------------------------------------------------------------
36
+ # General utilities
37
+
38
+ def self.symbol_map(data)
39
+ results = {}
40
+ return data unless data
41
+
42
+ case data
43
+ when Hash
44
+ data.each do |key, value|
45
+ results[key.to_sym] = symbol_map(value)
46
+ end
47
+ else
48
+ results = data
49
+ end
50
+ return results
51
+ end
52
+
53
+ #---
54
+
55
+ def symbol_map(data)
56
+ return self.class.symbol_map(data)
57
+ end
58
+
59
+ #---
60
+
61
+ def self.string_map(data)
62
+ results = {}
63
+ return data unless data
64
+
65
+ case data
66
+ when Hash
67
+ data.each do |key, value|
68
+ results[key.to_s] = string_map(value)
69
+ end
70
+ else
71
+ results = data
72
+ end
73
+ return results
74
+ end
75
+
76
+ #---
77
+
78
+ def string_map(data)
79
+ return self.class.string_map(data)
80
+ end
81
+
82
+ #-----------------------------------------------------------------------------
83
+
84
+ def self.filter(data, method = false)
85
+ if method && method.is_a?(Symbol) &&
86
+ [ :array, :hash, :string, :symbol, :test ].include?(method.to_sym)
87
+ return send(method, data)
88
+ end
89
+ return data
90
+ end
91
+
92
+ #---
93
+
94
+ def filter(data, method = false)
95
+ return self.class.filter(data, method)
96
+ end
97
+
98
+ #-----------------------------------------------------------------------------
99
+
100
+ def self.array(data, default = [], split_string = false)
101
+ result = default
102
+ if data && ! data.empty?
103
+ case data
104
+ when Array
105
+ result = data
106
+ when String
107
+ result = [ ( split_string ? data.split(/\s*,\s*/) : data ) ]
108
+ else
109
+ result = [ data ]
110
+ end
111
+ end
112
+ return result
113
+ end
114
+
115
+ #---
116
+
117
+ def array(data, default = [], split_string = false)
118
+ return self.class.array(data, default, split_string)
119
+ end
120
+
121
+ #---
122
+
123
+ def self.hash(data, default = {})
124
+ result = default
125
+ if data && ! data.empty?
126
+ case data
127
+ when Hash
128
+ result = data
129
+ else
130
+ result = {}
131
+ end
132
+ end
133
+ return result
134
+ end
135
+
136
+ #---
137
+
138
+ def hash(data, default = {})
139
+ return self.class.hash(data, default)
140
+ end
141
+
142
+ #---
143
+
144
+ def self.string(data, default = '')
145
+ result = default
146
+ if data && ! data.empty?
147
+ case data
148
+ when String
149
+ result = data
150
+ else
151
+ result = data.to_s
152
+ end
153
+ end
154
+ return result
155
+ end
156
+
157
+ #---
158
+
159
+ def string(data, default = '')
160
+ return self.class.string(data, default)
161
+ end
162
+
163
+ #---
164
+
165
+ def self.symbol(data, default = :undefined)
166
+ result = default
167
+ if data && ! data.empty?
168
+ case data
169
+ when Symbol
170
+ result = data
171
+ when String
172
+ result = data.to_sym
173
+ else
174
+ result = data.class.to_sym
175
+ end
176
+ end
177
+ return result
178
+ end
179
+
180
+ #---
181
+
182
+ def symbol(data, default = '')
183
+ return self.class.symbol(data, default)
184
+ end
185
+
186
+ #---
187
+
188
+ def self.test(data)
189
+ return false if ! data || data.empty?
190
+ return false if data.is_a?(String) && data =~ /^(FALSE|false|False|No|no|N|n)$/
191
+ return true
192
+ end
193
+
194
+ #---
195
+
196
+ def test(data)
197
+ return self.class.test(data)
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,55 @@
1
+
2
+ module Coral
3
+ class RegexpEvent < Event
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Properties
7
+
8
+ TYPE = :regexp
9
+
10
+ #-----------------------------------------------------------------------------
11
+ # Constructor / Destructor
12
+
13
+ def initialize(options = {})
14
+ options[:type] = TYPE
15
+
16
+ super(options)
17
+
18
+ if options.has_key?(:string)
19
+ self.pattern = options[:string]
20
+ end
21
+ end
22
+
23
+ #-----------------------------------------------------------------------------
24
+ # Property accessors / modifiers
25
+
26
+ def pattern
27
+ return property(:pattern, '', :string)
28
+ end
29
+
30
+ #---
31
+
32
+ def pattern=pattern
33
+ set_property(:pattern, string(pattern))
34
+ end
35
+
36
+ #-----------------------------------------------------------------------------
37
+ # Import / Export
38
+
39
+ def export
40
+ return "#{type}:#{pattern}"
41
+ end
42
+
43
+ #-----------------------------------------------------------------------------
44
+ # Event handling
45
+
46
+ def check(source)
47
+ if source.match(/#{pattern}/)
48
+ logger.debug("MATCH! -> #{pattern} matched #{source}")
49
+ return true
50
+ end
51
+ logger.debug("nothing -> #{pattern} - #{source}")
52
+ return false
53
+ end
54
+ end
55
+ end