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 +4 -4
- data/Manifest.txt +9 -3
- data/README.md +15 -6
- data/Rakefile +16 -2
- data/TODO.md +10 -1
- data/Tutorial.md +8 -0
- data/bin/arborist +8 -0
- data/lib/arborist.rb +12 -11
- data/lib/arborist/cli.rb +380 -0
- data/lib/arborist/client.rb +16 -0
- data/lib/arborist/command/client.rb +30 -0
- data/lib/arborist/command/config.rb +20 -0
- data/lib/arborist/command/start.rb +60 -0
- data/lib/arborist/command/watch.rb +88 -0
- data/lib/arborist/event/node_matching.rb +5 -0
- data/lib/arborist/loader.rb +43 -0
- data/lib/arborist/loader/file.rb +72 -0
- data/lib/arborist/manager.rb +4 -3
- data/lib/arborist/monitor.rb +8 -22
- data/lib/arborist/node.rb +57 -37
- data/lib/arborist/observer.rb +4 -18
- data/spec/arborist/client_spec.rb +1 -1
- data/spec/arborist/manager/tree_api_spec.rb +1 -0
- data/spec/arborist/manager_spec.rb +15 -4
- data/spec/arborist/monitor_spec.rb +13 -9
- data/spec/arborist/node_spec.rb +36 -6
- data/spec/arborist_spec.rb +36 -5
- data/spec/data/monitors/pings.rb +1 -0
- data/spec/data/monitors/port_checks.rb +0 -3
- data/spec/spec_helper.rb +4 -1
- metadata +18 -11
- data/bin/amanagerd +0 -10
- data/bin/amonitord +0 -12
- data/bin/aobserverd +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff35c627aec6f851ab5771166be2e66540abc85e
|
4
|
+
data.tar.gz: 3b424125fb3f00a0dcafb5be8b9fabd33bd62785
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
16
|
-
bin/
|
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
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
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
|
+
[](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
|
-
|
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
|
-
|
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
|
-
*
|
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
data/bin/arborist
ADDED
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:
|
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
|
115
|
-
|
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(
|
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 +
|
128
|
-
def self::monitor_runner_for(
|
126
|
+
### the specified +loader+.
|
127
|
+
def self::monitor_runner_for( loader )
|
129
128
|
self.load_all
|
130
|
-
monitors = Arborist::Monitor.each_in(
|
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 +
|
140
|
-
def self::observer_runner_for(
|
138
|
+
### the specified +loader+.
|
139
|
+
def self::observer_runner_for( loader )
|
141
140
|
self.load_all
|
142
|
-
observers = Arborist::Observer.each_in(
|
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
|
data/lib/arborist/cli.rb
ADDED
@@ -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
|