kennel 2.22.2 → 2.23.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 371dd82c75198714d213f7aae056198d110a862559e7c7f880aa3d94049590fa
4
- data.tar.gz: b68693df3582c1c0344454af713c155210b9a477c311edff0278fd68134fc8f5
3
+ metadata.gz: 614aead22d9d8cbf26ce1ebc7d479bb31f639218975724c8d49788205498fc80
4
+ data.tar.gz: c74efdd742433b316e89ea90d9bb454995ae6dde9e718058a29291c69f430947
5
5
  SHA512:
6
- metadata.gz: 56020b989084f93c418ac3afc2a03fafea9eb2e0b9d9d760c7b06a152556d67f884d523b38c9178b8777edc5c09faff5d465dffd846e2b56cbb5652b106fd53d
7
- data.tar.gz: a10a1fb9a3b35bccde14f09a154b42f65f360d8887a0886df1fe73846d026df3a58f877ca247e7e7f572769cce0d0334a4a6f2e41edca26a98fdb0a11eb1d563
6
+ metadata.gz: 5e64729084251aede67228e6d2b610b2dd5a689a574ec47417aaceb31f14d1df6e7cb47b795108763ba0b28498d7db0b97aee5f1ad115949736ce74274b7f5b0
7
+ data.tar.gz: bfc68b6992bf396e488b46ce309aab911bd6650fa5c7e8577e7632d18ec1175053f85e89db458b9e7278d560e54a27b05fc3dd2eb830bc9a81089c8d80d62bf9
data/lib/kennel/api.rb CHANGED
@@ -103,10 +103,11 @@ module Kennel
103
103
  end
104
104
  end
105
105
 
106
- # yield each widget with a key built from its (optional) group title and its own title
106
+ # yield each widget with a key built from its group optional title/position and its own title/position
107
107
  def each_widget_with_key(widgets, prefix: nil, &block)
108
- widgets.each do |widget|
108
+ widgets.each_with_index do |widget, i|
109
109
  title = widget.dig(:definition, :title)
110
+ title = i.to_s if title.to_s.empty?
110
111
  key = [prefix, title].compact.join("-")
111
112
  yield key, widget
112
113
  if (nested = widget.dig(:definition, :widgets))
@@ -161,7 +161,7 @@ module Kennel
161
161
 
162
162
  sort_hash(hash).map do |k, v|
163
163
  pretty_value =
164
- if v.is_a?(Hash) || (v.is_a?(Array) && !v.all? { |e| e.is_a?(String) })
164
+ if v.is_a?(Hash) || (v.is_a?(Array) && !v.all?(String))
165
165
  # update answer here when changing https://stackoverflow.com/questions/8842546/best-way-to-pretty-print-a-hash
166
166
  # (exclude last indent gsub)
167
167
  pretty = JSON.pretty_generate(v)
@@ -32,7 +32,7 @@ module Kennel
32
32
 
33
33
  def validated_parts
34
34
  all = filter_parts(parts)
35
- unless all.is_a?(Array) && all.all? { |part| part.is_a?(Record) }
35
+ unless all.is_a?(Array) && all.all?(Record)
36
36
  raise "Project #{kennel_id} #parts must return an array of Records"
37
37
  end
38
38
 
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
+ require "etc"
3
+ require "parallel"
2
4
 
3
5
  module Kennel
4
6
  class PartsSerializer
@@ -29,20 +31,32 @@ module Kennel
29
31
  attr_reader :filter
30
32
 
31
33
  def write_changed(parts)
32
- used = []
33
- changed = []
34
+ paths_used = []
35
+ to_generate = []
34
36
 
35
- Utils.parallel(parts, max: 2) do |part|
37
+ parts.each do |part|
36
38
  path = path_for_tracking_id(part.tracking_id)
37
39
 
38
40
  # match paths returned from existing_files_and_folders
39
- used << File.dirname(path) # we have 1 level of sub folders, so this is enough
40
- used << path
41
+ paths_used << File.dirname(path) # we have 1 level of sub folders, so this is enough
42
+ paths_used << path
41
43
 
42
44
  content = part.as_json.merge(api_resource: part.class.api_resource)
43
- changed << path if write_file_if_necessary(path, content)
45
+ to_generate << [path, content]
46
+ end
47
+
48
+ paths_changed = generate_and_write(to_generate)
49
+
50
+ [paths_used, paths_changed]
51
+ end
52
+
53
+ # JSON.pretty_generate is CPU-bound and threads are limited by the GVL, so we fork
54
+ def generate_and_write(to_generate)
55
+ chunks = to_generate.each_slice(100) # processing 1-by-1 would be slow
56
+
57
+ Parallel.flat_map(chunks, exit!: true) do |chunk|
58
+ chunk.filter_map { |path, content| path if write_file_if_necessary(path, content) }
44
59
  end
45
- [used, changed]
46
60
  end
47
61
 
48
62
  def existing_files_and_folders
@@ -38,8 +38,22 @@ module Kennel
38
38
 
39
39
  def widget_queries(widget)
40
40
  requests = widget.dig(:definition, :requests) || []
41
- return requests.values.map { |r| r[:q] } if requests.is_a?(Hash) # hostmap widgets have hash requests
41
+ return hostmap_queries(requests) if requests.is_a?(Hash) # hostmap widgets have hash requests
42
42
  requests.flat_map { |r| r[:q] || r[:queries]&.map { |q| q[:query] } } # old format with q: or queries: [{query:}]
43
43
  end
44
+
45
+ # hostmap requests nest queries at varying depth, for example
46
+ # { fill: { q: "..." } } or { fill: { queries: [{ search: { query: "..." } }] }, request_type: "hosts" }
47
+ def hostmap_queries(node)
48
+ case node
49
+ when Hash
50
+ query = node[:q] || node[:query]
51
+ [*query, *hostmap_queries(node.except(:q, :query).values)]
52
+ when Array
53
+ node.flat_map { |v| hostmap_queries(v) }
54
+ else
55
+ [] # scalar leaves like request_type: "hosts"
56
+ end
57
+ end
44
58
  end
45
59
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "2.22.2"
3
+ VERSION = "2.23.0"
4
4
  end
data/lib/kennel.rb CHANGED
@@ -43,9 +43,14 @@ module Teams
43
43
  end
44
44
 
45
45
  module Kennel
46
- UnresolvableIdError = Class.new(StandardError)
47
- DisallowedUpdateError = Class.new(StandardError)
48
- GenerationAbortedError = Class.new(StandardError)
46
+ class UnresolvableIdError < StandardError
47
+ end
48
+
49
+ class DisallowedUpdateError < StandardError
50
+ end
51
+
52
+ class GenerationAbortedError < StandardError
53
+ end
49
54
 
50
55
  class << self
51
56
  attr_accessor :in, :out, :err
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kennel
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.22.2
4
+ version: 2.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '1.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: parallel
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.3'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.3'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: zeitwerk
70
84
  requirement: !ruby/object:Gem::Requirement