arborist 0.0.1.pre20160106113421 → 0.0.1.pre20160128152542

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9556233dcdad66412d5cabd6df2a7f3235dc616d
4
- data.tar.gz: 04d28c6e8168ff42793194506fa13c6a3261ba11
3
+ metadata.gz: ff35c627aec6f851ab5771166be2e66540abc85e
4
+ data.tar.gz: 3b424125fb3f00a0dcafb5be8b9fabd33bd62785
5
5
  SHA512:
6
- metadata.gz: a257132168202d1b7540286aad139cf52f3052924f64af76192ea65244ed591aff0dfc28241ee4e17497ab399b68639478e6200943757321b2a73c71fbd619fc
7
- data.tar.gz: c027d0fad82b687ae3d3f56335f7d81f50818f964a0d659b14bef3697124539efccd74e6dd72434bae896d3a30f508c411e36c113c0c8c61a55500ae8d1ab3d2
6
+ metadata.gz: 43fcf881e75fc6a9a78b00e1e69eb352c79aac330153fadf5df20f7e4dfda8c0da42b18ca5e25fd1e84cd897201024ffccd82e84210c919c2e750a9b7c8c1573
7
+ data.tar.gz: 769e82ffa9da3bed89475ef155a5c66e36263cd53cd9a61ae545183b5ad631da704f69abe650ba8080080bcae5943dba787df325d6f614dcbf5db60ba6b58e5d
data/Manifest.txt CHANGED
@@ -12,11 +12,15 @@ Protocol.md
12
12
  README.md
13
13
  Rakefile
14
14
  TODO.md
15
- bin/amanagerd
16
- bin/amonitord
17
- bin/aobserverd
15
+ Tutorial.md
16
+ bin/arborist
18
17
  lib/arborist.rb
18
+ lib/arborist/cli.rb
19
19
  lib/arborist/client.rb
20
+ lib/arborist/command/client.rb
21
+ lib/arborist/command/config.rb
22
+ lib/arborist/command/start.rb
23
+ lib/arborist/command/watch.rb
20
24
  lib/arborist/event.rb
21
25
  lib/arborist/event/node_acked.rb
22
26
  lib/arborist/event/node_delta.rb
@@ -24,6 +28,8 @@ lib/arborist/event/node_matching.rb
24
28
  lib/arborist/event/node_update.rb
25
29
  lib/arborist/event/sys_reloaded.rb
26
30
  lib/arborist/exceptions.rb
31
+ lib/arborist/loader.rb
32
+ lib/arborist/loader/file.rb
27
33
  lib/arborist/manager.rb
28
34
  lib/arborist/manager/event_publisher.rb
29
35
  lib/arborist/manager/tree_api.rb
data/README.md CHANGED
@@ -1,17 +1,26 @@
1
1
  # Arborist
2
2
 
3
- home :: http://deveiate.org/projects/Arborist
4
- code :: http://bitbucket.org/ged/Arborist
5
- github :: https://github.com/ged/arborist
6
- docs :: http://deveiate.org/code/arborist
3
+ home
4
+ : http://deveiate.org/projects/Arborist
5
+
6
+ code
7
+ : http://bitbucket.org/ged/Arborist
8
+
9
+ github
10
+ : https://github.com/ged/arborist
11
+
12
+ docs
13
+ : http://deveiate.org/code/arborist
7
14
 
8
15
 
9
16
  ## Description
10
17
 
11
- Arborist is a monitoring framework that follows the UNIX philosophy
18
+ Arborist is a monitoring toolkit that follows the UNIX philosophy
12
19
  of small parts and loose coupling for stability, reliability, and
13
20
  customizability.
14
21
 
22
+ [![Build Status](https://semaphoreci.com/api/v1/projects/13677b60-5f81-4e6e-a9c6-e21d30daa4ca/461532/badge.svg)](https://semaphoreci.com/ged/arborist)
23
+
15
24
 
16
25
  ## Prerequisites
17
26
 
@@ -44,7 +53,7 @@ and generate the API documentation.
44
53
 
45
54
  ## License
46
55
 
47
- Copyright (c) 2015, Michael Granger and Mahlon E. Smith
56
+ Copyright (c) 2015-2016, Michael Granger and Mahlon E. Smith
48
57
  All rights reserved.
49
58
 
50
59
  Redistribution and use in source and binary forms, with or without
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ hoespec = Hoe.spec 'arborist' do |spec|
20
20
  spec.readme_file = 'README.md'
21
21
  spec.history_file = 'History.md'
22
22
  spec.extra_rdoc_files = FileList[ '*.rdoc', '*.md' ]
23
- self.license 'BSD-3-Clause'
23
+ spec.license 'BSD-3-Clause'
24
24
  spec.urls = {
25
25
  home: 'http://deveiate.org/projects/arborist',
26
26
  code: 'http://bitbucket.org/ged/arborist',
@@ -46,7 +46,7 @@ hoespec = Hoe.spec 'arborist' do |spec|
46
46
  spec.require_ruby_version( '>=2.2.0' )
47
47
  spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
48
48
 
49
- self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
49
+ spec.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
50
50
  end
51
51
 
52
52
 
@@ -66,6 +66,20 @@ task :coverage do
66
66
  end
67
67
 
68
68
 
69
+ # Use the fivefish formatter for docs generated from development checkout
70
+ if File.directory?( '.hg' )
71
+ require 'rdoc/task'
72
+
73
+ Rake::Task[ 'docs' ].clear
74
+ RDoc::Task.new( 'docs' ) do |rdoc|
75
+ rdoc.main = "README.md"
76
+ rdoc.rdoc_files.include( "*.rdoc", "*.md", "ChangeLog", "lib/**/*.rb" )
77
+ rdoc.generator = :fivefish
78
+ rdoc.title = 'Arborist'
79
+ rdoc.rdoc_dir = 'doc'
80
+ end
81
+ end
82
+
69
83
  task :gemspec => GEMSPEC
70
84
  file GEMSPEC => __FILE__ do |task|
71
85
  spec = $hoespec.spec
data/TODO.md CHANGED
@@ -5,6 +5,7 @@
5
5
  * Serialize nodes on shutdown
6
6
  * Include a node's subscriptions in its serialized data
7
7
  * Implement loading/reloading nodes.
8
+ * Implement the system events (sys.acked, sys.reloaded, etc.)
8
9
 
9
10
  ## Tree API
10
11
 
@@ -21,4 +22,12 @@
21
22
 
22
23
  ## Node
23
24
 
24
- * Add a 'disabled' state, can be set on 'up' nodes by acking them.
25
+ * Allow (require?) node types to specify what kinds of nodes can be
26
+ their parent, and also adds the constructor DSL method to it
27
+
28
+
29
+ ## Setup/Installation
30
+
31
+ * Add a CLI for generating a basic setup and then adding
32
+ nodes/monitors/observers to it.
33
+
data/Tutorial.md ADDED
@@ -0,0 +1,8 @@
1
+ # Arborist Tutorial
2
+
3
+ Sorry, we're still building. We'll flesh this out once we get the software
4
+ stable and work out the kinks.
5
+
6
+ In the meantime, feel free to come chat us up in the
7
+ [Arborist Gitter channel](https://gitter.im/ged/arborist).
8
+
data/bin/arborist ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set nosta noet ts=4 sw=4:
3
+
4
+ require 'arborist'
5
+ require 'arborist/cli'
6
+
7
+ Arborist::CLI.run( ARGV.dup )
8
+
data/lib/arborist.rb CHANGED
@@ -17,7 +17,7 @@ module Arborist
17
17
  VERSION = '0.0.1'
18
18
 
19
19
  # Version control revision
20
- REVISION = %q$Revision: fddcbace9b6d $
20
+ REVISION = %q$Revision: e23d2b9f8f31 $
21
21
 
22
22
 
23
23
  # The name of the environment variable which can be used to set the config path
@@ -111,11 +111,10 @@ module Arborist
111
111
  end
112
112
 
113
113
 
114
- ### Return a new Arborist::Manager for the nodes described in files under
115
- ### the specified +directory+.
116
- def self::manager_for( directory )
114
+ ### Return a new Arborist::Manager for the nodes loaded by the specified +loader+.
115
+ def self::manager_for( loader )
117
116
  self.load_all
118
- nodes = Arborist::Node.each_in( directory )
117
+ nodes = Arborist::Node.each_in( loader )
119
118
  manager = Arborist::Manager.new
120
119
  manager.load_tree( nodes )
121
120
 
@@ -124,10 +123,10 @@ module Arborist
124
123
 
125
124
 
126
125
  ### Return a new Arborist::MonitorRunner for the monitors described in files under
127
- ### the specified +directory+.
128
- def self::monitor_runner_for( directory )
126
+ ### the specified +loader+.
127
+ def self::monitor_runner_for( loader )
129
128
  self.load_all
130
- monitors = Arborist::Monitor.each_in( directory )
129
+ monitors = Arborist::Monitor.each_in( loader )
131
130
  runner = Arborist::MonitorRunner.new
132
131
  runner.load_monitors( monitors )
133
132
 
@@ -136,10 +135,10 @@ module Arborist
136
135
 
137
136
 
138
137
  ### Return a new Arborist::ObserverRunner for the observers described in files under
139
- ### the specified +directory+.
140
- def self::observer_runner_for( directory )
138
+ ### the specified +loader+.
139
+ def self::observer_runner_for( loader )
141
140
  self.load_all
142
- observers = Arborist::Observer.each_in( directory )
141
+ observers = Arborist::Observer.each_in( loader )
143
142
  runner = Arborist::ObserverRunner.new
144
143
  runner.load_observers( observers )
145
144
 
@@ -171,11 +170,13 @@ module Arborist
171
170
 
172
171
  autoload :Client, 'arborist/client'
173
172
  autoload :Event, 'arborist/event'
173
+ autoload :Loader, 'arborist/loader'
174
174
  autoload :Manager, 'arborist/manager'
175
175
  autoload :Monitor, 'arborist/monitor'
176
176
  autoload :MonitorRunner, 'arborist/monitor_runner'
177
177
  autoload :Node, 'arborist/node'
178
178
  autoload :Observer, 'arborist/observer'
179
+ autoload :ObserverRunner, 'arborist/observer_runner'
179
180
  autoload :Subscription, 'arborist/subscription'
180
181
 
181
182
  end # module Arborist
@@ -0,0 +1,380 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'loggability'
5
+ require 'highline'
6
+ require 'gli'
7
+
8
+ require 'arborist' unless defined?( Arborist )
9
+ require 'arborist/mixins'
10
+
11
+
12
+ # The command-line interface to Arborist.
13
+ module Arborist::CLI
14
+ extend Arborist::MethodUtilities,
15
+ Loggability,
16
+ GLI::App
17
+
18
+
19
+ # Write logs to Arborist's logger
20
+ log_to :arborist
21
+
22
+
23
+ # Make a HighLine color scheme
24
+ COLOR_SCHEME = HighLine::ColorScheme.new do |scheme|
25
+ scheme[:header] = [ :bold, :yellow ]
26
+ scheme[:subheader] = [ :bold, :white ]
27
+ scheme[:key] = [ :white ]
28
+ scheme[:value] = [ :bold, :white ]
29
+ scheme[:error] = [ :red ]
30
+ scheme[:warning] = [ :yellow ]
31
+ scheme[:message] = [ :reset ]
32
+ end
33
+
34
+
35
+ #
36
+ # GLI
37
+ #
38
+
39
+ # Set up global[:description] and options
40
+ program_desc 'Arborist'
41
+
42
+ # The command version
43
+ version Arborist::VERSION
44
+
45
+ # Use an OpenStruct for options instead of a Hash
46
+ use_openstruct( true )
47
+
48
+ # Subcommand options are independent of global[:ones]
49
+ subcommand_option_handling :normal
50
+
51
+ # Strict argument validation
52
+ arguments :strict
53
+
54
+
55
+ # Custom parameter types
56
+ accept Array do |value|
57
+ value.strip.split(/\s*,\s*/)
58
+ end
59
+ accept Pathname do |value|
60
+ Pathname( value.strip )
61
+ end
62
+
63
+
64
+ # Global options
65
+ desc "Specify the config file to load"
66
+ flag [:c, :config], type: Pathname
67
+
68
+ desc 'Enable debugging output'
69
+ switch [:d, :debug]
70
+
71
+ desc 'Enable verbose output'
72
+ switch [:v, :verbose]
73
+
74
+ desc 'Set log level to LEVEL (one of %s)' % [Loggability::LOG_LEVELS.keys.join(', ')]
75
+ default_value Loggability[self].level
76
+ flag [:l, :loglevel], must_match: Loggability::LOG_LEVELS.keys
77
+
78
+ desc "Don't actually do anything, just show what would happen."
79
+ switch [:n, 'dry-run']
80
+
81
+ desc "Additional Ruby libs to require before doing anything."
82
+ flag [:r, 'requires'], type: Array
83
+
84
+
85
+ #
86
+ # GLI Event callbacks
87
+ #
88
+
89
+ pre do |global, command, options, args|
90
+ if loglevel = global[:loglevel]
91
+ Loggability.level = loglevel.to_sym
92
+ else
93
+ Loggability.level = :fatal
94
+ end
95
+
96
+ # Include a 'lib' directory if there is one
97
+ $LOAD_PATH.unshift( 'lib' ) if File.directory?( 'lib' )
98
+
99
+ self.require_additional_libs( global.requires ) if global.requires
100
+ self.load_config( global )
101
+ self.install_highline_colorscheme
102
+
103
+ true
104
+ end
105
+
106
+
107
+ ##
108
+ # Registered subcommand modules
109
+ singleton_attr_accessor :subcommand_modules
110
+
111
+ ##
112
+ # The IO opened to the output file
113
+ singleton_attr_accessor :outfile
114
+
115
+
116
+ ### Overridden -- Add registered subcommands immediately before running.
117
+ def self::run( * )
118
+ self.add_registered_subcommands
119
+ super
120
+ end
121
+
122
+
123
+ ### Add the specified +mod+ule containing subcommands to the 'arborist' command.
124
+ def self::register_subcommands( mod )
125
+ self.subcommand_modules ||= []
126
+ self.subcommand_modules.push( mod )
127
+ mod.extend( GLI::DSL, GLI::AppSupport, Loggability )
128
+ mod.log_to( :arborist )
129
+ end
130
+
131
+
132
+ ### Add the commands from the registered subcommand modules.
133
+ def self::add_registered_subcommands
134
+ self.subcommand_modules ||= []
135
+ self.subcommand_modules.each do |mod|
136
+ merged_commands = mod.commands.merge( self.commands )
137
+ self.commands.update( merged_commands )
138
+ command_objs = self.commands_declaration_order | self.commands.values
139
+ self.commands_declaration_order.replace( command_objs )
140
+ end
141
+ end
142
+
143
+
144
+ ### Return the HighLine prompt used by the command to communicate with the
145
+ ### user.
146
+ def self::prompt
147
+ @prompt ||= HighLine.new( $stdin, $stderr )
148
+ end
149
+
150
+
151
+ ### If the command's output was redirected to a file, return the open File object
152
+ ### for it.
153
+ def self::outfile
154
+ return @outfile
155
+ end
156
+
157
+
158
+ ### Discard the existing HighLine prompt object if one existed. Mostly useful for
159
+ ### testing.
160
+ def self::reset_prompt
161
+ @prompt = nil
162
+ end
163
+
164
+
165
+ ### Load any additional Ruby libraries given with the -r global option.
166
+ def self::require_additional_libs( requires)
167
+ requires.each do |path|
168
+ path = "arborist/#{path}" unless path.start_with?( 'arborist/' )
169
+ require( path )
170
+ end
171
+ end
172
+
173
+
174
+ ### Install the color scheme used by HighLine
175
+ def self::install_highline_colorscheme
176
+ HighLine.color_scheme = HighLine::ColorScheme.new do |cs|
177
+ cs[:headline] = [ :bold, :white, :on_black ]
178
+ cs[:success] = [ :bold, :green ]
179
+ cs[:error] = [ :bold, :red ]
180
+ cs[:up] = [ :green ]
181
+ cs[:down] = [ :red ]
182
+ cs[:unknown] = [ :dark, :yellow ]
183
+ cs[:disabled] = [ :dark, :white ]
184
+ cs[:acked] = [ :yellow ]
185
+ cs[:highlight] = [ :bold, :yellow ]
186
+ cs[:search_hit] = [ :black, :on_white ]
187
+ cs[:prompt] = [ :cyan ]
188
+ cs[:even_row] = [ :bold ]
189
+ cs[:odd_row] = [ :normal ]
190
+ end
191
+ end
192
+
193
+
194
+ ### Load the config file using either arborist-base's config-loader if available, or
195
+ ### fall back to DEFAULT_CONFIG_FILE
196
+ def self::load_config( global={} )
197
+ Arborist.load_config( global.config ) if global.config
198
+
199
+ # Set up the logging formatter
200
+ Loggability.format_with( :color ) if $stdout.tty?
201
+ end
202
+
203
+
204
+ ### Set up the output levels and globals based on the associated +global+ options.
205
+ def self::setup_output( global )
206
+
207
+ # Turn on Ruby debugging and/or verbosity if specified
208
+ if global[:n]
209
+ $DRYRUN = true
210
+ Loggability.level = :warn
211
+ else
212
+ $DRYRUN = false
213
+ end
214
+
215
+ if global[:verbose]
216
+ $VERBOSE = true
217
+ Loggability.level = :info
218
+ end
219
+
220
+ if global[:debug]
221
+ $DEBUG = true
222
+ Loggability.level = :debug
223
+ end
224
+ end
225
+
226
+
227
+ # Write the error to the log on exceptions.
228
+ on_error do |exception|
229
+ case exception
230
+ when OptionParser::ParseError, GLI::CustomExit
231
+ self.log.debug( exception )
232
+ else
233
+ self.log.error( exception )
234
+ end
235
+
236
+ exception.backtrace.each {|frame| self.log.debug(frame) }
237
+
238
+ true
239
+ end
240
+
241
+
242
+ #
243
+ # GLI subcommands
244
+ #
245
+
246
+
247
+ # Convenience module for subcommand registration syntax sugar.
248
+ module Subcommand
249
+
250
+ ### Extension callback -- register the extending object as a subcommand.
251
+ def self::extended( mod )
252
+ Arborist::CLI.log.debug "Registering subcommands from %p" % [ mod ]
253
+ Arborist::CLI.register_subcommands( mod )
254
+ end
255
+
256
+
257
+ ###############
258
+ module_function
259
+ ###############
260
+
261
+ ### Exit with the specified +exit_code+ after printing the given +message+.
262
+ def exit_now!( message, exit_code=1 )
263
+ raise GLI::CustomExit.new( message, exit_code )
264
+ end
265
+
266
+
267
+ ### Exit with a helpful +message+ and display the usage.
268
+ def help_now!( message=nil )
269
+ exception = OptionParser::ParseError.new( message )
270
+ def exception.exit_code; 64; end
271
+
272
+ raise exception
273
+ end
274
+
275
+
276
+ ### Get the prompt (a Highline object)
277
+ def prompt
278
+ return Arborist::CLI.prompt
279
+ end
280
+
281
+
282
+ ### Return the specified +text+ as a Highline::String for convenient formatting,
283
+ ### color, etc.
284
+ def hl( text )
285
+ return HighLine::String.new( text.to_s )
286
+ end
287
+
288
+
289
+ ### Return the specified +string+ in the 'headline' ANSI color.
290
+ def headline_string( string )
291
+ return hl( string ).color( :headline )
292
+ end
293
+
294
+
295
+ ### Return the specified +string+ in the 'highlight' ANSI color.
296
+ def highlight_string( string )
297
+ return hl( string ).color( :highlight )
298
+ end
299
+
300
+
301
+ ### Return the specified +string+ in the 'success' ANSI color.
302
+ def success_string( string )
303
+ return hl( string ).color( :success )
304
+ end
305
+
306
+
307
+ ### Return the specified +string+ in the 'error' ANSI color.
308
+ def error_string( string )
309
+ return hl( string ).color( :error )
310
+ end
311
+
312
+
313
+ ### Output a table with the given +rows+.
314
+ def display_table( rows )
315
+ colwidths = rows.transpose.map do |colvals|
316
+ colvals.map {|val| visible_chars(val) }.max
317
+ end
318
+
319
+ rows.each do |row|
320
+ row_string = row.zip( colwidths ).inject( '' ) do |accum, (val, colsize)|
321
+ padding = ' ' * (colsize - visible_chars(val) + 2)
322
+ accum + val.to_s + padding
323
+ end
324
+
325
+ Arborist::CLI.prompt.say( row_string + "\n" )
326
+ end
327
+ end
328
+
329
+
330
+ ### Return the count of visible (i.e., non-control) characters in the given +string+.
331
+ def visible_chars( string )
332
+ return string.to_s.gsub(/\e\[.*?m/, '').scan( /\P{Cntrl}/ ).size
333
+ end
334
+
335
+
336
+ ### In dry-run mode, output the description instead of running the provided block and
337
+ ### return the +return_value+.
338
+ ### If dry-run mode is not enabled, yield to the block.
339
+ def unless_dryrun( description, return_value=true )
340
+ if $DRYRUN
341
+ self.log.warn( "DRYRUN> #{description}" )
342
+ return return_value
343
+ else
344
+ return yield
345
+ end
346
+ end
347
+ alias_method :unless_dry_run, :unless_dryrun
348
+
349
+ end # module Subcommand
350
+
351
+
352
+ ### Register one or more subcommands with the 'arborist' command shell. The given
353
+ ### block will be evaluated in the context of Arborist::CLI.
354
+ def self::register( &block )
355
+ self.instance_eval( &block )
356
+ end
357
+
358
+
359
+ ### Custom command loader. The default one is silly.
360
+ def self::load_commands( path )
361
+ self.log.debug "Load commands from %s" % [ path ]
362
+ Pathname.glob( path + '*.rb' ).each do |rbfile|
363
+ self.log.debug " loading %s..." % [ rbfile ]
364
+ require( rbfile )
365
+ end
366
+ end
367
+
368
+
369
+ # Load commands from any files in the specified directory relative to LOAD_PATHs
370
+ def self::commands_from( subdir )
371
+ $LOAD_PATH.map {|path| Pathname(path) }.each do |libdir|
372
+ command_dir = libdir.expand_path + subdir
373
+ load_commands( command_dir )
374
+ end
375
+ end
376
+
377
+
378
+ commands_from 'arborist/command'
379
+
380
+ end # class Arborist::CLI