Skip to content

Commit d13307f

Browse files
committed
fixed scripts/export_provider_catalog.rb for terraform provider/module
1 parent 4755e92 commit d13307f

File tree

4 files changed

+148
-90
lines changed

4 files changed

+148
-90
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ GEM
414414
spoom (>= 1.2.0)
415415
thor (>= 1.2.0)
416416
yard-sorbet
417-
thor (1.3.2)
417+
thor (1.4.0)
418418
tilt (2.6.0)
419419
timeout (0.4.3)
420420
tzinfo (2.0.6)

scripts/export_provider_catalog.rb

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,99 @@
66
require "fileutils"
77

88
root = File.expand_path("..", __dir__)
9-
docs_gen = File.join(root, "docs", "lib", "log-generation")
10-
enums_path = File.join(docs_gen, "sorbet-enums.json")
11-
structs_path = File.join(docs_gen, "sorbet-log-structs.json")
12-
keys_path = File.join(docs_gen, "log-fields.json")
9+
docs_generated = File.join(root, "docs", "generated", "logstruct")
10+
structs_path = File.join(docs_generated, "sorbet-log-structs.json")
11+
enums_path = File.join(docs_generated, "sorbet-enums.json")
1312

14-
unless File.exist?(enums_path) && File.exist?(structs_path) && File.exist?(keys_path)
15-
abort "Missing generated files in #{docs_gen}. Run `task generate` first."
13+
unless File.exist?(structs_path) && File.exist?(enums_path)
14+
abort "Missing generated files in #{docs_generated}. Run `scripts/generate_structs.rb` first."
1615
end
1716

18-
enums = JSON.parse(File.read(enums_path))
1917
structs = JSON.parse(File.read(structs_path))
20-
keys = JSON.parse(File.read(keys_path))
18+
enums = JSON.parse(File.read(enums_path))
19+
20+
def camel_to_snake(value)
21+
value
22+
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\\1_\\2')
23+
.gsub(/([a-z\d])([A-Z])/, '\\1_\\2')
24+
.downcase
25+
end
2126

22-
# Build lookup maps for enum serialized values
23-
event_values = {}
24-
(enums["LogStruct::Event"] || []).each { |e| event_values[e["name"]] = e["value"] }
25-
source_values = {}
26-
(enums["LogStruct::Source"] || []).each { |e| source_values[e["name"]] = e["value"] }
27+
log_field_enum = enums.fetch("LogStruct::LogField") do
28+
abort "LogStruct::LogField enum missing from #{enums_path}."
29+
end
30+
31+
keys = log_field_enum.fetch("values", []).each_with_object({}) do |enum_value, memo|
32+
name = enum_value.fetch("name")
33+
serialized = enum_value.fetch("serialized")
34+
memo[camel_to_snake(name)] = serialized
35+
end
2736

28-
catalog = {"keys" => keys, "structs" => {}}
37+
keys = keys.sort.to_h
38+
39+
groups = Hash.new { |h, k| h[k] = {sources: [], events: []} }
40+
41+
def collect_serialized(field)
42+
return [] unless field.is_a?(Hash)
43+
44+
values = []
45+
values << field["default_enum_serialized"]
46+
values << field["enum_value_serialized"]
47+
enum_values = field["enum_values_serialized"]
48+
values.concat(enum_values) if enum_values.is_a?(Array)
49+
50+
values.compact.map(&:to_s).uniq
51+
end
2952

3053
structs.each do |fq_name, info|
31-
name = info["name"] || fq_name.split("::").last
32-
fields = info["fields"] || {}
33-
s = {"name" => name}
34-
35-
# Fixed source if enum_single
36-
if fields["source"] && fields["source"]["type"] == "enum_single" && fields["source"]["enum_value"]
37-
src_name = fields["source"]["enum_value"]
38-
s["fixed_source"] = source_values[src_name] || src_name.downcase
39-
else
40-
s["fixed_source"] = nil
41-
end
54+
next unless fq_name.start_with?("LogStruct::Log::")
4255

43-
# Allowed events (serialized)
44-
allowed = []
45-
if fields["event"]
46-
ef = fields["event"]
47-
case ef["type"]
48-
when "enum_single"
49-
if ef["enum_value"]
50-
nm = ef["enum_value"]
51-
allowed << (event_values[nm] || nm.downcase)
52-
end
53-
when "enum_union"
54-
(ef["enum_values"] || []).each do |nm|
55-
allowed << (event_values[nm] || nm.downcase)
56-
end
57-
end
58-
end
59-
s["allowed_events"] = allowed.uniq
56+
fields = info["fields"]
57+
next unless fields.is_a?(Hash)
58+
59+
event_field = fields["event"]
60+
event_values = collect_serialized(event_field)
61+
next if event_values.empty?
62+
63+
log_type = fq_name.split("::")[2]
64+
next unless log_type
65+
66+
group = groups[log_type]
67+
group[:events] = (group[:events] | event_values)
68+
69+
source_field = fields["source"]
70+
source_values = collect_serialized(source_field)
71+
group[:sources] = (group[:sources] | source_values) if source_values.any?
72+
end
73+
74+
catalog_structs = groups.each_with_object({}) do |(log_type, data), memo|
75+
events = data[:events].uniq.sort
76+
next if events.empty?
77+
78+
sources = data[:sources].uniq
79+
fixed_source = (sources.size == 1) ? sources.first : nil
6080

61-
catalog["structs"][name] = s
81+
memo[log_type] = {
82+
"name" => log_type,
83+
"fixed_source" => fixed_source,
84+
"allowed_events" => events
85+
}
6286
end
6387

88+
catalog_structs = catalog_structs.sort.to_h
89+
90+
catalog = {"keys" => keys, "structs" => catalog_structs}
91+
6492
provider_dir = File.join(root, "terraform-provider-logstruct")
6593
data_dir = File.join(provider_dir, "pkg", "data")
6694
FileUtils.mkdir_p(data_dir)
6795

68-
# Always write JSON (useful for inspection)
6996
catalog_path = File.join(data_dir, "catalog.json")
7097
File.write(catalog_path, JSON.pretty_generate(catalog))
7198

72-
# Also generate a Go source file with embedded types and data for zero runtime parsing
7399
gen_path = File.join(data_dir, "catalog_gen.go")
74100

75101
def go_string(str)
76-
# Escape backslashes and quotes for Go string literals
77102
str.to_s.gsub("\\", "\\\\").gsub('"', '\\"')
78103
end
79104

@@ -83,19 +108,24 @@ def go_string(str)
83108
go << "type StructCatalog struct {\n\tName string\n\tFixedSource *string\n\tAllowedEvents []string\n}\n\n"
84109
go << "type Catalog struct {\n\tKeys map[string]string\n\tStructs map[string]StructCatalog\n}\n\n"
85110
go << "var CatalogData = Catalog{\n\tKeys: map[string]string{\n"
86-
keys.each do |k, v|
87-
go << "\t\t\"#{go_string(k)}\": \"#{go_string(v)}\",\n"
111+
keys.each do |key, value|
112+
go << "\t\t\"#{go_string(key)}\": \"#{go_string(value)}\",\n"
88113
end
89114
go << "\t},\n\tStructs: map[string]StructCatalog{\n"
90-
catalog["structs"].each do |name, s|
91-
go << "\t\t\"#{go_string(name)}\": {Name: \"#{go_string(s["name"])}\","
92-
go << if s["fixed_source"]
93-
" FixedSource: ptr(\"#{go_string(s["fixed_source"])}\"),"
115+
catalog_structs.each do |name, data|
116+
go << "\t\t\"#{go_string(name)}\": {Name: \"#{go_string(data["name"])}\","
117+
fixed_source = data["fixed_source"]
118+
fragment = if fixed_source
119+
" FixedSource: ptr(\"#{go_string(fixed_source)}\"),"
94120
else
95121
" FixedSource: nil,"
96122
end
123+
go << fragment
97124
go << " AllowedEvents: []string{"
98-
go << s["allowed_events"].map { |ev| "\"#{go_string(ev)}\"" }.join(", ")
125+
events = data["allowed_events"]
126+
if events.any?
127+
go << events.map { |event| "\"#{go_string(event)}\"" }.join(", ")
128+
end
99129
go << "}},\n"
100130
end
101131
go << "\t},\n}\n"

sorbet/rbi/gems/sorbet-typescript@0.1.0.rbi renamed to sorbet/rbi/gems/sorbet-typescript@0.1.1.rbi

Lines changed: 28 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)