inspec 1.45.9 → 1.45.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +54 -32
  3. data/CHANGELOG.md +29 -21
  4. data/Gemfile +1 -1
  5. data/docs/resources/ini.md.erb +14 -1
  6. data/docs/shell.md +1 -1
  7. data/inspec.gemspec +2 -2
  8. data/lib/bundles/inspec-artifact/cli.rb +3 -8
  9. data/lib/bundles/inspec-compliance/configuration.rb +5 -5
  10. data/lib/bundles/inspec-compliance/http.rb +2 -5
  11. data/lib/bundles/inspec-compliance/target.rb +6 -6
  12. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +1 -1
  13. data/lib/bundles/inspec-habitat/profile.rb +68 -74
  14. data/lib/bundles/inspec-supermarket/api.rb +7 -7
  15. data/lib/bundles/inspec-supermarket/cli.rb +1 -1
  16. data/lib/fetchers/git.rb +3 -8
  17. data/lib/fetchers/local.rb +7 -13
  18. data/lib/fetchers/url.rb +1 -1
  19. data/lib/inspec/backend.rb +0 -1
  20. data/lib/inspec/base_cli.rb +1 -1
  21. data/lib/inspec/cached_fetcher.rb +11 -12
  22. data/lib/inspec/cli.rb +0 -1
  23. data/lib/inspec/control_eval_context.rb +2 -2
  24. data/lib/inspec/dependencies/lockfile.rb +13 -15
  25. data/lib/inspec/dependencies/requirement.rb +1 -1
  26. data/lib/inspec/dependencies/resolver.rb +3 -5
  27. data/lib/inspec/dsl.rb +5 -5
  28. data/lib/inspec/dsl_shared.rb +1 -1
  29. data/lib/inspec/env_printer.rb +26 -26
  30. data/lib/inspec/metadata.rb +11 -10
  31. data/lib/inspec/objects/or_test.rb +4 -2
  32. data/lib/inspec/objects/test.rb +1 -1
  33. data/lib/inspec/profile.rb +2 -2
  34. data/lib/inspec/resource.rb +1 -3
  35. data/lib/inspec/rspec_json_formatter.rb +6 -8
  36. data/lib/inspec/shell.rb +51 -52
  37. data/lib/inspec/version.rb +1 -1
  38. data/lib/matchers/matchers.rb +1 -2
  39. data/lib/resources/audit_policy.rb +2 -2
  40. data/lib/resources/auditd.rb +6 -3
  41. data/lib/resources/dh_params.rb +1 -2
  42. data/lib/resources/docker.rb +2 -2
  43. data/lib/resources/docker_container.rb +4 -4
  44. data/lib/resources/elasticsearch.rb +2 -6
  45. data/lib/resources/etc_group.rb +2 -4
  46. data/lib/resources/groups.rb +14 -14
  47. data/lib/resources/host.rb +2 -3
  48. data/lib/resources/packages.rb +1 -1
  49. data/lib/resources/port.rb +1 -1
  50. data/lib/resources/postgres.rb +6 -6
  51. data/lib/resources/powershell.rb +1 -1
  52. data/lib/resources/service.rb +4 -5
  53. data/lib/resources/users.rb +58 -58
  54. data/lib/resources/vbscript.rb +10 -10
  55. data/lib/resources/virtualization.rb +3 -4
  56. data/lib/resources/x509_certificate.rb +1 -1
  57. data/lib/resources/yum.rb +1 -1
  58. data/lib/source_readers/inspec.rb +2 -1
  59. data/lib/utils/command_wrapper.rb +3 -8
  60. data/lib/utils/filter.rb +1 -1
  61. data/lib/utils/json_log.rb +2 -1
  62. data/lib/utils/latest_version.rb +5 -4
  63. data/lib/utils/object_traversal.rb +1 -1
  64. data/lib/utils/parser.rb +2 -2
  65. metadata +4 -4
@@ -55,13 +55,13 @@ module Inspec::Resources
55
55
  private
56
56
 
57
57
  def verify_dirs
58
- if !inspec.directory(@conf_dir).exist?
59
- warn "Default postgresql configuration directory: #{@conf_dir} does not exist. Postgresql may not be installed or we've misidentified the configuration directory."
60
- end
58
+ warn "Default postgresql configuration directory: #{@conf_dir} does not exist. " \
59
+ "Postgresql may not be installed or we've misidentified the configuration " \
60
+ 'directory.' unless inspec.directory(@conf_dir).exist?
61
61
 
62
- if !inspec.directory(@data_dir).exist?
63
- warn "Default postgresql data directory: #{@data_dir} does not exist. Postgresql may not be installed or we've misidentified the data directory."
64
- end
62
+ warn "Default postgresql data directory: #{@data_dir} does not exist. " \
63
+ "Postgresql may not be installed or we've misidentified the data " \
64
+ 'directory.' unless inspec.directory(@data_dir).exist?
65
65
  end
66
66
 
67
67
  def version_from_psql
@@ -34,7 +34,7 @@ module Inspec::Resources
34
34
 
35
35
  # Removes leading and trailing whitespace from stdout
36
36
  def strip
37
- result.stdout.strip unless result.stdout.nil?
37
+ result.stdout&.strip
38
38
  end
39
39
 
40
40
  def to_s
@@ -51,7 +51,7 @@ module Inspec::Resources
51
51
  #
52
52
  # @return [boolean] true if all runlevels are disabled
53
53
  def disabled?
54
- !values.any?
54
+ values.none?
55
55
  end
56
56
 
57
57
  def to_s
@@ -136,7 +136,7 @@ module Inspec::Resources
136
136
  end
137
137
  elsif %w{redhat fedora centos oracle}.include?(platform)
138
138
  version = os[:release].to_i
139
- if (%w{ redhat centos oracle }.include?(platform) && version >= 7) || (platform == 'fedora' && version >= 15)
139
+ if (%w{redhat centos oracle}.include?(platform) && version >= 7) || (platform == 'fedora' && version >= 15)
140
140
  Systemd.new(inspec, service_ctl)
141
141
  else
142
142
  SysV.new(inspec, service_ctl || '/sbin/service')
@@ -314,7 +314,6 @@ module Inspec::Resources
314
314
  enabled_rc_tcpip? || enabled_inittab?
315
315
  end
316
316
 
317
- # #rubocop:disable Style/TrailingComma
318
317
  def enabled_rc_tcpip?
319
318
  inspec.command(
320
319
  "grep -v ^# /etc/rc.tcpip | grep 'start ' | grep -Eq '(/{0,1}| )#{name} '",
@@ -367,10 +366,10 @@ module Inspec::Resources
367
366
  end
368
367
 
369
368
  def version
370
- @version ||= (
369
+ @version ||= begin
371
370
  out = inspec.command("#{service_ctl} --version").stdout
372
371
  Gem::Version.new(out[/\(upstart ([^\)]+)\)/, 1])
373
- )
372
+ end
374
373
  end
375
374
  end
376
375
 
@@ -575,64 +575,64 @@ module Inspec::Resources
575
575
  # https://msdn.microsoft.com/en-us/library/aa746340(v=vs.85).aspx
576
576
  def collect_user_details # rubocop:disable Metrics/MethodLength
577
577
  return @users_cache if defined?(@users_cache)
578
- script = <<-EOH
579
- Function ConvertTo-SID { Param([byte[]]$BinarySID)
580
- (New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
581
- }
582
-
583
- Function Convert-UserFlag { Param ($UserFlag)
584
- $List = @()
585
- Switch ($UserFlag) {
586
- ($UserFlag -BOR 0x0001) { $List += 'SCRIPT' }
587
- ($UserFlag -BOR 0x0002) { $List += 'ACCOUNTDISABLE' }
588
- ($UserFlag -BOR 0x0008) { $List += 'HOMEDIR_REQUIRED' }
589
- ($UserFlag -BOR 0x0010) { $List += 'LOCKOUT' }
590
- ($UserFlag -BOR 0x0020) { $List += 'PASSWD_NOTREQD' }
591
- ($UserFlag -BOR 0x0040) { $List += 'PASSWD_CANT_CHANGE' }
592
- ($UserFlag -BOR 0x0080) { $List += 'ENCRYPTED_TEXT_PWD_ALLOWED' }
593
- ($UserFlag -BOR 0x0100) { $List += 'TEMP_DUPLICATE_ACCOUNT' }
594
- ($UserFlag -BOR 0x0200) { $List += 'NORMAL_ACCOUNT' }
595
- ($UserFlag -BOR 0x0800) { $List += 'INTERDOMAIN_TRUST_ACCOUNT' }
596
- ($UserFlag -BOR 0x1000) { $List += 'WORKSTATION_TRUST_ACCOUNT' }
597
- ($UserFlag -BOR 0x2000) { $List += 'SERVER_TRUST_ACCOUNT' }
598
- ($UserFlag -BOR 0x10000) { $List += 'DONT_EXPIRE_PASSWORD' }
599
- ($UserFlag -BOR 0x20000) { $List += 'MNS_LOGON_ACCOUNT' }
600
- ($UserFlag -BOR 0x40000) { $List += 'SMARTCARD_REQUIRED' }
601
- ($UserFlag -BOR 0x80000) { $List += 'TRUSTED_FOR_DELEGATION' }
602
- ($UserFlag -BOR 0x100000) { $List += 'NOT_DELEGATED' }
603
- ($UserFlag -BOR 0x200000) { $List += 'USE_DES_KEY_ONLY' }
604
- ($UserFlag -BOR 0x400000) { $List += 'DONT_REQ_PREAUTH' }
605
- ($UserFlag -BOR 0x800000) { $List += 'PASSWORD_EXPIRED' }
606
- ($UserFlag -BOR 0x1000000) { $List += 'TRUSTED_TO_AUTH_FOR_DELEGATION' }
607
- ($UserFlag -BOR 0x04000000) { $List += 'PARTIAL_SECRETS_ACCOUNT' }
608
- }
609
- $List
610
- }
611
-
612
- $Computername = $Env:Computername
613
- $adsi = [ADSI]"WinNT://$Computername"
614
- $adsi.Children | where {$_.SchemaClassName -eq 'user'} | ForEach {
615
- New-Object PSObject -property @{
616
- uid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
617
- username = $_.Name[0]
618
- description = $_.Description[0]
619
- disabled = $_.AccountDisabled[0]
620
- userflags = Convert-UserFlag -UserFlag $_.UserFlags[0]
621
- passwordage = [math]::Round($_.PasswordAge[0]/86400)
622
- minpasswordlength = $_.MinPasswordLength[0]
623
- mindays = [math]::Round($_.MinPasswordAge[0]/86400)
624
- maxdays = [math]::Round($_.MaxPasswordAge[0]/86400)
625
- warndays = $null
626
- badpasswordattempts = $_.BadPasswordAttempts[0]
627
- maxbadpasswords = $_.MaxBadPasswordsAllowed[0]
628
- gid = $null
629
- group = $null
630
- groups = @($_.Groups() | Foreach-Object { $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null) })
631
- home = $_.HomeDirectory[0]
632
- shell = $null
633
- domain = $Computername
634
- }
635
- } | ConvertTo-Json
578
+ script = <<~EOH
579
+ Function ConvertTo-SID { Param([byte[]]$BinarySID)
580
+ (New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
581
+ }
582
+
583
+ Function Convert-UserFlag { Param ($UserFlag)
584
+ $List = @()
585
+ Switch ($UserFlag) {
586
+ ($UserFlag -BOR 0x0001) { $List += 'SCRIPT' }
587
+ ($UserFlag -BOR 0x0002) { $List += 'ACCOUNTDISABLE' }
588
+ ($UserFlag -BOR 0x0008) { $List += 'HOMEDIR_REQUIRED' }
589
+ ($UserFlag -BOR 0x0010) { $List += 'LOCKOUT' }
590
+ ($UserFlag -BOR 0x0020) { $List += 'PASSWD_NOTREQD' }
591
+ ($UserFlag -BOR 0x0040) { $List += 'PASSWD_CANT_CHANGE' }
592
+ ($UserFlag -BOR 0x0080) { $List += 'ENCRYPTED_TEXT_PWD_ALLOWED' }
593
+ ($UserFlag -BOR 0x0100) { $List += 'TEMP_DUPLICATE_ACCOUNT' }
594
+ ($UserFlag -BOR 0x0200) { $List += 'NORMAL_ACCOUNT' }
595
+ ($UserFlag -BOR 0x0800) { $List += 'INTERDOMAIN_TRUST_ACCOUNT' }
596
+ ($UserFlag -BOR 0x1000) { $List += 'WORKSTATION_TRUST_ACCOUNT' }
597
+ ($UserFlag -BOR 0x2000) { $List += 'SERVER_TRUST_ACCOUNT' }
598
+ ($UserFlag -BOR 0x10000) { $List += 'DONT_EXPIRE_PASSWORD' }
599
+ ($UserFlag -BOR 0x20000) { $List += 'MNS_LOGON_ACCOUNT' }
600
+ ($UserFlag -BOR 0x40000) { $List += 'SMARTCARD_REQUIRED' }
601
+ ($UserFlag -BOR 0x80000) { $List += 'TRUSTED_FOR_DELEGATION' }
602
+ ($UserFlag -BOR 0x100000) { $List += 'NOT_DELEGATED' }
603
+ ($UserFlag -BOR 0x200000) { $List += 'USE_DES_KEY_ONLY' }
604
+ ($UserFlag -BOR 0x400000) { $List += 'DONT_REQ_PREAUTH' }
605
+ ($UserFlag -BOR 0x800000) { $List += 'PASSWORD_EXPIRED' }
606
+ ($UserFlag -BOR 0x1000000) { $List += 'TRUSTED_TO_AUTH_FOR_DELEGATION' }
607
+ ($UserFlag -BOR 0x04000000) { $List += 'PARTIAL_SECRETS_ACCOUNT' }
608
+ }
609
+ $List
610
+ }
611
+
612
+ $Computername = $Env:Computername
613
+ $adsi = [ADSI]"WinNT://$Computername"
614
+ $adsi.Children | where {$_.SchemaClassName -eq 'user'} | ForEach {
615
+ New-Object PSObject -property @{
616
+ uid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
617
+ username = $_.Name[0]
618
+ description = $_.Description[0]
619
+ disabled = $_.AccountDisabled[0]
620
+ userflags = Convert-UserFlag -UserFlag $_.UserFlags[0]
621
+ passwordage = [math]::Round($_.PasswordAge[0]/86400)
622
+ minpasswordlength = $_.MinPasswordLength[0]
623
+ mindays = [math]::Round($_.MinPasswordAge[0]/86400)
624
+ maxdays = [math]::Round($_.MaxPasswordAge[0]/86400)
625
+ warndays = $null
626
+ badpasswordattempts = $_.BadPasswordAttempts[0]
627
+ maxbadpasswords = $_.MaxBadPasswordsAllowed[0]
628
+ gid = $null
629
+ group = $null
630
+ groups = @($_.Groups() | Foreach-Object { $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null) })
631
+ home = $_.HomeDirectory[0]
632
+ shell = $null
633
+ domain = $Computername
634
+ }
635
+ } | ConvertTo-Json
636
636
  EOH
637
637
  cmd = inspec.powershell(script)
638
638
  # cannot rely on exit code for now, successful command returns exit code 1
@@ -37,16 +37,16 @@ module Inspec::Resources
37
37
  def initialize(vbscript)
38
38
  return skip_resource 'The `vbscript` resource is not supported on your OS yet.' unless inspec.os.windows?
39
39
  @seperator = SecureRandom.uuid
40
- cmd = <<-EOH
41
- $vbscript = @"
42
- #{vbscript}
43
- Wscript.Stdout.Write "#{@seperator}"
44
- "@
45
- $filename = [System.IO.Path]::GetTempFileName() + ".vbs"
46
- New-Item $filename -type file -force -value $vbscript | Out-Null
47
- cscript.exe /nologo $filename
48
- Remove-Item $filename | Out-Null
49
- EOH
40
+ cmd = <<~EOH
41
+ $vbscript = @"
42
+ #{vbscript}
43
+ Wscript.Stdout.Write "#{@seperator}"
44
+ "@
45
+ $filename = [System.IO.Path]::GetTempFileName() + ".vbs"
46
+ New-Item $filename -type file -force -value $vbscript | Out-Null
47
+ cscript.exe /nologo $filename
48
+ Remove-Item $filename | Out-Null
49
+ EOH
50
50
  super(cmd)
51
51
  end
52
52
 
@@ -76,7 +76,7 @@ module Inspec::Resources
76
76
 
77
77
  # This file should exist on most Xen systems, normally empty for guests
78
78
  if inspec.file('/proc/xen/capabilities').exist? &&
79
- inspec.file('/proc/xen/capabilities').content =~ /control_d/i # rubocop:disable Style/MultilineOperationIndentation
79
+ inspec.file('/proc/xen/capabilities').content =~ /control_d/i # rubocop:disable Layout/MultilineOperationIndentation
80
80
  @virtualization_data[:role] = 'host'
81
81
  end
82
82
  true
@@ -120,11 +120,10 @@ module Inspec::Resources
120
120
  # guests will have the hypervisor cpu feature that hosts don't have
121
121
  def detect_kvm_from_sys
122
122
  return false unless inspec.file('/sys/devices/virtual/misc/kvm').exist?
123
+ @virtualization_data[:system] = 'kvm'
123
124
  if inspec.file('/proc/cpuinfo').content =~ /hypervisor/
124
- @virtualization_data[:system] = 'kvm'
125
125
  @virtualization_data[:role] = 'guest'
126
126
  else
127
- @virtualization_data[:system] = 'kvm'
128
127
  @virtualization_data[:role] = 'host'
129
128
  end
130
129
  true
@@ -190,7 +189,7 @@ module Inspec::Resources
190
189
  return false unless inspec.file('/proc/self/cgroup').exist?
191
190
  cgroup_content = inspec.file('/proc/self/cgroup').content
192
191
  if cgroup_content =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$} ||
193
- cgroup_content =~ %r{^\d+:[^:]+:/[^/]+/(lxc|docker)-.+$} # rubocop:disable Style/MultilineOperationIndentation
192
+ cgroup_content =~ %r{^\d+:[^:]+:/[^/]+/(lxc|docker)-.+$} # rubocop:disable Layout/MultilineOperationIndentation
194
193
  @virtualization_data[:system] = $1 # rubocop:disable Style/PerlBackrefs
195
194
  @virtualization_data[:role] = 'guest'
196
195
  elsif lxc_version_exists? && cgroup_content =~ %r{\d:[^:]+:/$}
@@ -52,7 +52,7 @@ module Inspec::Resources
52
52
  end
53
53
 
54
54
  # Forward these methods directly to OpenSSL::X509::Certificate instance
55
- %w{version not_before not_after signature_algorithm public_key }.each do |m|
55
+ %w{version not_before not_after signature_algorithm public_key}.each do |m|
56
56
  define_method m.to_sym do |*args|
57
57
  @cert.method(m.to_sym).call(*args)
58
58
  end
data/lib/resources/yum.rb CHANGED
@@ -94,7 +94,7 @@ module Inspec::Resources
94
94
 
95
95
  # Removes lefthand and righthand whitespace
96
96
  def strip(value)
97
- value.strip if !value.nil?
97
+ value&.strip
98
98
  end
99
99
 
100
100
  # Optimize the key value
@@ -43,7 +43,8 @@ module SourceReaders
43
43
  Inspec::Metadata.from_ref(
44
44
  metadata_source,
45
45
  @target.read(metadata_source),
46
- nil)
46
+ nil,
47
+ )
47
48
  rescue Psych::SyntaxError => e
48
49
  raise "Unable to parse inspec.yml: line #{e.line}, #{e.problem} #{e.context}"
49
50
  rescue => e
@@ -14,16 +14,11 @@ class CommandWrapper
14
14
  end
15
15
 
16
16
  wrap = options[:wrap]
17
- if !wrap.nil? && !wrap.is_a?(Proc)
18
- raise "Called command wrapper with wrap: #{wrap.inspect}. It must be called with a Proc."
19
- elsif !wrap.nil?
20
- return wrap.call(cmd)
21
- end
17
+ raise "Called command wrapper with wrap: #{wrap.inspect}. It must be called with a Proc." if !wrap.nil? && !wrap.is_a?(Proc)
18
+ return wrap.call(cmd) unless wrap.nil?
22
19
 
23
20
  shell = options[:shell]
24
- unless UNIX_SHELLS.include?(shell)
25
- raise "Don't know how to wrap commands for shell: #{shell.inspect}."
26
- end
21
+ raise "Don't know how to wrap commands for shell: #{shell.inspect}." unless UNIX_SHELLS.include?(shell)
27
22
 
28
23
  path = options[:path] || shell
29
24
  args = options[:args] || '-c'
data/lib/utils/filter.rb CHANGED
@@ -151,7 +151,7 @@ module FilterTable
151
151
  # the struct to hold single items from the #entries method
152
152
  entry_struct = Struct.new(*struct_fields.map(&:to_sym)) do
153
153
  attr_accessor :__filter
154
- def to_s # rubocop:disable Lint/NestedMethodDefinition
154
+ def to_s
155
155
  @__filter || super
156
156
  end
157
157
  end unless struct_fields.empty?
@@ -12,6 +12,7 @@ class Logger::JSONFormatter < Logger::Formatter
12
12
  'severity'=> severity,
13
13
  'time'=> time,
14
14
  'msg'=> msg,
15
- },)
15
+ },
16
+ )
16
17
  end
17
18
  end
@@ -8,14 +8,15 @@ class LatestInSpecVersion
8
8
  # fetches the latest version from rubygems server
9
9
  def latest
10
10
  uri = URI('https://rubygems.org/api/v1/gems/inspec.json')
11
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https',
12
- open_timeout: 0.5, read_timeout: 0.5
13
- ) {|http|
11
+ res = Net::HTTP.start(
12
+ uri.host, uri.port, use_ssl: uri.scheme == 'https',
13
+ open_timeout: 0.5, read_timeout: 0.5
14
+ ) { |http|
14
15
  http.get(uri.path)
15
16
  }
16
17
  inspec_info = JSON.parse(res.body)
17
18
  inspec_info['version']
18
- rescue Exception # rubocop:disable Lint/RescueException
19
+ rescue StandardError
19
20
  nil
20
21
  end
21
22
  end
@@ -27,7 +27,7 @@ module ObjectTraverser
27
27
  # If the values to return from is an Array, allow returning by index.
28
28
  # Otherwise, support methods on the Array itself.
29
29
  def extract_from_array(key, value)
30
- if key.is_a?(Fixnum)
30
+ if key.is_a?(Integer)
31
31
  value[key]
32
32
  elsif value.respond_to?(key.to_sym)
33
33
  value.send(key.to_sym)
data/lib/utils/parser.rb CHANGED
@@ -234,8 +234,8 @@ module XinetdParser
234
234
  # extract content line
235
235
  nl = rest.index("\n") || (rest.length-1)
236
236
  comment = rest.index('#') || (rest.length-1)
237
- dst_idx = (comment < nl) ? comment : nl
238
- inner_line = (dst_idx == 0) ? '' : rest[0..dst_idx-1].strip
237
+ dst_idx = comment < nl ? comment : nl
238
+ inner_line = dst_idx == 0 ? '' : rest[0..dst_idx-1].strip
239
239
  # update unparsed content
240
240
  rest = rest[nl+1..-1]
241
241
  next if inner_line.empty?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.45.9
4
+ version: 1.45.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-16 00:00:00.000000000 Z
11
+ date: 2017-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '0.29'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.29.1
22
+ version: 0.29.2
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '0.29'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.29.1
32
+ version: 0.29.2
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: thor
35
35
  requirement: !ruby/object:Gem::Requirement