qb 0.3.13 → 0.3.14
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/doc/getting_started.md +2 -0
- data/doc/qb_roles.md +4 -109
- data/doc/qb_roles/metadata.md +221 -0
- data/exe/qb +23 -11
- data/lib/qb.rb +1 -3
- data/lib/qb/cli.rb +97 -85
- data/lib/qb/options.rb +6 -6
- data/lib/qb/role/default_dir.rb +28 -28
- data/lib/qb/util.rb +3 -2
- data/lib/qb/version.rb +1 -1
- data/qb.gemspec +22 -9
- data/roles/nrser.rbenv_gem/tasks/main.yml +3 -3
- data/roles/qb/gem/build/defaults/main.yml +12 -0
- data/roles/{qb.build_gem → qb/gem/build}/meta/main.yml +0 -0
- data/roles/qb/gem/build/meta/qb.yml +42 -0
- data/roles/qb/gem/build/tasks/main.yml +61 -0
- data/roles/{qb.install_gem → qb/gem/install}/defaults/main.yml +1 -1
- data/roles/qb/gem/install/meta/main.yml +17 -0
- data/roles/{qb.install_gem → qb/gem/install}/meta/qb.yml +5 -2
- data/roles/{qb.install_gem → qb/gem/install}/tasks/main.yml +0 -0
- data/roles/qb/git/ignore/files/gitignore/Eagle.gitignore +9 -1
- data/roles/qb/git/ignore/files/gitignore/Global/Eclipse.gitignore +3 -0
- data/roles/qb/git/ignore/files/gitignore/Go.gitignore +1 -0
- data/roles/qb/git/ignore/files/gitignore/Node.gitignore +2 -0
- data/roles/qb/git/ignore/files/gitignore/Python.gitignore +7 -19
- data/roles/qb/git/ignore/files/gitignore/Python/Packaging.gitignore +25 -0
- data/roles/qb/git/ignore/files/gitignore/Ruby.gitignore +15 -5
- data/roles/qb/git/ignore/files/gitignore/Umbraco.gitignore +2 -2
- data/roles/qb/git/ignore/files/gitignore/VisualStudio.gitignore +4 -0
- data/roles/qb/role/qb/templates/qb.yml.j2 +19 -39
- data/roles/qb/role/templates/README.md.j2 +1 -1
- data/roles/qb/role/templates/defaults/main.yml.j2 +6 -1
- data/roles/qb/role/templates/filter_plugins/filters.py.j2 +5 -5
- data/roles/qb/role/templates/handlers/main.yml.j2 +3 -1
- data/roles/qb/role/templates/meta/main.yml.j2 +4 -2
- data/roles/qb/role/templates/tasks/main.yml.j2 +3 -1
- data/roles/qb/role/templates/vars/main.yml.j2 +3 -1
- metadata +43 -34
- data/roles/qb.build_gem/defaults/main.yml +0 -2
- data/roles/qb.build_gem/tasks/main.yml +0 -27
- data/roles/qb.install_gem/meta/main.yml +0 -12
data/lib/qb/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Requirements
|
2
4
|
# =======================================================================
|
3
5
|
|
@@ -32,101 +34,111 @@ module QB::CLI
|
|
32
34
|
|
33
35
|
include SemanticLogger::Loggable
|
34
36
|
|
35
|
-
|
36
|
-
#
|
37
|
+
|
38
|
+
# Constants
|
39
|
+
# ============================================================================
|
40
|
+
|
41
|
+
# CLI args that common to all commands that enable debug output
|
37
42
|
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
if default
|
66
|
-
puts "DEFAULT #{ default.to_s }".indent
|
67
|
-
end
|
68
|
-
|
69
|
-
$stdout.write '> '
|
70
|
-
|
71
|
-
value = gets.chomp
|
72
|
-
|
73
|
-
QB.debug "User input", value
|
74
|
-
|
75
|
-
if value == '' && default != NRSER::NO_ARG
|
76
|
-
puts <<-END.dedent
|
77
|
-
|
78
|
-
Using default value #{ default.to_s }
|
79
|
-
|
80
|
-
END
|
81
|
-
|
82
|
-
return default
|
83
|
-
end
|
84
|
-
|
85
|
-
begin
|
86
|
-
type.from_s value
|
87
|
-
rescue TypeError => e
|
88
|
-
puts <<-END.dedent
|
89
|
-
Input value #{ value.inspect } failed to satisfy type
|
90
|
-
|
91
|
-
#{ type.to_s }
|
92
|
-
|
93
|
-
END
|
94
|
-
else
|
95
|
-
break value
|
96
|
-
end
|
97
|
-
|
98
|
-
end # loop
|
43
|
+
# @return [Array<String>]
|
44
|
+
#
|
45
|
+
DEBUG_ARGS = ['-D', '--DEBUG'].freeze
|
46
|
+
|
47
|
+
|
48
|
+
def self.set_debug! args
|
49
|
+
if DEBUG_ARGS.any? {|arg| args.include? arg}
|
50
|
+
QB::Util::Logging.setup level: :debug
|
51
|
+
DEBUG_ARGS.each {|arg| args.delete arg}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# @todo Document ask method.
|
57
|
+
#
|
58
|
+
# @param [type] arg_name
|
59
|
+
# @todo Add name param description.
|
60
|
+
#
|
61
|
+
# @return [return_type]
|
62
|
+
# @todo Document return value.
|
63
|
+
#
|
64
|
+
def self.ask name:,
|
65
|
+
description: nil,
|
66
|
+
type:,
|
67
|
+
default: NRSER::NO_ARG
|
68
|
+
puts
|
99
69
|
|
100
|
-
|
70
|
+
value = loop do
|
101
71
|
|
102
|
-
|
72
|
+
puts "Enter value for #{ name }"
|
103
73
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
74
|
+
if description
|
75
|
+
puts description.indent
|
76
|
+
end
|
77
|
+
|
78
|
+
puts "TYPE #{ type.to_s }".indent
|
79
|
+
|
80
|
+
if default
|
81
|
+
puts "DEFAULT #{ default.to_s }".indent
|
82
|
+
end
|
83
|
+
|
84
|
+
$stdout.write '> '
|
85
|
+
|
86
|
+
value = gets.chomp
|
87
|
+
|
88
|
+
QB.debug "User input", value
|
89
|
+
|
90
|
+
if value == '' && default != NRSER::NO_ARG
|
91
|
+
puts <<-END.dedent
|
92
|
+
|
93
|
+
Using default value #{ default.to_s }
|
94
|
+
|
95
|
+
END
|
96
|
+
|
97
|
+
return default
|
98
|
+
end
|
99
|
+
|
100
|
+
begin
|
101
|
+
type.from_s value
|
102
|
+
rescue TypeError => e
|
103
|
+
puts <<-END.dedent
|
104
|
+
Input value #{ value.inspect } failed to satisfy type
|
105
|
+
|
106
|
+
#{ type.to_s }
|
107
|
+
|
108
|
+
END
|
112
109
|
else
|
113
|
-
|
110
|
+
break value
|
114
111
|
end
|
115
112
|
|
116
|
-
|
117
|
-
description: option.description,
|
118
|
-
default: default
|
119
|
-
# type:
|
120
|
-
end
|
113
|
+
end # loop
|
121
114
|
|
115
|
+
puts "Using value #{ value.inspect }"
|
122
116
|
|
123
|
-
|
124
|
-
options.select { |opt| opt.value.nil? }.each { |option|
|
125
|
-
ask_for_option role: role, option: option
|
126
|
-
}
|
127
|
-
end # #ask_for_options
|
117
|
+
return value
|
128
118
|
|
119
|
+
end # .ask
|
120
|
+
|
121
|
+
|
122
|
+
def self.ask_for_option role:, option:
|
123
|
+
default = if role.defaults.key?(option.var_name)
|
124
|
+
role.defaults[option.var_name]
|
125
|
+
elsif option.required?
|
126
|
+
NRSER::NO_ARG
|
127
|
+
else
|
128
|
+
nil
|
129
|
+
end
|
129
130
|
|
130
|
-
|
131
|
+
ask name: option.name,
|
132
|
+
description: option.description,
|
133
|
+
default: default
|
134
|
+
# type:
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def self.ask_for_options role:, options:
|
139
|
+
options.select { |opt| opt.value.nil? }.each { |option|
|
140
|
+
ask_for_option role: role, option: option
|
141
|
+
}
|
142
|
+
end # .ask_for_options
|
131
143
|
|
132
144
|
end # module QB::CLI
|
data/lib/qb/options.rb
CHANGED
@@ -20,13 +20,13 @@ module QB
|
|
20
20
|
# =======================================================================
|
21
21
|
|
22
22
|
QB_DEFAULTS = {
|
23
|
-
'hosts' => ['localhost'],
|
23
|
+
'hosts' => ['localhost'].freeze,
|
24
24
|
'facts' => true,
|
25
|
-
'print' => [
|
25
|
+
'print' => [].freeze,
|
26
26
|
'verbose' => false,
|
27
27
|
'run' => true,
|
28
28
|
'ask' => false,
|
29
|
-
}
|
29
|
+
}.freeze
|
30
30
|
|
31
31
|
# appended on the end of an `opts.on` call to create a newline after
|
32
32
|
# the option (making the help output a bit easier to read)
|
@@ -210,7 +210,7 @@ module QB
|
|
210
210
|
end
|
211
211
|
}
|
212
212
|
}
|
213
|
-
else
|
213
|
+
else
|
214
214
|
raise QB::Role::MetadataError,
|
215
215
|
"bad type for option #{ option.meta_name }: #{ option.meta['type'].inspect }"
|
216
216
|
end
|
@@ -284,7 +284,7 @@ module QB
|
|
284
284
|
options[option.cli_name] = option
|
285
285
|
end
|
286
286
|
end # each var
|
287
|
-
end # add
|
287
|
+
end # add
|
288
288
|
|
289
289
|
# destructively removes options from `@argv` and populates ansible, role,
|
290
290
|
# and qb option hashes.
|
@@ -531,4 +531,4 @@ module QB
|
|
531
531
|
# end protected
|
532
532
|
|
533
533
|
end # Options
|
534
|
-
end # QB
|
534
|
+
end # QB
|
data/lib/qb/role/default_dir.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
##
|
2
|
-
# {QB::Role} methods for finding the default directory for
|
2
|
+
# {QB::Role} methods for finding the default directory for
|
3
3
|
# running a role when one is not provided in the CLI.
|
4
4
|
#
|
5
|
-
# Broken out from the main `//lib/qb/role.rb` file because it was starting to
|
5
|
+
# Broken out from the main `//lib/qb/role.rb` file because it was starting to
|
6
6
|
# get long and unwieldy.
|
7
7
|
#
|
8
8
|
##
|
@@ -17,6 +17,7 @@ require 'pathname'
|
|
17
17
|
|
18
18
|
# Deps
|
19
19
|
# -----------------------------------------------------------------------
|
20
|
+
require 'nrser'
|
20
21
|
|
21
22
|
# Project / Package
|
22
23
|
# -----------------------------------------------------------------------
|
@@ -25,7 +26,6 @@ require 'pathname'
|
|
25
26
|
# Refinements
|
26
27
|
# =======================================================================
|
27
28
|
|
28
|
-
require 'nrser/refinements'
|
29
29
|
using NRSER
|
30
30
|
|
31
31
|
|
@@ -46,11 +46,11 @@ class QB::Role
|
|
46
46
|
# Gets the default `qb_dir` value, raising an error if the role doesn't
|
47
47
|
# define how to get one or there is a problem getting it.
|
48
48
|
#
|
49
|
-
# It uses a "strategy" value found at the 'default_dir' key in the role's
|
50
|
-
# QB metadata (in `<role_path>/meta/qb.yml` or returned by a
|
49
|
+
# It uses a "strategy" value found at the 'default_dir' key in the role's
|
50
|
+
# QB metadata (in `<role_path>/meta/qb.yml` or returned by a
|
51
51
|
# `<role_path>/meta/qb` executable).
|
52
52
|
#
|
53
|
-
# See the {file:doc/qb_roles/metadata/default_dir.md default_dir}
|
53
|
+
# See the {file:doc/qb_roles/metadata/default_dir.md default_dir}
|
54
54
|
# documentation for details on the accepted strategy values.
|
55
55
|
#
|
56
56
|
# @param [String | Pathname] cwd:
|
@@ -65,7 +65,7 @@ class QB::Role
|
|
65
65
|
# The directory to target.
|
66
66
|
#
|
67
67
|
# @raise
|
68
|
-
# When we can't determine a directory due to role meta settings or target
|
68
|
+
# When we can't determine a directory due to role meta settings or target
|
69
69
|
# system state.
|
70
70
|
#
|
71
71
|
def default_dir cwd, options
|
@@ -77,7 +77,7 @@ class QB::Role
|
|
77
77
|
options: options
|
78
78
|
|
79
79
|
default_dir_for(
|
80
|
-
|
80
|
+
strategy: self.meta['default_dir'],
|
81
81
|
cwd: cwd,
|
82
82
|
options: options
|
83
83
|
).to_pn
|
@@ -102,8 +102,8 @@ class QB::Role
|
|
102
102
|
# @return [return_type]
|
103
103
|
# @todo Document return value.
|
104
104
|
#
|
105
|
-
def default_dir_for
|
106
|
-
case
|
105
|
+
def default_dir_for strategy:, cwd:, options:
|
106
|
+
case strategy
|
107
107
|
when nil
|
108
108
|
# there is no get_dir info in meta/qb.yml, can't get the dir
|
109
109
|
raise QB::UserInputError.new binding.erb <<-END
|
@@ -116,7 +116,7 @@ class QB::Role
|
|
116
116
|
|
117
117
|
qb run <%= self.name %> DIRECTORY
|
118
118
|
|
119
|
-
or, if you are the developer of the <%= self.name %> role, set a
|
119
|
+
or, if you are the developer of the <%= self.name %> role, set a
|
120
120
|
non-null value for the 'default_dir' key in
|
121
121
|
|
122
122
|
<%= self.meta_path %>
|
@@ -124,8 +124,8 @@ class QB::Role
|
|
124
124
|
END
|
125
125
|
|
126
126
|
when false
|
127
|
-
# this method should not get called when the
|
128
|
-
# section is skipped in exe/qb when `default_dir = false`)
|
127
|
+
# this method should not get called when the strategy is `false` (an
|
128
|
+
# entire section is skipped in exe/qb when `default_dir = false`)
|
129
129
|
raise QB::StateError.squished <<-END
|
130
130
|
role does not use default directory (meta/qb.yml:default_dir = false)
|
131
131
|
END
|
@@ -141,11 +141,11 @@ class QB::Role
|
|
141
141
|
when Hash
|
142
142
|
logger.debug "qb meta option is a Hash"
|
143
143
|
|
144
|
-
unless
|
145
|
-
raise "#{ meta_path.to_s }:default_dir invalid: #{
|
144
|
+
unless strategy.length == 1
|
145
|
+
raise "#{ meta_path.to_s }:default_dir invalid: #{ strategy.inspect }"
|
146
146
|
end
|
147
147
|
|
148
|
-
hash_key, hash_value =
|
148
|
+
hash_key, hash_value = strategy.first
|
149
149
|
|
150
150
|
case hash_key
|
151
151
|
when 'exe'
|
@@ -172,21 +172,21 @@ class QB::Role
|
|
172
172
|
end
|
173
173
|
|
174
174
|
when 'find_up'
|
175
|
-
|
175
|
+
rel_path = hash_value
|
176
176
|
|
177
|
-
unless
|
178
|
-
raise "find_up
|
177
|
+
unless rel_path.is_a? String
|
178
|
+
raise "find_up relative path or glob must be string, found #{ rel_path.inspect }"
|
179
179
|
end
|
180
180
|
|
181
|
-
|
181
|
+
logger.debug "found 'find_up' strategy", rel_path: rel_path
|
182
182
|
|
183
|
-
|
183
|
+
cwd.to_pn.find_up! rel_path
|
184
184
|
|
185
185
|
when 'from_role'
|
186
186
|
# Get the value from another role, presumably one this role includes
|
187
187
|
|
188
188
|
default_dir_for \
|
189
|
-
|
189
|
+
strategy: QB::Role.require( hash_value ).meta['default_dir'],
|
190
190
|
cwd: cwd,
|
191
191
|
options: options
|
192
192
|
|
@@ -200,9 +200,9 @@ class QB::Role
|
|
200
200
|
|
201
201
|
contains an invalid default directory strategy
|
202
202
|
|
203
|
-
<%=
|
203
|
+
<%= strategy.pretty_inspect %>
|
204
204
|
|
205
|
-
The key <%= hash_key.inspect %> does not correspond to a recognized
|
205
|
+
The key <%= hash_key.inspect %> does not correspond to a recognized
|
206
206
|
form.
|
207
207
|
|
208
208
|
Valid forms are:
|
@@ -215,15 +215,15 @@ class QB::Role
|
|
215
215
|
end
|
216
216
|
|
217
217
|
when Array
|
218
|
-
|
219
|
-
default_dir_for
|
218
|
+
strategy.try_find do |candidate|
|
219
|
+
default_dir_for strategy: candidate, cwd: cwd, options: options
|
220
220
|
end
|
221
221
|
|
222
222
|
else
|
223
223
|
raise QB::Role::MetadataError.new binding.erb <<-END
|
224
|
-
bad default_dir
|
224
|
+
bad default_dir strategy: <%= strategy %>
|
225
225
|
END
|
226
|
-
end # case
|
226
|
+
end # case strategy
|
227
227
|
end # .default_dir_for
|
228
228
|
|
229
229
|
# end protected
|
data/lib/qb/util.rb
CHANGED
@@ -13,7 +13,7 @@ module QB
|
|
13
13
|
string.split(/[\W_\-\/]+/).reject {|w| w.empty?}
|
14
14
|
end # .words
|
15
15
|
|
16
|
-
# see if words from an input match words
|
16
|
+
# see if words from an input match words
|
17
17
|
def self.words_start_with? full_string, input
|
18
18
|
# QB.debug "does #{ input } match #{ full_string }?"
|
19
19
|
|
@@ -84,6 +84,7 @@ module QB
|
|
84
84
|
Pathname.new contracted
|
85
85
|
end
|
86
86
|
|
87
|
+
|
87
88
|
# find `filename` in `from` or closest parent directory.
|
88
89
|
#
|
89
90
|
# @param [String] filename
|
@@ -96,7 +97,7 @@ module QB
|
|
96
97
|
# When `true`, a {QB::FSStateError} will be raised if no file is found
|
97
98
|
# (default behavior).
|
98
99
|
#
|
99
|
-
# This is something of a legacy behavior - I think it would be better
|
100
|
+
# This is something of a legacy behavior - I think it would be better
|
100
101
|
# to have {find_up} return `nil` in that case and add a `find_up!`
|
101
102
|
# method that raises on not found. But I'm not going to do it right now.
|
102
103
|
#
|
data/lib/qb/version.rb
CHANGED
data/qb.gemspec
CHANGED
@@ -105,6 +105,8 @@ Gem::Specification.new do |spec|
|
|
105
105
|
spec.homepage = "https://github.com/nrser/qb"
|
106
106
|
spec.license = "MIT"
|
107
107
|
|
108
|
+
spec.required_ruby_version = '>= 2.3.0'
|
109
|
+
|
108
110
|
|
109
111
|
# Files
|
110
112
|
# ============================================================================
|
@@ -160,6 +162,7 @@ Gem::Specification.new do |spec|
|
|
160
162
|
spec.executables = spec.files.grep %r{^#{ spec.bindir }/[^\.]},
|
161
163
|
&File.method( :basename )
|
162
164
|
|
165
|
+
# Where that source be, standard `//lib` directory
|
163
166
|
spec.require_paths = ["lib"]
|
164
167
|
|
165
168
|
|
@@ -169,20 +172,30 @@ Gem::Specification.new do |spec|
|
|
169
172
|
# Development Dependencies
|
170
173
|
# ----------------------------------------------------------------------------
|
171
174
|
|
172
|
-
spec.add_development_dependency "bundler",
|
173
|
-
spec.add_development_dependency "rake",
|
174
|
-
|
175
|
-
|
176
|
-
spec.add_development_dependency "
|
177
|
-
|
178
|
-
|
175
|
+
spec.add_development_dependency "bundler", '~> 1.16', '>= 1.16.1'
|
176
|
+
spec.add_development_dependency "rake", '~> 12.3'
|
177
|
+
|
178
|
+
# Testing with `rspec`
|
179
|
+
spec.add_development_dependency "rspec", '~> 3.7'
|
180
|
+
|
181
|
+
# Doc site generation with `yard`
|
182
|
+
spec.add_development_dependency "yard", '~> 0.9.12'
|
183
|
+
|
184
|
+
# These, along with `//.yardopts` config, are *supposed to* result in
|
185
|
+
# rendering markdown files and doc comments using
|
186
|
+
# GitHub-Flavored Markdown (GFM), though I'm not sure if it's totally working
|
187
|
+
spec.add_development_dependency "redcarpet", '~> 3.4'
|
188
|
+
spec.add_development_dependency "github-markup", '~> 1.6'
|
189
|
+
|
190
|
+
# Nicer REPL experience
|
191
|
+
spec.add_development_dependency "pry", '~> 0.10.4'
|
179
192
|
|
180
193
|
|
181
194
|
# Runtime Dependencies
|
182
195
|
# ----------------------------------------------------------------------------
|
183
196
|
|
184
197
|
spec.add_dependency "cmds", '~> 0.0', ">= 0.2.4"
|
185
|
-
spec.add_dependency "nrser", '~> 0.
|
198
|
+
spec.add_dependency "nrser", '~> 0.1', ">= 0.1.0"
|
186
199
|
spec.add_dependency "nrser-extras", '~> 0.0', ">= 0.0.3"
|
187
200
|
spec.add_dependency "state_mate", '~> 0.0', ">= 0.1.0"
|
188
201
|
|
@@ -199,7 +212,7 @@ Gem::Specification.new do |spec|
|
|
199
212
|
spec.add_dependency 'awesome_print', '~> 1.8'
|
200
213
|
|
201
214
|
# Ruby lib wrapping `git` binary system calls for use in {QB::Repo::Git}
|
202
|
-
spec.add_dependency 'git',
|
215
|
+
spec.add_dependency 'git', '~> 1.3'
|
203
216
|
|
204
217
|
|
205
218
|
# Development-Only Extra Metadata
|