cmd-utils 1.0.12 → 1.1.2
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/.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: []
|