cmd-utils 1.0.12 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +64 -0
- data/LICENSE.txt +20 -0
- data/README.md +255 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/cmd-utils.gemspec +67 -0
- data/lib/cmd-utils.rb +17 -15
- data/lib/ssh-utils.rb +134 -0
- data/test/helper.rb +35 -0
- data/{tests → test}/test-cmd-utils.rb +4 -4
- data/{tests → test}/test-lookup.rb +13 -5
- data/test/test_cmd-utils.rb.off +7 -0
- metadata +97 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f047ffb87574fcc165f9651ff733e2f42f0c2e3
|
4
|
+
data.tar.gz: b64622069ed70aca2474362658474f88c9f26542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d74547e65fb7d59e99aae4cc87d6bb358c3b3a0a784e2894b90e37db53e58f0be35fbb10cf107c3c0c8f6b4cc74a17fada172071c5f658d4498232a7ac7580fd
|
7
|
+
data.tar.gz: e56c5364aed15bb4cc340924bf0e64c434007081e600eaa3ddd65e7377a22858fae8671b8244707f905d4e93754442857ce693371470e13424a7d83ba141b137
|
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "minitest", ">= 5.3.0"
|
10
|
+
#gem "shoulda"
|
11
|
+
gem "rdoc"
|
12
|
+
gem "bundler"
|
13
|
+
gem "jeweler"
|
14
|
+
gem "simplecov"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.5)
|
5
|
+
builder (3.2.2)
|
6
|
+
descendants_tracker (0.0.3)
|
7
|
+
docile (1.1.3)
|
8
|
+
faraday (0.9.0)
|
9
|
+
multipart-post (>= 1.2, < 3)
|
10
|
+
git (1.2.6)
|
11
|
+
github_api (0.11.3)
|
12
|
+
addressable (~> 2.3)
|
13
|
+
descendants_tracker (~> 0.0.1)
|
14
|
+
faraday (~> 0.8, < 0.10)
|
15
|
+
hashie (>= 1.2)
|
16
|
+
multi_json (>= 1.7.5, < 2.0)
|
17
|
+
nokogiri (~> 1.6.0)
|
18
|
+
oauth2
|
19
|
+
hashie (2.0.5)
|
20
|
+
highline (1.6.21)
|
21
|
+
jeweler (2.0.1)
|
22
|
+
builder
|
23
|
+
bundler (>= 1.0)
|
24
|
+
git (>= 1.2.5)
|
25
|
+
github_api
|
26
|
+
highline (>= 1.6.15)
|
27
|
+
nokogiri (>= 1.5.10)
|
28
|
+
rake
|
29
|
+
rdoc
|
30
|
+
json (1.8.1)
|
31
|
+
jwt (0.1.11)
|
32
|
+
multi_json (>= 1.5)
|
33
|
+
mini_portile (0.5.2)
|
34
|
+
minitest (5.3.0)
|
35
|
+
multi_json (1.8.4)
|
36
|
+
multi_xml (0.5.5)
|
37
|
+
multipart-post (2.0.0)
|
38
|
+
nokogiri (1.6.1)
|
39
|
+
mini_portile (~> 0.5.0)
|
40
|
+
oauth2 (0.9.3)
|
41
|
+
faraday (>= 0.8, < 0.10)
|
42
|
+
jwt (~> 0.1.8)
|
43
|
+
multi_json (~> 1.3)
|
44
|
+
multi_xml (~> 0.5)
|
45
|
+
rack (~> 1.2)
|
46
|
+
rack (1.5.2)
|
47
|
+
rake (10.1.1)
|
48
|
+
rdoc (4.1.1)
|
49
|
+
json (~> 1.4)
|
50
|
+
simplecov (0.8.2)
|
51
|
+
docile (~> 1.1.0)
|
52
|
+
multi_json
|
53
|
+
simplecov-html (~> 0.8.0)
|
54
|
+
simplecov-html (0.8.0)
|
55
|
+
|
56
|
+
PLATFORMS
|
57
|
+
ruby
|
58
|
+
|
59
|
+
DEPENDENCIES
|
60
|
+
bundler
|
61
|
+
jeweler
|
62
|
+
minitest (>= 5.3.0)
|
63
|
+
rdoc
|
64
|
+
simplecov
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Alan K. Stebbens
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,255 @@
|
|
1
|
+
cmd-utils
|
2
|
+
=========
|
3
|
+
|
4
|
+
Utilities for writing command line tools in ruby.
|
5
|
+
|
6
|
+
Installation:
|
7
|
+
|
8
|
+
gem install cmd-utils
|
9
|
+
|
10
|
+
Usage:
|
11
|
+
|
12
|
+
require 'cmd-utils'
|
13
|
+
require 'ssh-utils'
|
14
|
+
require 'lookup'
|
15
|
+
|
16
|
+
This gem provides:
|
17
|
+
|
18
|
+
* routines for output on `$stderr`, controlled by several global variables
|
19
|
+
* error-reporting-and-exit
|
20
|
+
* system call handling, with verbose or debug output, error and "ok" message handling
|
21
|
+
* remote system command invocation (based on ssh)
|
22
|
+
* ambiguous, case-insensitive string lookups in arrays or hashs, with error handling
|
23
|
+
|
24
|
+
talk, dtalk, qtalk, vtalk, nrtalk, nvtalk
|
25
|
+
=========================================
|
26
|
+
|
27
|
+
These utilities provide simple utilities that rely on the following global variables:
|
28
|
+
|
29
|
+
`$verbose` -- enables vtalk(f) function output
|
30
|
+
`$norun` -- enables nrtalk(f) output, and disables the "run" command execution
|
31
|
+
`$quiet` -- disables talk(f) output, and enables qtalk(f) function output
|
32
|
+
`$debug` -- enables dtalk(f) function output
|
33
|
+
|
34
|
+
These routines provide option-controlled output. The arguments can be given as
|
35
|
+
part of the the function calls, or, can be provided as the return value of a
|
36
|
+
block.
|
37
|
+
|
38
|
+
The advantage of using a block is that the block is not evaluated unless the
|
39
|
+
conditions requiring output are met. So, if the expression to compute a value
|
40
|
+
that _might_ be printed is expensive, do the computation inside a block.
|
41
|
+
|
42
|
+
The brief synopses given below show the function calls with arguments, and then
|
43
|
+
the function calls with the arguments passed as the block's return value.
|
44
|
+
|
45
|
+
Talk:
|
46
|
+
|
47
|
+
talk msg - print msg on STDERR unless $quiet
|
48
|
+
talk { msg }
|
49
|
+
talkf fmt, args ..
|
50
|
+
talkf(fmt) { args .. }
|
51
|
+
|
52
|
+
Debug talk:
|
53
|
+
|
54
|
+
dtalk msg - print msg on STDERR if $debug
|
55
|
+
dtalk { msg }
|
56
|
+
dtalkf fmt, args ..
|
57
|
+
dtalkf(fmt) { args .. }
|
58
|
+
|
59
|
+
Quiet talk:
|
60
|
+
|
61
|
+
qtalk msg - print msg on STDERR if $quiet
|
62
|
+
qtalk { msg }
|
63
|
+
qtalkf fmt, args ..
|
64
|
+
qtalkf(fmt) { args .. }
|
65
|
+
|
66
|
+
Verbose talk:
|
67
|
+
|
68
|
+
vtalk msg - print msg on STDERR if $verbose
|
69
|
+
vtalk { msg }
|
70
|
+
vtalkf fmt, args ..
|
71
|
+
vtalkf(fmt) { args .. }
|
72
|
+
|
73
|
+
No-run talk:
|
74
|
+
|
75
|
+
nrtalk msg - print msg on STDERR if $norun || $verbose
|
76
|
+
nrtalk { msg }
|
77
|
+
nrtalkf fmt, args ..
|
78
|
+
nrtalkf(fmt) { args .. }
|
79
|
+
|
80
|
+
Non-verbose talk:
|
81
|
+
|
82
|
+
nvtalk msg - print msg on STDERR unless $verbose
|
83
|
+
nvtalk { msg }
|
84
|
+
nvtalkf fmt, args ..
|
85
|
+
nvtalkf(fmt) { args .. }
|
86
|
+
|
87
|
+
Error output:
|
88
|
+
|
89
|
+
error [code,] msg - print msg on STDERR, exit with CODE [default:1]
|
90
|
+
error { [ [code,] msg ] }
|
91
|
+
errorf [code,] fmt, args ..
|
92
|
+
errorf { [ [code,] fmt, args .. ] }
|
93
|
+
|
94
|
+
The `error` routine take an optional numeric first argument which is used to
|
95
|
+
set the exit code. If not given, the exit code is 1.
|
96
|
+
|
97
|
+
`cmd_run`
|
98
|
+
--------
|
99
|
+
|
100
|
+
cmd_run cmd
|
101
|
+
cmd_run { cmd }
|
102
|
+
|
103
|
+
Variants:
|
104
|
+
|
105
|
+
cmd_run cmd, errmsg
|
106
|
+
cmd_run cmd, errmsg, okmsg
|
107
|
+
cmd_run (cmd) { [ errmsg, okmsg ] }
|
108
|
+
cmd_run { [ cmd, errmsg, okmsg ] }
|
109
|
+
|
110
|
+
The `cmd_run` method depends on the `$norun` and `$verbose` global variables.
|
111
|
+
If `$norun` is set, the `cmd` is simply displayed with a prefix of `(norun) `,
|
112
|
+
and the method returns without invoking `cmd`.
|
113
|
+
|
114
|
+
When `$norun` is false, and if `$verbose` is set, the `cmd` is displayed with
|
115
|
+
a prefix of `">> "` before executing it.
|
116
|
+
|
117
|
+
If the result of invoking `system(cmd)` is an error (non-zero exit code), then
|
118
|
+
an error is printed on `$stderr`, possibly preceded by the command itself if it
|
119
|
+
was not already printed.
|
120
|
+
|
121
|
+
Note that when using the block forms of run (e.g., `run { cmd }`), the result
|
122
|
+
of the block should be an array of one or more strings, in the same order as
|
123
|
+
the arguments. The block will always be evaluated in order to obtain the string
|
124
|
+
values that will be printed in `$norun` mode, or used as the error or ok
|
125
|
+
messages.
|
126
|
+
|
127
|
+
The `safe_run` method invokes `cmd`, regardless of `$norun`, basically wrapping the
|
128
|
+
command evaluation with the `$verbose` treatment.
|
129
|
+
|
130
|
+
safe_run cmd
|
131
|
+
safe_run cmd, errmsg
|
132
|
+
safe_run cmd, errmsg, okmsg
|
133
|
+
safe_run (cmd) {[errmsg, okmsg]}
|
134
|
+
safe_run { cmd }
|
135
|
+
safe_run {[cmd, errmsg, okmsg]}
|
136
|
+
|
137
|
+
ssh-utils
|
138
|
+
=========
|
139
|
+
|
140
|
+
A module to define some routines for running commands across many systems using
|
141
|
+
ssh. Environment variables can be specified (PATH is used by default).
|
142
|
+
|
143
|
+
Usage:
|
144
|
+
|
145
|
+
require 'ssh-utils'
|
146
|
+
|
147
|
+
on serverlist, :debug = true do |server|
|
148
|
+
as user do
|
149
|
+
with PATH
|
150
|
+
remote_run :whoami
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
Method Descriptions
|
156
|
+
-------------------
|
157
|
+
|
158
|
+
on SERVERLIST, OPTIONSHASH |server|
|
159
|
+
BLOCK-TO-EXECUTE-FOR-EACH-SERVER
|
160
|
+
end
|
161
|
+
|
162
|
+
The `on` method specifies a list of servers, with an optional hash of
|
163
|
+
options. The supported options are: `:debug`, `:verbose`, `:with`,
|
164
|
+
`:without`, and `:as`
|
165
|
+
|
166
|
+
:with => ENVARS
|
167
|
+
|
168
|
+
`ENVARS` is an array of environment symbol names (or strings) that will
|
169
|
+
be included on the `ssh` command that is used to run remote commands.
|
170
|
+
|
171
|
+
:without => ENVARS
|
172
|
+
|
173
|
+
`ENVARS` is an array of environment symbol names (or strings) that will *not*
|
174
|
+
be included on the `ssh` command that is used to run remote commands. This
|
175
|
+
option is useful when overriding the default inclusion of `PATH`. For example:
|
176
|
+
|
177
|
+
on backupserver, :without => :PATH
|
178
|
+
remote_run "/bin/tar", "-cf", source_path, dest_path
|
179
|
+
end
|
180
|
+
|
181
|
+
:as => USER
|
182
|
+
|
183
|
+
Specifies the user to be used for the subsequent invocations. By default,
|
184
|
+
the current user is used implicitly.
|
185
|
+
|
186
|
+
:debug => [true | false]
|
187
|
+
|
188
|
+
Sets the `:debug` flag for use within the associated block. The `$debug` flag
|
189
|
+
is globally available, but the `:debug` option is a block-local specification.
|
190
|
+
|
191
|
+
:verbose => [true | false]
|
192
|
+
|
193
|
+
Sets the `:verbose` flag for use within the associated block. The `$verbose` flag
|
194
|
+
is globally available, but the `:verbose` option is a block-local specification.
|
195
|
+
|
196
|
+
|
197
|
+
as USERLIST, OPTIONSHASH
|
198
|
+
BLOCK-TO-EXECUTE-FOR-EACH-USER
|
199
|
+
end
|
200
|
+
|
201
|
+
The `as` method is optional, and if absent causes the current user to
|
202
|
+
be used by default (unless overridden by the `~/.ssh/config` file).
|
203
|
+
|
204
|
+
The `as` method allows the embedded block to be repeated for each given user.
|
205
|
+
If there only one user, it can be specified on the `on` method with an `:as`
|
206
|
+
option. For example, the following two sections are equivalent:
|
207
|
+
|
208
|
+
on someserver
|
209
|
+
as root
|
210
|
+
remote_run :whoami
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
on someserver, :as => 'root'
|
215
|
+
remote_run :whoami
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
lookup
|
221
|
+
======
|
222
|
+
|
223
|
+
usage:
|
224
|
+
|
225
|
+
require 'lookup'
|
226
|
+
|
227
|
+
lookup: lookup a keyword in a list, in a case-insensitive, disambiguous way
|
228
|
+
|
229
|
+
result = lookup list, key, err_notfound="%s not found", err_ambig="% is ambiguous"
|
230
|
+
result = list.lookup( key, err_notfound, err_ambig )
|
231
|
+
result = list.lookup( key, err_notfound )
|
232
|
+
result = list.lookup( key )
|
233
|
+
|
234
|
+
Lookup key in list, which can be an array or a hash. Return the one that
|
235
|
+
matches exactly, or matches using case-insensitive, unambiguous matches, or
|
236
|
+
raise a LookupError with a message.
|
237
|
+
|
238
|
+
`LookupError` is a subclass of StandardError.
|
239
|
+
|
240
|
+
`LookupNotFoundError`, a subclass of `LookupError`, is raised when a keyword is
|
241
|
+
not found, and only if `err_notfound` is not nil.
|
242
|
+
|
243
|
+
`LookupAmbigError`, a subsclass of `LookupError`, is raised when a keyword search
|
244
|
+
matches multiple entries from the list, and only if `err_ambig` is not nil.
|
245
|
+
|
246
|
+
If `err_notfound` is nil, do not raise a `LookupNotFoundError` error, and return
|
247
|
+
nil.
|
248
|
+
|
249
|
+
If `err_ambigmsg` is nil, do not raise a `LookupAmbigError`, and return the list
|
250
|
+
of possible results.
|
251
|
+
|
252
|
+
Author
|
253
|
+
------
|
254
|
+
|
255
|
+
Alan K. Stebbens <aks@stebbens.org>
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
+
gem.name = "cmd-utils"
|
18
|
+
gem.homepage = "http://bitbucket.org/aks_/cmd-utils"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Utilities for building CLIs}
|
21
|
+
gem.description = %Q{Several ruby libraries for building command-line utilities.}
|
22
|
+
gem.email = "aks@stebbens.org"
|
23
|
+
gem.authors = ["Alan K. Stebbens"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test-*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Code coverage detail"
|
36
|
+
task :simplecov do
|
37
|
+
ENV['COVERAGE'] = "true"
|
38
|
+
Rake::Task['test'].execute
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :test
|
42
|
+
|
43
|
+
require 'rdoc/task'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "cmd-utils #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.2
|
data/cmd-utils.gemspec
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: cmd-utils 1.1.2 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "cmd-utils"
|
9
|
+
s.version = "1.1.2"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Alan K. Stebbens"]
|
14
|
+
s.date = "2014-03-03"
|
15
|
+
s.description = "Several ruby libraries for building command-line utilities."
|
16
|
+
s.email = "aks@stebbens.org"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.md",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"cmd-utils.gemspec",
|
30
|
+
"lib/cmd-utils.rb",
|
31
|
+
"lib/lookup.rb",
|
32
|
+
"lib/ssh-utils.rb",
|
33
|
+
"test/helper.rb",
|
34
|
+
"test/test-cmd-utils.rb",
|
35
|
+
"test/test-lookup.rb",
|
36
|
+
"test/test_cmd-utils.rb.off"
|
37
|
+
]
|
38
|
+
s.homepage = "http://bitbucket.org/aks_/cmd-utils"
|
39
|
+
s.licenses = ["MIT"]
|
40
|
+
s.rubygems_version = "2.2.2"
|
41
|
+
s.summary = "Utilities for building CLIs"
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
s.specification_version = 4
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_development_dependency(%q<minitest>, [">= 5.3.0"])
|
48
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<minitest>, [">= 5.3.0"])
|
54
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
55
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
56
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
57
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<minitest>, [">= 5.3.0"])
|
61
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
62
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
63
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
64
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/lib/cmd-utils.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
#
|
6
6
|
# require 'cmd-utils'
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# Utilities for option-controlled output, and running commands.
|
9
9
|
#
|
10
10
|
# The output and run methods rely on some external variables:
|
@@ -14,11 +14,12 @@
|
|
14
14
|
# $quiet -- enables qtalk(f) output, and disables talk(f) output
|
15
15
|
# $debug -- enables dtalk(f) output
|
16
16
|
#
|
17
|
-
# These routines provide conditional output. The arguments can be given as
|
18
|
-
# the function calls, or, can be provided as the return value of a
|
19
|
-
# of using a block is that the block is not evaluated
|
20
|
-
# output are met. So, if the expression to
|
21
|
-
# expensive, do the computation
|
17
|
+
# These routines provide conditional output. The arguments can be given as
|
18
|
+
# part of the the function calls, or, can be provided as the return value of a
|
19
|
+
# block. The advantage of using a block is that the block is not evaluated
|
20
|
+
# unless the conditions requiring output are met. So, if the expression to
|
21
|
+
# compute a value that _might_ be printed is expensive, do the computation
|
22
|
+
# inside a block.
|
22
23
|
#
|
23
24
|
##
|
24
25
|
# talk - Print msg on STDERR unless `$quiet` is set
|
@@ -62,7 +63,7 @@ def _fmtargs args, flag
|
|
62
63
|
end
|
63
64
|
|
64
65
|
##
|
65
|
-
# dtalk - "debug talk"
|
66
|
+
# dtalk - "debug talk"
|
66
67
|
# Print msg on STDERR only if `$debug` is set
|
67
68
|
#
|
68
69
|
# :call-seq:
|
@@ -77,9 +78,9 @@ def dtalk *args
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
|
80
|
-
def dtalkf *args
|
81
|
+
def dtalkf *args
|
81
82
|
if $debug && (args.size> 0 || block_given?)
|
82
|
-
$stderr.printf(*_fmtargs(args, block_given?) { yield })
|
83
|
+
$stderr.printf(*_fmtargs(args, block_given?) { yield })
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
@@ -99,7 +100,7 @@ def qtalk *args
|
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
def qtalkf *args
|
103
|
+
def qtalkf *args
|
103
104
|
if $quiet && (args.size > 0 || block_given?)
|
104
105
|
$stderr.printf(*_fmtargs(args, block_given?) { yield } )
|
105
106
|
end
|
@@ -222,6 +223,7 @@ end
|
|
222
223
|
# run { [cmd, errmsg] }
|
223
224
|
# run { [cmd, errmsg, okmg] }
|
224
225
|
# run cmd, errmsg, okmsg
|
226
|
+
#
|
225
227
|
# safe_run cmd
|
226
228
|
# safe_run cmd, errmsg
|
227
229
|
# safe_run cmd, errmsg, okmsg
|
@@ -238,10 +240,10 @@ end
|
|
238
240
|
#
|
239
241
|
# If there is an error, show the command (preceded by `>> `) if `$verbose` is
|
240
242
|
# not set, then show the error code, followed by the given `errmsg` or the
|
241
|
-
# default error message.
|
243
|
+
# default error message.
|
242
244
|
#
|
243
245
|
# The `cmd` can be given either as an argument, or as the returned value from a
|
244
|
-
# block. Important: the block should return a string value to be passed to
|
246
|
+
# block. Important: the block should return a string value to be passed to
|
245
247
|
# the system call.
|
246
248
|
|
247
249
|
def cmd_run *args
|
@@ -249,7 +251,7 @@ def cmd_run *args
|
|
249
251
|
if $norun
|
250
252
|
nrtalk(args.first)
|
251
253
|
elsif args.size > 0
|
252
|
-
safe_run
|
254
|
+
safe_run *args
|
253
255
|
end
|
254
256
|
end
|
255
257
|
|
@@ -259,8 +261,8 @@ def safe_run *args
|
|
259
261
|
args = _msgargs(args, block_given?) { yield }
|
260
262
|
cmd, errmsg, okmsg = args
|
261
263
|
vtalkf ">> %s\n", cmd
|
262
|
-
if cmd
|
263
|
-
if system
|
264
|
+
if cmd
|
265
|
+
if system cmd # invoke the command
|
264
266
|
$stderr.puts okmsg if okmsg
|
265
267
|
return true
|
266
268
|
else # an error occured
|
data/lib/ssh-utils.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# ssh-utils.rb
|
2
|
+
#
|
3
|
+
# A module to define some routines for running commands across many systems
|
4
|
+
# using ssh
|
5
|
+
#
|
6
|
+
# Copyright 2013, Alan K. Stebbens <aks@stebbens.org>
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# require 'ssh-utils'
|
11
|
+
#
|
12
|
+
# on serverlist, :debug = true do |server|
|
13
|
+
# as user do
|
14
|
+
# with PATH
|
15
|
+
# remote_run :whoami
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
require 'rubygems'
|
21
|
+
require 'cmd-utils'
|
22
|
+
|
23
|
+
module SSH_Utils
|
24
|
+
|
25
|
+
attr_reader :server
|
26
|
+
attr_accessor :servers
|
27
|
+
|
28
|
+
@opts = {}
|
29
|
+
@opts.default = nil
|
30
|
+
@@default_envars = %w(PATH) # default envarlist
|
31
|
+
|
32
|
+
def merge_opts opts = {}
|
33
|
+
@opts ||= {}
|
34
|
+
@opts.merge!(opts) unless opts.empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
# merge_env opts
|
38
|
+
#
|
39
|
+
# merge envars. :with => ENVARS_TO_ADD, :without => ENVARS_TO_EXCLUDE
|
40
|
+
# :with => %w(PATH RUBYLIB)
|
41
|
+
# :without => %w(PATH)
|
42
|
+
# Removes the :with and :without keys from the opts hash
|
43
|
+
|
44
|
+
def merge_env opts
|
45
|
+
@envars = @@default_envars
|
46
|
+
if opts.key?(:with)
|
47
|
+
@envars.concat(opts[:with]).uniq!
|
48
|
+
opts.delete(:with)
|
49
|
+
end
|
50
|
+
if opts.key?(:without)
|
51
|
+
@envars -= opts[:without]
|
52
|
+
opts.delete(:without)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# on SERVERLIST, :with => %w(PATH RUBYLIB), :debug => [true|false], :norun => [true|false]
|
57
|
+
|
58
|
+
def on servers, opts = {}
|
59
|
+
merge_env (opts = opts.dup)
|
60
|
+
merge_opts opts
|
61
|
+
(@servers = servers).each do |server|
|
62
|
+
@server = server
|
63
|
+
talk("--> Running block for server #{server}..") if @opts[:debug] || $debug
|
64
|
+
yield server
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# as USER, :with => ENVARLIST, :debug => [true|false], :norun => [true|false]
|
69
|
+
|
70
|
+
def as user, opts = {}
|
71
|
+
@user = user
|
72
|
+
merge_env (opts = opts.dup)
|
73
|
+
merge_opts opts
|
74
|
+
yield if block_given?
|
75
|
+
end
|
76
|
+
|
77
|
+
# with ENVARLIST, :VAR1 => value, :debug => ...
|
78
|
+
|
79
|
+
def with env, opts = {}
|
80
|
+
merge_env (opts = opts.dup)
|
81
|
+
merge_opts opts
|
82
|
+
end
|
83
|
+
|
84
|
+
def ssh_command cmd
|
85
|
+
ssh = "ssh -A"
|
86
|
+
ssh += " -u #{@user}" unless @user.nil?
|
87
|
+
ssh += " #{@server}"
|
88
|
+
@envars.each do |env|
|
89
|
+
# explicit values in the options list override the environment values
|
90
|
+
val = @opts.key?(env) ? @opts[env] : ENV[env]
|
91
|
+
if !(val.nil? || val.empty?)
|
92
|
+
ssh += sprintf(" %s='%s'", env, val.gsub("'", "\'"))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
ssh += " " + cmd.to_s
|
96
|
+
ssh
|
97
|
+
end
|
98
|
+
|
99
|
+
def _show_cmd cmd
|
100
|
+
if @opts[:norun] || $norun
|
101
|
+
talkf "(norun) %s\n", cmd
|
102
|
+
elsif @opts[:debug] || $debug || @opts[:verbose] || $verbose
|
103
|
+
talkf "--> %s\n", cmd
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# remote_run COMMAND
|
108
|
+
# run the remote command
|
109
|
+
|
110
|
+
def remote_run cmd
|
111
|
+
ssh = ssh_command(cmd)
|
112
|
+
_show_cmd ssh
|
113
|
+
system(ssh) unless @opts[:norun] || $norun
|
114
|
+
end
|
115
|
+
alias :run_remotely :remote_run
|
116
|
+
|
117
|
+
|
118
|
+
def remote_run_with_output cmd, opts = {}
|
119
|
+
merge_env (opts = opts.dup)
|
120
|
+
merge_opts opts
|
121
|
+
ssh = ssh_command cmd
|
122
|
+
_show_cmd ssh
|
123
|
+
out = nil
|
124
|
+
IO.popen(ssh) {|f| out = f.read }
|
125
|
+
out
|
126
|
+
end
|
127
|
+
alias :capture :remote_run_with_output
|
128
|
+
alias :rrout :remote_run_with_output
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
include SSH_Utils
|
133
|
+
|
134
|
+
# vim: sw=2:ai
|
data/test/helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
module SimpleCov::Configuration
|
4
|
+
def clean_filters
|
5
|
+
@filters = []
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
clean_filters
|
11
|
+
load_adapter 'test_frameworks'
|
12
|
+
end
|
13
|
+
|
14
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
15
|
+
add_filter "/.rvm/"
|
16
|
+
end
|
17
|
+
require 'rubygems'
|
18
|
+
require 'bundler'
|
19
|
+
begin
|
20
|
+
Bundler.setup(:default, :development)
|
21
|
+
rescue Bundler::BundlerError => e
|
22
|
+
$stderr.puts e.message
|
23
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
24
|
+
exit e.status_code
|
25
|
+
end
|
26
|
+
require 'minitest'
|
27
|
+
require 'test/unit'
|
28
|
+
require 'shoulda'
|
29
|
+
|
30
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
31
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
32
|
+
require 'cmd-utils'
|
33
|
+
|
34
|
+
class Test::Unit::TestCase
|
35
|
+
end
|
@@ -8,7 +8,7 @@ require 'cmd-utils'
|
|
8
8
|
|
9
9
|
# these routines produce output on STDERR depending on $norun, $verbose, and $quiet.
|
10
10
|
|
11
|
-
class TestCmdUtils <
|
11
|
+
class TestCmdUtils < Minitest::Test
|
12
12
|
|
13
13
|
#def gen_test name, norun, verbose, quiet, debug, output
|
14
14
|
def gen_test name, flags, output
|
@@ -29,9 +29,9 @@ class TestCmdUtils < MiniTest::Test
|
|
29
29
|
begin
|
30
30
|
out, err = capture_subprocess_io do
|
31
31
|
begin
|
32
|
-
yield
|
33
|
-
rescue
|
34
|
-
end
|
32
|
+
yield
|
33
|
+
rescue
|
34
|
+
end
|
35
35
|
end
|
36
36
|
rescue
|
37
37
|
end
|
@@ -8,18 +8,18 @@ require 'lookup'
|
|
8
8
|
|
9
9
|
class NilClass ; def to_s ; '' ; end ; end
|
10
10
|
|
11
|
-
class TestLookup <
|
11
|
+
class TestLookup < Minitest::Test
|
12
12
|
|
13
13
|
# do_lookup input-text, output-text, true-if-notfound, true-if-ambiguous
|
14
14
|
|
15
15
|
def do_lookup input, output, notfound=nil, ambig=nil
|
16
16
|
found = nil
|
17
17
|
if notfound
|
18
|
-
assert_raises(LookupNotFoundError) {
|
18
|
+
assert_raises(LookupNotFoundError) {
|
19
19
|
found = lookup(@keywords, input)
|
20
20
|
}
|
21
21
|
elsif ambig
|
22
|
-
assert_raises(LookupAmbigError) {
|
22
|
+
assert_raises(LookupAmbigError) {
|
23
23
|
found = lookup(@keywords, input)
|
24
24
|
}
|
25
25
|
else
|
@@ -46,10 +46,18 @@ class TestLookup < MiniTest::Test
|
|
46
46
|
@keywords = %w( email emails reason reasons )
|
47
47
|
do_lookup 'email', 'email'
|
48
48
|
do_lookup 'emails', 'emails'
|
49
|
-
do_lookup 'emai', '
|
50
|
-
do_lookup 'rea', '
|
49
|
+
do_lookup 'emai', '', nil, true # ambiguous
|
50
|
+
do_lookup 'rea', '', nil, true # ambiguous
|
51
51
|
do_lookup 'reason', 'reason'
|
52
52
|
do_lookup 'reasons', 'reasons'
|
53
53
|
end
|
54
54
|
|
55
|
+
def test_lookup_failures
|
56
|
+
@keywords = %w( set get show edit reset delete count )
|
57
|
+
do_lookup "s", nil, nil, true # ambigous
|
58
|
+
do_lookup "foo", nil, true # not found
|
59
|
+
do_lookup "showit", nil, true # not found
|
60
|
+
do_lookup "rest", nil, true # not found
|
61
|
+
end
|
62
|
+
|
55
63
|
end
|
metadata
CHANGED
@@ -1,28 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmd-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alan K. Stebbens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.3.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.3.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jeweler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Several ruby libraries for building command-line utilities.
|
14
84
|
email: aks@stebbens.org
|
15
85
|
executables: []
|
16
86
|
extensions: []
|
17
|
-
extra_rdoc_files:
|
87
|
+
extra_rdoc_files:
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.md
|
18
90
|
files:
|
91
|
+
- ".document"
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- VERSION
|
98
|
+
- cmd-utils.gemspec
|
19
99
|
- lib/cmd-utils.rb
|
20
100
|
- lib/lookup.rb
|
21
|
-
-
|
22
|
-
-
|
23
|
-
|
101
|
+
- lib/ssh-utils.rb
|
102
|
+
- test/helper.rb
|
103
|
+
- test/test-cmd-utils.rb
|
104
|
+
- test/test-lookup.rb
|
105
|
+
- test/test_cmd-utils.rb.off
|
106
|
+
homepage: http://bitbucket.org/aks_/cmd-utils
|
24
107
|
licenses:
|
25
|
-
-
|
108
|
+
- MIT
|
26
109
|
metadata: {}
|
27
110
|
post_install_message:
|
28
111
|
rdoc_options: []
|
@@ -30,20 +113,18 @@ require_paths:
|
|
30
113
|
- lib
|
31
114
|
required_ruby_version: !ruby/object:Gem::Requirement
|
32
115
|
requirements:
|
33
|
-
- -
|
116
|
+
- - ">="
|
34
117
|
- !ruby/object:Gem::Version
|
35
118
|
version: '0'
|
36
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
120
|
requirements:
|
38
|
-
- -
|
121
|
+
- - ">="
|
39
122
|
- !ruby/object:Gem::Version
|
40
123
|
version: '0'
|
41
124
|
requirements: []
|
42
125
|
rubyforge_project:
|
43
|
-
rubygems_version: 2.
|
126
|
+
rubygems_version: 2.2.2
|
44
127
|
signing_key:
|
45
128
|
specification_version: 4
|
46
|
-
summary: Utilities for
|
47
|
-
test_files:
|
48
|
-
- tests/test-cmd-utils.rb
|
49
|
-
- tests/test-lookup.rb
|
129
|
+
summary: Utilities for building CLIs
|
130
|
+
test_files: []
|