manifold-cli 0.1.0 → 0.2.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: 72cd86649418feb395a957902e3e966e3df9fdc2931729beeb6719b0a98e831b
4
- data.tar.gz: 399938be40f27388f0d9c742b922d5ab5909cc132e76c9f0a793e89ed2f4277b
3
+ metadata.gz: c51fac99031686a4856753b93cd64ad3de0b6c304aefaa6f4c7b40db19c03b30
4
+ data.tar.gz: 907654d8f6f18061dd26d5a47299f541aefbb36657c5ef6267d041a581c53430
5
5
  SHA512:
6
- metadata.gz: a6b9919146b5e9cce7e32b423cc9119c6371a95fa5b4733d72ac217c23fc91ba95f95c472225afbb577a5bc8a359c01f26cbe2dcbc705b9792f402bcb88d6d0a
7
- data.tar.gz: 691783ca633a17ae13f0488fcd69c64521dae189cbc139d1f37a011fb65dd2d1c9fadfc43903d998b82acbbb61d52c94336962229f3b69739d5050b9e1dc51be
6
+ metadata.gz: ceb3039ef12f726c2c8c95ddb9378b945fb37ee1249040a75c910a9bb6a165534d47913e42508e1c5ba150187f514473de7aa0e2113f3e5e359f5661241bf3b8
7
+ data.tar.gz: de3a2ef465a7f7ed31f8e8a26972b42baed631c70b9fe877ce23033eda95b8c4f1dd0c5238a4113e8d09c4e760e6a8d1b9dbe979bcabd5df059075f9fec6efc0
@@ -57,18 +57,28 @@ module Manifold
57
57
  def write_metrics_schemas(tables_directory)
58
58
  return unless @manifold_yaml["metrics"]
59
59
 
60
- # Create metrics subdirectory
60
+ create_metrics_directory(tables_directory)
61
+ write_individual_metrics_schemas(tables_directory)
62
+ end
63
+
64
+ def create_metrics_directory(tables_directory)
61
65
  metrics_directory = tables_directory.join("metrics")
62
66
  metrics_directory.mkpath
67
+ end
63
68
 
69
+ def write_individual_metrics_schemas(tables_directory)
64
70
  @manifold_yaml["metrics"].each do |group_name, group_config|
65
- metrics_table_path = metrics_directory.join("#{group_name}.json")
66
- metrics_table_schema = metrics_table_schema(group_name, group_config)
67
- metrics_table_path.write(JSON.pretty_generate(metrics_table_schema).concat("\n"))
68
- @logger.info("Generated metrics table schema for '#{group_name}'.")
71
+ write_metrics_group_schema(tables_directory, group_name, group_config)
69
72
  end
70
73
  end
71
74
 
75
+ def write_metrics_group_schema(tables_directory, group_name, group_config)
76
+ metrics_table_path = tables_directory.join("metrics", "#{group_name}.json")
77
+ metrics_table_schema = metrics_table_schema(group_name, group_config)
78
+ metrics_table_path.write(JSON.pretty_generate(metrics_table_schema).concat("\n"))
79
+ @logger.info("Generated metrics table schema for '#{group_name}'.")
80
+ end
81
+
72
82
  def metrics_table_schema(group_name, group_config)
73
83
  [
74
84
  { "type" => "STRING", "name" => "id", "mode" => "REQUIRED" },
@@ -116,16 +126,121 @@ module Manifold
116
126
  end
117
127
 
118
128
  def group_metrics_fields(group_config)
119
- return [] unless group_config["breakouts"] && group_config["aggregations"]
129
+ return [] unless group_config["aggregations"]
120
130
 
121
- group_config["breakouts"].map do |breakout_name, _breakout_config|
122
- {
123
- "name" => breakout_name,
124
- "type" => "RECORD",
125
- "mode" => "NULLABLE",
126
- "fields" => breakout_metrics_fields(group_config)
127
- }
131
+ # Generate condition fields
132
+ condition_fields = generate_condition_fields(get_conditions_list(group_config), group_config)
133
+
134
+ # Generate intersection fields between breakout groups
135
+ intersection_fields = generate_breakout_intersection_fields(group_config)
136
+
137
+ condition_fields + intersection_fields
138
+ end
139
+
140
+ def get_conditions_list(group_config)
141
+ return [] unless group_config["conditions"]
142
+
143
+ group_config["conditions"].keys
144
+ end
145
+
146
+ def create_metric_field(field_name, group_config)
147
+ {
148
+ "name" => field_name,
149
+ "type" => "RECORD",
150
+ "mode" => "NULLABLE",
151
+ "fields" => breakout_metrics_fields(group_config)
152
+ }
153
+ end
154
+
155
+ def generate_condition_fields(conditions, group_config)
156
+ conditions.map do |condition_name|
157
+ create_metric_field(condition_name, group_config)
158
+ end
159
+ end
160
+
161
+ def generate_breakout_intersection_fields(group_config)
162
+ return [] unless group_config["breakouts"]
163
+ return [] if group_config["breakouts"].keys.size <= 1
164
+
165
+ generate_all_breakout_combinations(group_config)
166
+ end
167
+
168
+ def generate_all_breakout_combinations(group_config)
169
+ all_intersection_fields = []
170
+ breakout_groups = group_config["breakouts"].keys
171
+
172
+ # Generate combinations of different sizes (2 to n breakout groups)
173
+ (2..breakout_groups.size).each do |combination_size|
174
+ add_combinations_of_size(combination_size, breakout_groups, group_config, all_intersection_fields)
175
+ end
176
+
177
+ all_intersection_fields
178
+ end
179
+
180
+ def add_combinations_of_size(size, breakout_groups, group_config, all_fields)
181
+ breakout_groups.combination(size).each do |breakout_combination|
182
+ fields = generate_intersection_fields_for_combination(group_config, breakout_combination)
183
+ all_fields.concat(fields)
184
+ end
185
+ end
186
+
187
+ def generate_intersection_fields_for_combination(group_config, breakout_combination)
188
+ # Get all conditions from the given breakout groups
189
+ condition_sets = breakout_combination.map do |breakout_group|
190
+ group_config["breakouts"][breakout_group]
191
+ end
192
+
193
+ # Generate all combinations of one condition from each breakout group
194
+ generate_all_condition_combinations(condition_sets, group_config)
195
+ end
196
+
197
+ def generate_all_condition_combinations(condition_sets, group_config)
198
+ # Start with first breakout group's conditions
199
+ combinations = condition_sets.first.map { |condition| [condition] }
200
+
201
+ # Extend combinations with remaining breakout groups
202
+ extended_combinations = extend_combinations_with_remaining_sets(combinations, condition_sets[1..])
203
+
204
+ # Convert combinations to field definitions
205
+ create_intersection_fields(extended_combinations, group_config)
206
+ end
207
+
208
+ def extend_combinations_with_remaining_sets(initial_combinations, remaining_sets)
209
+ combinations = initial_combinations
210
+
211
+ remaining_sets.each do |conditions|
212
+ combinations = extend_combinations_with_conditions(combinations, conditions)
213
+ end
214
+
215
+ combinations
216
+ end
217
+
218
+ def extend_combinations_with_conditions(existing_combinations, conditions)
219
+ new_combinations = []
220
+
221
+ existing_combinations.each do |existing_combination|
222
+ conditions.each do |condition|
223
+ new_combinations << (existing_combination + [condition])
224
+ end
225
+ end
226
+
227
+ new_combinations
228
+ end
229
+
230
+ def create_intersection_fields(combinations, group_config)
231
+ combinations.map do |condition_combination|
232
+ # Format name with first condition lowercase, others capitalized
233
+ field_name = format_intersection_name(condition_combination)
234
+ create_metric_field(field_name, group_config)
235
+ end
236
+ end
237
+
238
+ def format_intersection_name(condition_combination)
239
+ name = condition_combination.first
240
+ condition_combination[1..].each do |condition|
241
+ name += condition.capitalize
128
242
  end
243
+ name
129
244
  end
130
245
 
131
246
  def breakout_metrics_fields(group_config)
@@ -4,7 +4,7 @@ module Manifold
4
4
  module Services
5
5
  # Handles the loading of vector schemas from configuration files
6
6
  class VectorService
7
- def initialize(logger)
7
+ def initialize(logger = nil)
8
8
  @logger = logger
9
9
  end
10
10
 
@@ -14,9 +14,22 @@ timestamp:
14
14
 
15
15
  metrics:
16
16
  renders:
17
+ conditions:
18
+ mobile: IS_DESKTOP(context.device)
19
+ desktop: IS_MOBILE(context.device)
20
+ us: context.geo.country = 'US'
21
+ global: context.geo.country != 'US'
22
+
17
23
  breakouts:
18
- paid: IS_PAID(context.location)
19
- organic: IS_ORGANIC(context.location)
24
+ device:
25
+ - mobile
26
+ - desktop
27
+ acquisition:
28
+ - organic
29
+ - paid
30
+ region:
31
+ - us
32
+ - global
20
33
 
21
34
  aggregations:
22
35
  countif: renderCount
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Manifold
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manifold-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - claytongentry
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-11 00:00:00.000000000 Z
10
+ date: 2025-03-31 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: thor