qb 0.3.23 → 0.3.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b3a5dfc104a28f159f72ffcfedf5932e2912448
4
- data.tar.gz: b68ee826b4d98678abc8adffbe5e54395f0109f3
3
+ metadata.gz: aca30bc6181a0452746aeb8fa262a1fe8e5b0537
4
+ data.tar.gz: 6a94b47657b966b02c9b0de3dbb6acbfe4a33c65
5
5
  SHA512:
6
- metadata.gz: bcf7a62d2b0d4d0089c46e768e0660137a040593ec58b96a1bce6849be7e2d0680595d6f349cfc985efbc6d862dcf5ab11379851e83c7c0dad45836c95d5bd80
7
- data.tar.gz: '0797e7ae29fb71602935b9959cf3df432ab0ed7f5098734e3dbf29c38f691a217015f9b0e49c1f69e6bd09366a73aafc515d33e809c3f1df1c1b6d1cb2ea6649'
6
+ metadata.gz: 80c25333f1c2c26f865bf7ef6879b5dfbd10f203ca1f4df1f37c08a8f5fb26627581e4bb408e94d1e1b99f5b7168f5f73e53cfbba8295fae1b6be9ed6da167f3
7
+ data.tar.gz: ff848dc6e1f90c134d518f810f30dab66526c811890692fdc84941c88a3248cae042c6fdfe582732fa26318021c32d3e112d94bf4f411eafc0030052133ebe0b
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  QB
2
2
  ==============================================================================
3
3
 
4
+ [![Gem Version](http://img.shields.io/gem/v/qb.svg)][gem]
5
+ [![Build Status](http://img.shields.io/travis/nrser/qb.svg)][travis]
6
+
7
+ [gem]: https://rubygems.org/gems/qb
8
+ [travis]: http://travis-ci.org/nrser/qb
9
+
4
10
  QB is all about projects. Named after everyone's favorite projects.
5
11
 
6
12
  QB works by running [Ansible][] plays. So you can think about it as "quarterback" if you happen to be from the corner of the world where that makes any sense.
@@ -30,14 +36,16 @@ and opening
30
36
  Quickies
31
37
  ------------------------------------------------------------------------------
32
38
 
33
- 1. Status: **UNSTABLE**
39
+ 1. Status: **UNSTABLE (BUT GETTING BETTER)**
34
40
 
35
41
  A bit past experimental, but still actively exploring API and features. Any and every thing subject to breaking changes until we hit `1.0`. Generally trying to bump the minor version with larger changes, but not paying a huge amount of attention to it. Being used personally and in projects and organizations I work with.
36
42
 
37
- 2. Compatibility: **OSX/macOS-only**
43
+ 2. Compatibility: **Unix-based, specifically OSX**
44
+
45
+ Developed and used on OSX/macOS, though [Travis tests][travis] tests pass on Linux as well (currently Ubuntu Trusty 14.04, see [Travis Build Env][]).
46
+
47
+ I don't know of any fundamental reason it wouldn't work on other \*nixes, but you will probably have to figure it out yourself.
38
48
 
39
- Though it would probably run fine on Linux, if not other \*nix as well.
40
-
41
49
  3. Installation
42
50
 
43
51
  Head over to {file:doc/getting_started.md Getting Started}.
@@ -49,6 +57,8 @@ Quickies
49
57
 
50
58
  <!-- References & Further Reading: -->
51
59
 
60
+ [Travis Build Env]: https://docs.travis-ci.com/user/reference/overview/#Container-based
61
+
52
62
  [Homebrew]: https://brew.sh/
53
63
 
54
64
  [Ansible Installation]: http://docs.ansible.com/ansible/latest/intro_installation.html
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.23
1
+ 0.3.24
data/exe/qb CHANGED
@@ -35,11 +35,13 @@ using NRSER
35
35
  # Definitions
36
36
  # =======================================================================
37
37
 
38
- def main args
38
+ def main *args
39
39
  Thread.current.name = 'main'
40
40
  logger = SemanticLogger['qb/exe/qb#main']
41
41
 
42
42
  QB::CLI.set_debug! args
43
+ QB::Util::Logging.setup sync: true, dest: $stderr
44
+
43
45
  logger.debug args: args
44
46
 
45
47
  QB.check_ansible_version
@@ -79,4 +81,4 @@ end
79
81
  # Execution
80
82
  # ============================================================================
81
83
 
82
- main(ARGV) # if __FILE__ == $0 # doesn't work with gem stub or something?
84
+ main( *ARGV ) # if __FILE__ == $0 # doesn't work with gem stub or something?
data/lib/qb.rb CHANGED
@@ -11,6 +11,7 @@ require 'nrser'
11
11
  # Project / Package
12
12
  # -----------------------------------------------------------------------
13
13
  require 'qb/errors'
14
+ require 'qb/python'
14
15
  require 'qb/version'
15
16
  require 'qb/util'
16
17
  require 'qb/path'
@@ -206,6 +206,16 @@ class QB::Ansible::Cmds::Playbook < ::Cmds
206
206
  end # #before_write
207
207
 
208
208
 
209
+ # HACK To fix test fails on linux... seems you can't end a command there
210
+ # with a `\`
211
+ #
212
+ # @todo Move up to Cmds
213
+ #
214
+ def prepare *args, &block
215
+ prepared = super *args, &block
216
+ prepared.gsub /[\s\n\\]+\z/, ''
217
+ end
218
+
209
219
  protected
210
220
  # ========================================================================
211
221
 
@@ -63,7 +63,7 @@ module QB::CLI
63
63
 
64
64
  def self.set_debug! args
65
65
  if DEBUG_ARGS.any? {|arg| args.include? arg}
66
- QB::Util::Logging.setup level: :debug
66
+ ENV['QB_DEBUG'] = 'true'
67
67
  DEBUG_ARGS.each {|arg| args.delete arg}
68
68
  end
69
69
  end
@@ -220,7 +220,7 @@ module QB::CLI
220
220
 
221
221
  env = QB::Ansible::Env::Devel.new
222
222
  exe = [
223
- "python2",
223
+ QB::Python.bin,
224
224
  (QB::Ansible::Env::Devel::ANSIBLE_HOME / 'bin' / 'ansible-playbook')
225
225
  ].join " "
226
226
 
@@ -304,6 +304,10 @@ module QB::CLI
304
304
  end
305
305
  end
306
306
 
307
+ logger.debug "Command prepared, running...",
308
+ command: cmd,
309
+ prepared: cmd.prepare
310
+
307
311
  status = cmd.stream
308
312
 
309
313
  if status != 0
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ # Definitions
6
+ # =======================================================================
7
+
8
+ module QB::Python
9
+
10
+ # Switch python bin depending on local dev / Travis CI env
11
+ #
12
+ # @todo
13
+ # Probably want more robust way of finding the Python we want and figuring
14
+ # out we're in Travis.
15
+ #
16
+ # @return [String]
17
+ #
18
+ def self.bin
19
+ # if File.exists? '/home/travis'
20
+ # 'python'
21
+ # else
22
+ # 'python2'
23
+ # end
24
+ 'python'
25
+ end
26
+
27
+ end # module QB::Python
@@ -3,6 +3,7 @@
3
3
 
4
4
  # Stdlib
5
5
  # -----------------------------------------------------------------------
6
+ require 'forwardable'
6
7
 
7
8
  # Deps
8
9
  # -----------------------------------------------------------------------
@@ -16,11 +17,13 @@ require 'semantic_logger'
16
17
  # Refinements
17
18
  # =======================================================================
18
19
 
20
+ using NRSER
21
+ using NRSER::Types
22
+
19
23
 
20
24
  # Declarations
21
25
  # =======================================================================
22
26
 
23
- module QB; end
24
27
  module QB::Util; end
25
28
 
26
29
 
@@ -64,6 +67,7 @@ module QB::Util::Logging
64
67
  super ap: { multiline: true },
65
68
  color_map: SemanticLogger::Formatters::Color::ColorMap.new(
66
69
  debug: SemanticLogger::AnsiColors::MAGENTA,
70
+ trace: "\e[1;30m", # "Dark Gray"
67
71
  ),
68
72
  **options
69
73
  end # #initialize
@@ -82,10 +86,10 @@ module QB::Util::Logging
82
86
  end
83
87
 
84
88
 
85
- # Create the log entry text. Overridden to customize appearance -
89
+ # Create the log entry text. Overridden to customize appearance -
86
90
  # generally reduce amount of info and put payload on it's own line.
87
91
  #
88
- # We need to replace *two* super functions, the first being
92
+ # We need to replace *two* super functions, the first being
89
93
  # [SemanticLogger::Formatters::Color#call][]:
90
94
  #
91
95
  # def call(log, logger)
@@ -122,8 +126,8 @@ module QB::Util::Logging
122
126
  #
123
127
  # See [SemanticLogger::Logger](https://github.com/rocketjob/semantic_logger/blob/v4.2.0/lib/semantic_logger/logger.rb)
124
128
  #
125
- # @return [return_type]
126
- # @todo Document return value.
129
+ # @return [String]
130
+ # The full log string.
127
131
  #
128
132
  def call log, logger
129
133
  # SemanticLogger::Formatters::Color code
@@ -133,22 +137,18 @@ module QB::Util::Logging
133
137
  self.log = log
134
138
  self.logger = logger
135
139
 
140
+ is_info = log.level == :info
141
+
136
142
  [
137
- # time, annoyingly noisy and don't really need for local CLI app
138
143
  level,
139
- process_info,
140
144
  tags,
141
145
  named_tags,
142
146
  duration,
143
- name,
144
- ].compact.join( ' ' ) +
145
- "\n" +
146
- [
147
+ (is_info ? nil : name),
147
148
  message,
148
149
  payload,
149
150
  exception,
150
- ].compact.join(' ') +
151
- "\n" # I like extra newline to space shit out
151
+ ].compact.join(' ')
152
152
 
153
153
  end # #call
154
154
 
@@ -158,9 +158,139 @@ module QB::Util::Logging
158
158
  end # module Formatters
159
159
 
160
160
 
161
+ module Appender
162
+ # Replacement for {SemanticLogger::Appender::Async} that implements the
163
+ # same interface but just logs synchronously in the current thread.
164
+ #
165
+ class Sync
166
+ extend Forwardable
167
+
168
+ # The appender we forward to, which is a {SemanticLogger::Processor}
169
+ # in practice, since it wouldn't make any sense to wrap a regular
170
+ # appender in a Sync.
171
+ #
172
+ # @return [SemanticLogger::Processor]
173
+ #
174
+ attr_accessor :appender
175
+
176
+ # Forward methods that can be called directly
177
+ def_delegator :@appender, :name
178
+ def_delegator :@appender, :should_log?
179
+ def_delegator :@appender, :filter
180
+ def_delegator :@appender, :host
181
+ def_delegator :@appender, :application
182
+ def_delegator :@appender, :level
183
+ def_delegator :@appender, :level=
184
+ def_delegator :@appender, :logger
185
+ # Added for sync
186
+ def_delegator :@appender, :log
187
+ def_delegator :@appender, :on_log
188
+ def_delegator :@appender, :flush
189
+ def_delegator :@appender, :close
190
+
191
+ class FakeQueue
192
+ def self.size
193
+ 0
194
+ end
195
+ end
196
+
197
+ # Appender proxy to allow an existing appender to run asynchronously in a separate thread.
198
+ #
199
+ # Parameters:
200
+ # name: [String]
201
+ # Name to use for the log thread and the log name when logging any errors from this appender.
202
+ #
203
+ # lag_threshold_s [Float]
204
+ # Log a warning when a log message has been on the queue for longer than this period in seconds.
205
+ # Default: 30
206
+ #
207
+ # lag_check_interval: [Integer]
208
+ # Number of messages to process before checking for slow logging.
209
+ # Default: 1,000
210
+ def initialize(appender:,
211
+ name: appender.class.name)
212
+
213
+ @appender = appender
214
+ end
215
+
216
+ # Needs to be there to support {SemanticLogger::Processor.queue_size},
217
+ # which gets the queue and returns it's size (which will always be zero
218
+ # for us).
219
+ #
220
+ # We return {FakeQueue}, which only implements a `size` method that
221
+ # returns zero.
222
+ #
223
+ # @return [#size]
224
+ #
225
+ def queue; FakeQueue; end
226
+
227
+ def lag_check_interval; -1; end
228
+
229
+ def lag_check_interval= value
230
+ raise "Can't set `lag_check_interval` on Sync appender"
231
+ end
232
+
233
+ def lag_threshold_s; -1; end
234
+
235
+ def lag_threshold_s= value
236
+ raise "Can't set `lag_threshold_s` on Sync appender"
237
+ end
238
+
239
+ # @return [false] Sync appender is of course not size-capped.
240
+ def capped?; false; end
241
+
242
+ # The {SemanticLogger::Appender::Async} worker thread is exposed via
243
+ # this method, which creates it if it doesn't exist and returns it, but
244
+ # it doesn't seem like the returned value is ever used; the method
245
+ # call is just invoked to start the thread.
246
+ #
247
+ # Hence it seems to make most sense to just return `nil` since we don't
248
+ # have a thread, and figure out what to do if that causes errors (so far
249
+ # it seems fine).
250
+ #
251
+ # @return [nil]
252
+ #
253
+ def thread; end
254
+
255
+ # @return [true] Sync appender is always active
256
+ def active?; true; end
257
+
258
+ end # class Sync
259
+ end # module Appenders
260
+
261
+
161
262
  # Module (Class) Methods
162
263
  # =====================================================================
163
264
 
265
+
266
+ def self.level
267
+ SemanticLogger.default_level
268
+ end
269
+
270
+
271
+ def self.level= level
272
+ SemanticLogger.default_level = level
273
+ end
274
+
275
+
276
+ def self.setup?
277
+ !!@setup
278
+ end
279
+
280
+
281
+ def self.get_env_level
282
+ if ENV['QB_TRACE'].truthy?
283
+ return :trace
284
+ elsif ENV['QB_DEBUG'].truthy?
285
+ return :debug
286
+ elsif ENV['QB_LOG_LEVEL']
287
+ return ENV['QB_LOG_LEVEL'].to_sym
288
+ end
289
+
290
+ nil
291
+ end
292
+
293
+
164
294
  # Setup logging.
165
295
  #
166
296
  # @param [type] arg_name
@@ -169,34 +299,38 @@ module QB::Util::Logging
169
299
  # @return [return_type]
170
300
  # @todo Document return value.
171
301
  #
172
- def self.setup level: nil
173
- if level.nil?
174
- if ENV['QB_LOG_LEVEL']
175
- level = ENV['QB_LOG_LEVEL'].to_sym
176
- else
177
- level = :info
178
- end
302
+ def self.setup level: nil, sync: false, dest: nil
303
+ if setup?
304
+ logger.warn "Logging is already setup!"
305
+ return false
179
306
  end
180
307
 
181
- SemanticLogger.default_level = level
182
-
183
- @appender ||= SemanticLogger.add_appender(
184
- io: $stderr,
185
- formatter: Formatters::Color.new,
186
- )
187
-
188
- # Set ENV vars (that Ansible modules will have access to!)
308
+ SemanticLogger.application = 'qb'
189
309
 
190
- ENV['QB_LOG_LEVEL'] = level.to_s
310
+ level = get_env_level if level.nil?
311
+ self.level = level if level
312
+ self.appender = dest if dest
191
313
 
192
- if level == :debug
193
- ENV['QB_DEBUG'] = 'true'
194
- logger.debug "debug logging is ON"
195
- else
196
- ENV.delete 'QB_DEBUG'
314
+ if sync
315
+ # Hack up SemanticLogger to do sync logging in the main thread
316
+
317
+ # Create a {Locd::Logging::Appender::Sync}, which implements the
318
+ # {SemanticLogger::Appender::Async} interface but just forwards directly
319
+ # to it's appender in the same thread, and point it where
320
+ # {SemanticLogger::Processor.instance} (which is an Async) points.
321
+ #
322
+ sync_appender = Appender::Sync.new \
323
+ appender: SemanticLogger::Processor.instance.appender
324
+
325
+ # Swap our sync in for the async
326
+ SemanticLogger::Processor.instance_variable_set \
327
+ :@processor,
328
+ sync_appender
197
329
  end
198
330
 
199
- nil
331
+ @setup = true
332
+
333
+ true
200
334
  end # .setup
201
335
 
202
336
 
@@ -205,4 +339,28 @@ module QB::Util::Logging
205
339
  end
206
340
 
207
341
 
342
+ def self.appender= value
343
+ # Save ref to current appender (if any) so we can remove it after adding
344
+ # the new one.
345
+ old_appender = @appender
346
+
347
+ @appender = case value
348
+ when Hash
349
+ SemanticLogger.add_appender value
350
+ when String
351
+ SemanticLogger.add_appender file_name: value
352
+ else
353
+ SemanticLogger.add_appender \
354
+ io: value,
355
+ formatter: Formatters::Color.new
356
+ end
357
+
358
+ # Remove the old appender (if there was one). This is done after adding
359
+ # the new one so that failing won't result with no appenders.
360
+ SemanticLogger.remove_appender( old_appender ) if old_appender
361
+
362
+ @appender
363
+ end
364
+
365
+
208
366
  end # module QB::Util::Logging
@@ -1,4 +1,4 @@
1
- #!/usr/bin/python
1
+ #!/usr/bin/env python
2
2
 
3
3
  # import some python modules that we'll use. These are all
4
4
  # available in Python's core
@@ -70,4 +70,4 @@ from ansible.module_utils.basic import *
70
70
  from ansible.module_utils.known_hosts import *
71
71
 
72
72
  if __name__ == '__main__':
73
- main()
73
+ main()
@@ -1,4 +1,4 @@
1
- #!/usr/bin/python
1
+ #!/usr/bin/env python
2
2
 
3
3
  import subprocess
4
4
  import os
@@ -55,7 +55,7 @@ def main():
55
55
  'qb_git_origin_url': ['git', 'remote', 'get-url', 'origin'],
56
56
  }
57
57
 
58
- for key, cmd in cmds.iteritems():
58
+ for key, cmd in cmds.iteritems():
59
59
  try:
60
60
  value = subprocess.check_output(cmd).rstrip()
61
61
  facts[key] = value
@@ -114,4 +114,4 @@ from ansible.module_utils.basic import *
114
114
  from ansible.module_utils.known_hosts import *
115
115
 
116
116
  if __name__ == '__main__':
117
- main()
117
+ main()
data/qb.gemspec CHANGED
@@ -194,9 +194,14 @@ Gem::Specification.new do |spec|
194
194
  # Runtime Dependencies
195
195
  # ----------------------------------------------------------------------------
196
196
 
197
- spec.add_dependency "cmds", '~> 0.2.7'
198
- spec.add_dependency "nrser", '< 0.3', '>= 0.2.0.pre.2'
199
- spec.add_dependency "state_mate", '~> 0.1.1'
197
+ # My guns
198
+ spec.add_dependency "nrser", '< 0.3', '>= 0.2.0.pre.3'
199
+
200
+ # My favorite wrapper
201
+ spec.add_dependency "cmds", '~> 0.2.10'
202
+
203
+ # My gem to help manage system state
204
+ spec.add_dependency "state_mate", '~> 0.1.3'
200
205
 
201
206
  # Used to parse `ansible.cfg` files
202
207
  spec.add_dependency 'parseconfig', '~> 1.0', '>= 1.0.8'
@@ -0,0 +1,14 @@
1
+ ##
2
+ # Python dependencies
3
+ #
4
+ # TODO Consider changing this to
5
+ #
6
+ # ansible>=2.4.1.0,<2.5
7
+ # pathlib2>=2.3.0,<3
8
+ #
9
+ # to allow more flexibility?
10
+ #
11
+ ##
12
+
13
+ ansible==2.4.1.0
14
+ pathlib2==2.3.0
@@ -25,12 +25,7 @@ import tempfile
25
25
  from itertools import chain
26
26
 
27
27
  import pprint
28
-
29
- try:
30
- from __main__ import display
31
- except ImportError:
32
- from ansible.utils.display import Display
33
- display = Display()
28
+
34
29
 
35
30
  DOCUMENTATION = """
36
31
  ---
@@ -295,31 +290,31 @@ def main():
295
290
  # removed along with the content.
296
291
  #
297
292
  if not present or block == '':
298
- display.debug("removing block")
293
+ module.debug("removing block")
299
294
 
300
295
  result = different_re.sub('', original)
301
296
 
302
297
  # 2. no-op - the exact text is already present
303
298
  elif exact_re.search(original):
304
- display.debug("block already present")
299
+ module.debug("block already present")
305
300
 
306
301
  pass
307
302
 
308
303
  # 3. replace - the markers are present but the content is different
309
304
  elif different_re.search(original):
310
- display.debug("block present but different, replacing")
305
+ module.debug("block present but different, replacing")
311
306
 
312
307
  result = different_re.sub(replacement, original)
313
308
 
314
- # 4. insert - the markers
309
+ # 4. insert - the markers
315
310
  else:
316
- display.debug("block not present, inserting")
311
+ module.debug("block not present, inserting")
317
312
 
318
313
  lines = original.splitlines()
319
314
 
320
315
  n0 = None
321
316
  if insertre is not None:
322
- match = insertre.search(original)
317
+ match = insertre.search(original)
323
318
  for i, line in enumerate(lines):
324
319
  if insertre.search(line):
325
320
  n0 = i
@@ -4,7 +4,7 @@ galaxy_info:
4
4
  description: Contains blockinfile module
5
5
  to insert/update/remove a text block surrounded by marker lines
6
6
  license: GPLv3+
7
- min_ansible_version: 1.2
7
+ min_ansible_version: 2.4
8
8
  categories:
9
9
  - system
10
10
  dependencies: []
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.23
4
+ version: 0.3.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - nrser
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-28 00:00:00.000000000 Z
11
+ date: 2018-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,20 +114,6 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: 0.10.4
117
- - !ruby/object:Gem::Dependency
118
- name: cmds
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: 0.2.7
124
- type: :runtime
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: 0.2.7
131
117
  - !ruby/object:Gem::Dependency
132
118
  name: nrser
133
119
  requirement: !ruby/object:Gem::Requirement
@@ -137,7 +123,7 @@ dependencies:
137
123
  version: '0.3'
138
124
  - - ">="
139
125
  - !ruby/object:Gem::Version
140
- version: 0.2.0.pre.2
126
+ version: 0.2.0.pre.3
141
127
  type: :runtime
142
128
  prerelease: false
143
129
  version_requirements: !ruby/object:Gem::Requirement
@@ -147,21 +133,35 @@ dependencies:
147
133
  version: '0.3'
148
134
  - - ">="
149
135
  - !ruby/object:Gem::Version
150
- version: 0.2.0.pre.2
136
+ version: 0.2.0.pre.3
137
+ - !ruby/object:Gem::Dependency
138
+ name: cmds
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: 0.2.10
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: 0.2.10
151
151
  - !ruby/object:Gem::Dependency
152
152
  name: state_mate
153
153
  requirement: !ruby/object:Gem::Requirement
154
154
  requirements:
155
155
  - - "~>"
156
156
  - !ruby/object:Gem::Version
157
- version: 0.1.1
157
+ version: 0.1.3
158
158
  type: :runtime
159
159
  prerelease: false
160
160
  version_requirements: !ruby/object:Gem::Requirement
161
161
  requirements:
162
162
  - - "~>"
163
163
  - !ruby/object:Gem::Version
164
- version: 0.1.1
164
+ version: 0.1.3
165
165
  - !ruby/object:Gem::Dependency
166
166
  name: parseconfig
167
167
  requirement: !ruby/object:Gem::Requirement
@@ -294,6 +294,7 @@ files:
294
294
  - lib/qb/package/version/from.rb
295
295
  - lib/qb/package/version/leveled.rb
296
296
  - lib/qb/path.rb
297
+ - lib/qb/python.rb
297
298
  - lib/qb/repo.rb
298
299
  - lib/qb/repo/git.rb
299
300
  - lib/qb/repo/git/github.rb
@@ -332,6 +333,7 @@ files:
332
333
  - plugins/lookup_plugins/resolve.py
333
334
  - plugins/lookup_plugins/version.py
334
335
  - qb.gemspec
336
+ - requirements.txt
335
337
  - roles/nrser.blockinfile/CONTRIBUTING.md
336
338
  - roles/nrser.blockinfile/README.md
337
339
  - roles/nrser.blockinfile/library/blockinfile.py