pmgmt 1.0.0 → 1.1.0
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 +5 -5
- data/lib/optionsparser.rb +69 -0
- data/lib/pmgmt.rb +68 -13
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 3e6afb20a3759c4c7975553ffb186bb641cb7b05
|
|
4
|
+
data.tar.gz: f0200e100d4de9902e24286d6cc4f78a05cf0270
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 768f313e048275c7c79aab4e88a4e963999ca657cacfde98241f5ee13e8795e3c022cc28a9971e554e6ce014d7cbbaddb96fedae76eab89c355f8a0ce2f1f115
|
|
7
|
+
data.tar.gz: 257c6e1a90cb9b67e8d89f0fcb8ca23ea53d1c53609eb41cfcdf41b0fcd9d2b73ede6f315431fb5ff39a35d98fb27d43977bdaee3ef285db9d3109b7f80133e4
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require "optparse"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
# Creates a default command-line argument parser.
|
|
5
|
+
# command_name: For help text.
|
|
6
|
+
def create_parser(command_name)
|
|
7
|
+
OptionParser.new do |parser|
|
|
8
|
+
parser.banner = "Usage: #{$PROGRAM_NAME} #{command_name} [options]"
|
|
9
|
+
parser
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module PmgmtLib
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Allows parsing of command line options without requiring any subclassing.
|
|
17
|
+
|
|
18
|
+
class OptionsParser
|
|
19
|
+
attr_reader :opts, :remaining
|
|
20
|
+
|
|
21
|
+
def initialize(command_name, args)
|
|
22
|
+
@opts = OpenStruct.new
|
|
23
|
+
@parser = create_parser(command_name)
|
|
24
|
+
@args = args
|
|
25
|
+
@validators = []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def add_option(option, assign, help)
|
|
29
|
+
@parser.on(option, help) {|v| assign.call(@opts, v)}
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_typed_option(option, type, assign, help)
|
|
34
|
+
@parser.on(option, type, help) {|v| assign.call(@opts, v)}
|
|
35
|
+
self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_validator(fn)
|
|
39
|
+
@validators.push(fn)
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def parse()
|
|
44
|
+
begin
|
|
45
|
+
@remaining = @parser.parse @args
|
|
46
|
+
rescue ArgumentError => e
|
|
47
|
+
STDERR.puts e
|
|
48
|
+
STDERR.puts
|
|
49
|
+
STDERR.puts @parser.help
|
|
50
|
+
exit 1
|
|
51
|
+
end
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def validate()
|
|
56
|
+
@validators.each do |fn|
|
|
57
|
+
begin
|
|
58
|
+
fn.call(@opts)
|
|
59
|
+
rescue ArgumentError => e
|
|
60
|
+
STDERR.puts e
|
|
61
|
+
STDERR.puts
|
|
62
|
+
STDERR.puts @parser.help
|
|
63
|
+
exit 1
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/pmgmt.rb
CHANGED
|
@@ -3,11 +3,23 @@ require "ostruct"
|
|
|
3
3
|
require "yaml"
|
|
4
4
|
|
|
5
5
|
require_relative "dockerhelper"
|
|
6
|
+
require_relative "optionsparser"
|
|
6
7
|
require_relative "syncfiles"
|
|
7
8
|
|
|
8
9
|
class Pmgmt
|
|
10
|
+
# State to hold registered commands. See {#Pmgmt.register_command}.
|
|
9
11
|
@@commands = []
|
|
12
|
+
# Convenience method to provide access to the options parsing utility class.
|
|
13
|
+
@@options_parser = PmgmtLib::OptionsParser
|
|
10
14
|
|
|
15
|
+
def self.OptionsParser
|
|
16
|
+
@@options_parser
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Loads all `.rb` scripts from the given directory. Scripts are expected to register commands as
|
|
20
|
+
# a side-effect of loading.
|
|
21
|
+
# @param scripts_dir [String]
|
|
22
|
+
# @return [void]
|
|
11
23
|
def self.load_scripts(scripts_dir)
|
|
12
24
|
if !File.directory?(scripts_dir)
|
|
13
25
|
self.new.error "Cannot load scripts. Not a directory: #{scripts_dir}"
|
|
@@ -20,9 +32,22 @@ class Pmgmt
|
|
|
20
32
|
end
|
|
21
33
|
end
|
|
22
34
|
|
|
35
|
+
# Registers a command. Registered commands can be invoked by name, appear in command lists and
|
|
36
|
+
# allow --help docs.
|
|
37
|
+
# @param command [Map] The :invocation key is what would be typed to invoke the command and the :fn key is what function to execute when invoked. Specify only a :fn key for shorthand.
|
|
38
|
+
# @return [void]
|
|
23
39
|
def self.register_command(command)
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
if command.nil?
|
|
41
|
+
self.new.error "register_command called with nil argument"
|
|
42
|
+
exit 1
|
|
43
|
+
end
|
|
44
|
+
if command.is_a?(Symbol)
|
|
45
|
+
invocation = command.to_s
|
|
46
|
+
fn = command
|
|
47
|
+
else
|
|
48
|
+
invocation = command[:invocation]
|
|
49
|
+
fn = command[:fn]
|
|
50
|
+
end
|
|
26
51
|
if fn.nil?
|
|
27
52
|
self.new.error "No :fn key defined for command #{invocation}"
|
|
28
53
|
exit 1
|
|
@@ -40,13 +65,16 @@ class Pmgmt
|
|
|
40
65
|
end
|
|
41
66
|
end
|
|
42
67
|
|
|
43
|
-
@@commands.push(
|
|
68
|
+
@@commands.push({:invocation => invocation, :fn => fn})
|
|
44
69
|
end
|
|
45
70
|
|
|
71
|
+
# @return [Array] the commands array for inspection.
|
|
46
72
|
def self.commands()
|
|
47
73
|
@@commands
|
|
48
74
|
end
|
|
49
75
|
|
|
76
|
+
# Handles command execution.
|
|
77
|
+
# @param args [Array] Pass ARGV.
|
|
50
78
|
def self.handle_or_die(args)
|
|
51
79
|
if args.length == 0 or args[0] == "--help"
|
|
52
80
|
self.new.print_usage
|
|
@@ -65,19 +93,27 @@ class Pmgmt
|
|
|
65
93
|
command = args.first
|
|
66
94
|
handler = @@commands.select{ |x| x[:invocation] == command }.first
|
|
67
95
|
if handler.nil?
|
|
68
|
-
error "#{command} command not found."
|
|
96
|
+
self.new.error "#{command} command not found."
|
|
69
97
|
exit 1
|
|
70
98
|
end
|
|
71
99
|
|
|
72
100
|
fn = handler[:fn]
|
|
101
|
+
args = args
|
|
73
102
|
if fn.is_a?(Symbol)
|
|
74
|
-
method(fn)
|
|
103
|
+
fn = method(fn)
|
|
104
|
+
else
|
|
105
|
+
args = args.drop(1)
|
|
106
|
+
end
|
|
107
|
+
if fn.arity == 0
|
|
108
|
+
fn.call()
|
|
75
109
|
else
|
|
76
|
-
|
|
110
|
+
fn.call(*args)
|
|
77
111
|
end
|
|
78
112
|
end
|
|
79
113
|
|
|
114
|
+
# Convenience method to easily retrieve Docker utilities. See {#PmgmtLib::DockerHelper}.
|
|
80
115
|
attr :docker
|
|
116
|
+
# Convenience method to easily retrieve file-syncing utilities. See {#PmgmtLib::SyncFiles}.
|
|
81
117
|
attr :sf
|
|
82
118
|
|
|
83
119
|
def initialize()
|
|
@@ -123,19 +159,25 @@ class Pmgmt
|
|
|
123
159
|
"\033[1m#{text}\033[0m"
|
|
124
160
|
end
|
|
125
161
|
|
|
162
|
+
# Prints "status" text (blue) on STDERR.
|
|
163
|
+
# @return [void]
|
|
126
164
|
def status(text)
|
|
127
165
|
STDERR.puts blue_term_text(text)
|
|
128
166
|
end
|
|
129
167
|
|
|
168
|
+
# Prints "warning" text (yellow) on STDERR.
|
|
169
|
+
# @return [void]
|
|
130
170
|
def warning(text)
|
|
131
171
|
STDERR.puts yellow_term_text(text)
|
|
132
172
|
end
|
|
133
173
|
|
|
174
|
+
# Prints "error" text (red) on STDERR.
|
|
175
|
+
# @return [void]
|
|
134
176
|
def error(text)
|
|
135
177
|
STDERR.puts red_term_text(text)
|
|
136
178
|
end
|
|
137
179
|
|
|
138
|
-
def put_command(cmd, redact
|
|
180
|
+
def put_command(cmd, redact: nil)
|
|
139
181
|
if cmd.is_a?(String)
|
|
140
182
|
command_string = "+ #{cmd}"
|
|
141
183
|
else
|
|
@@ -148,8 +190,11 @@ class Pmgmt
|
|
|
148
190
|
STDERR.puts command_to_echo
|
|
149
191
|
end
|
|
150
192
|
|
|
151
|
-
#
|
|
152
|
-
|
|
193
|
+
# Runs the given command and captures its stdout.
|
|
194
|
+
# @param cmd [Array] Command to run.
|
|
195
|
+
# @param err: Pass nil to suppress stderr output.
|
|
196
|
+
# @return [String] Captured stdout.
|
|
197
|
+
def capture_stdout(cmd, err: STDERR)
|
|
153
198
|
if err.nil?
|
|
154
199
|
err = "/dev/null"
|
|
155
200
|
end
|
|
@@ -157,8 +202,12 @@ class Pmgmt
|
|
|
157
202
|
output
|
|
158
203
|
end
|
|
159
204
|
|
|
160
|
-
|
|
161
|
-
|
|
205
|
+
# Runs the given command "inline," meaning that it will take over the terminal while running.
|
|
206
|
+
# @param cmd [Array] Command to run.
|
|
207
|
+
# @param redact: [String] Occurrances of this string will be hidden from normal output.
|
|
208
|
+
# @return [void]
|
|
209
|
+
def run_inline(cmd, redact: nil)
|
|
210
|
+
put_command(cmd, redact: redact)
|
|
162
211
|
|
|
163
212
|
# `system`, by design (?!), hides stderr when the command fails.
|
|
164
213
|
if ENV["PROJECTRB_USE_SYSTEM"] == "true"
|
|
@@ -179,6 +228,7 @@ class Pmgmt
|
|
|
179
228
|
end
|
|
180
229
|
end
|
|
181
230
|
|
|
231
|
+
# Similar to {#run_inline} but will prevent exiting when an interrupt is encountered.
|
|
182
232
|
def run_inline_swallowing_interrupt(cmd)
|
|
183
233
|
begin
|
|
184
234
|
run_inline cmd
|
|
@@ -186,8 +236,9 @@ class Pmgmt
|
|
|
186
236
|
end
|
|
187
237
|
end
|
|
188
238
|
|
|
189
|
-
|
|
190
|
-
|
|
239
|
+
# Runs a command and fails on non-success exit code.
|
|
240
|
+
def run_or_fail(cmd, redact: nil)
|
|
241
|
+
put_command(cmd, redact: redact)
|
|
191
242
|
Open3.popen3(*cmd) do |i, o, e, t|
|
|
192
243
|
i.close
|
|
193
244
|
if not t.value.success?
|
|
@@ -197,6 +248,8 @@ class Pmgmt
|
|
|
197
248
|
end
|
|
198
249
|
end
|
|
199
250
|
|
|
251
|
+
# Runs a command without echoing.
|
|
252
|
+
# @return [Status] command's exit status.
|
|
200
253
|
def run(cmd)
|
|
201
254
|
Open3.popen3(*cmd) do |i, o, e, t|
|
|
202
255
|
i.close
|
|
@@ -204,6 +257,8 @@ class Pmgmt
|
|
|
204
257
|
end
|
|
205
258
|
end
|
|
206
259
|
|
|
260
|
+
# Accepts multiple arrays of commands and pipes each one to the next, failing if any command
|
|
261
|
+
# exits with an error.
|
|
207
262
|
def pipe(*cmds)
|
|
208
263
|
s = cmds.map { |x| x.join(" ") }
|
|
209
264
|
s = s.join(" | ")
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pmgmt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Mohs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-12-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A library to make Ruby your preferred scripting language for dev scripts.
|
|
14
14
|
email: davidmohs@gmail.com
|
|
@@ -17,12 +17,14 @@ extensions: []
|
|
|
17
17
|
extra_rdoc_files: []
|
|
18
18
|
files:
|
|
19
19
|
- lib/dockerhelper.rb
|
|
20
|
+
- lib/optionsparser.rb
|
|
20
21
|
- lib/pmgmt.rb
|
|
21
22
|
- lib/syncfiles.rb
|
|
22
|
-
homepage:
|
|
23
|
+
homepage: https://github.com/dmohs/project-management
|
|
23
24
|
licenses:
|
|
24
25
|
- MIT
|
|
25
|
-
metadata:
|
|
26
|
+
metadata:
|
|
27
|
+
source_code_uri: https://github.com/dmohs/project-management
|
|
26
28
|
post_install_message:
|
|
27
29
|
rdoc_options: []
|
|
28
30
|
require_paths:
|
|
@@ -31,7 +33,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
31
33
|
requirements:
|
|
32
34
|
- - ">="
|
|
33
35
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: '
|
|
36
|
+
version: '2'
|
|
35
37
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
38
|
requirements:
|
|
37
39
|
- - ">="
|
|
@@ -39,7 +41,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
39
41
|
version: '0'
|
|
40
42
|
requirements: []
|
|
41
43
|
rubyforge_project:
|
|
42
|
-
rubygems_version: 2.
|
|
44
|
+
rubygems_version: 2.5.2.3
|
|
43
45
|
signing_key:
|
|
44
46
|
specification_version: 4
|
|
45
47
|
summary: Project management scripting library.
|