Class: ProductTaxonomy::IntegrationVersion
- Inherits:
-
Object
- Object
- ProductTaxonomy::IntegrationVersion
- Defined in:
- lib/product_taxonomy/models/integration_version.rb
Overview
A single version of an integration, e.g. "shopify/2024-07".
Includes:
- The full names of categories in the integration's taxonomy.
- The mapping rules for converting between the integration's taxonomy and Shopify's taxonomy.
Constant Summary collapse
- INTEGRATIONS_PATH =
File.("integrations", ProductTaxonomy.data_path)
Instance Attribute Summary collapse
-
#from_shopify_mappings ⇒ Object
readonly
Returns the value of attribute from_shopify_mappings.
-
#full_names_by_id ⇒ Object
readonly
Returns the value of attribute full_names_by_id.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#to_shopify_mappings ⇒ Object
readonly
Returns the value of attribute to_shopify_mappings.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.clear_shopify_integrations_directory(output_path:, logger:) ⇒ Object
Clear the Shopify integrations directory before generating new files.
-
.generate_all_distributions(output_path:, logger:, current_shopify_version: nil, base_path: INTEGRATIONS_PATH) ⇒ Object
Generate all distribution files for all integration versions.
-
.generate_all_mappings_file(mappings:, current_shopify_version:, output_path:) ⇒ Object
Generate a JSON file containing all mappings for all integration versions.
-
.integrations_output_path(base_output_path) ⇒ String
Generate the path to the integrations output directory.
-
.load_all_from_source(current_shopify_version: nil, base_path: INTEGRATIONS_PATH) ⇒ Array<IntegrationVersion>
Load all integration versions from the source data directory.
-
.load_from_source(integration_path:, current_shopify_version: nil) ⇒ IntegrationVersion
Load an integration version from the provided source data directory.
-
.resolve_to_shopify_mappings_chain(versions) ⇒ Object
Resolve a set of IntegrationVersion to_shopify mappings so that each one maps to the latest version of the Shopify taxonomy.
-
.to_json(current_shopify_version:, mappings:) ⇒ Hash
Generate a JSON representation for a given set of mappings and version of the Shopify taxonomy.
Instance Method Summary collapse
-
#generate_distribution(output_path:, direction:) ⇒ Object
Generate JSON and TXT distribution files for a single direction of the integration version.
-
#generate_distributions(output_path:) ⇒ Object
Generate all distribution files for the integration version.
-
#initialize(name:, version:, full_names_by_id:, current_shopify_version: nil, from_shopify_mappings: nil, to_shopify_mappings: nil) ⇒ IntegrationVersion
constructor
A new instance of IntegrationVersion.
-
#resolve_to_shopify_mappings(next_integration_versions) ⇒ Object
Resolve the output categories of to_shopify mappings to the current version of the Shopify taxonomy, taking into any mappings from later versions.
-
#to_json(direction:) ⇒ Hash, ...
Generate a JSON representation of the integration version for a single direction.
-
#to_txt(direction:) ⇒ String
Generate a TXT representation of the integration version for a single direction.
-
#unmapped_external_category_ids ⇒ Array<String>
For a mapping to an external taxonomy, get the IDs of external categories that are not mapped from Shopify.
Constructor Details
#initialize(name:, version:, full_names_by_id:, current_shopify_version: nil, from_shopify_mappings: nil, to_shopify_mappings: nil) ⇒ IntegrationVersion
Returns a new instance of IntegrationVersion.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 147 def initialize( name:, version:, full_names_by_id:, current_shopify_version: nil, from_shopify_mappings: nil, to_shopify_mappings: nil ) @name = name @version = version @full_names_by_id = full_names_by_id @current_shopify_version = current_shopify_version @from_shopify_mappings = from_shopify_mappings @to_shopify_mappings = to_shopify_mappings @to_json = {} # memoized by direction end |
Instance Attribute Details
#from_shopify_mappings ⇒ Object (readonly)
Returns the value of attribute from_shopify_mappings.
137 138 139 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 137 def from_shopify_mappings @from_shopify_mappings end |
#full_names_by_id ⇒ Object (readonly)
Returns the value of attribute full_names_by_id.
137 138 139 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 137 def full_names_by_id @full_names_by_id end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
137 138 139 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 137 def name @name end |
#to_shopify_mappings ⇒ Object (readonly)
Returns the value of attribute to_shopify_mappings.
137 138 139 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 137 def to_shopify_mappings @to_shopify_mappings end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
137 138 139 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 137 def version @version end |
Class Method Details
.clear_shopify_integrations_directory(output_path:, logger:) ⇒ Object
Clear the Shopify integrations directory before generating new files.
35 36 37 38 39 40 41 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 35 def clear_shopify_integrations_directory(output_path:, logger:) shopify_integrations_path = File.join(integrations_output_path(output_path), "shopify") if Dir.exist?(shopify_integrations_path) FileUtils.rm_rf(shopify_integrations_path) FileUtils.mkdir_p(shopify_integrations_path) end end |
.generate_all_distributions(output_path:, logger:, current_shopify_version: nil, base_path: INTEGRATIONS_PATH) ⇒ Object
Generate all distribution files for all integration versions.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 19 def generate_all_distributions(output_path:, logger:, current_shopify_version: nil, base_path: INTEGRATIONS_PATH) clear_shopify_integrations_directory(output_path:, logger:) integration_versions = load_all_from_source(current_shopify_version:, base_path:) all_mappings = integration_versions.each_with_object([]) do |integration_version, all_mappings| logger.info("Generating integration mappings for #{integration_version.name}/#{integration_version.version}") integration_version.generate_distributions(output_path:) all_mappings.concat(integration_version.to_json(direction: :both)) end generate_all_mappings_file(mappings: all_mappings, current_shopify_version:, output_path:) end |
.generate_all_mappings_file(mappings:, current_shopify_version:, output_path:) ⇒ Object
Generate a JSON file containing all mappings for all integration versions.
109 110 111 112 113 114 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 109 def generate_all_mappings_file(mappings:, current_shopify_version:, output_path:) File.write( File.("all_mappings.json", integrations_output_path(output_path)), JSON.pretty_generate(to_json(mappings:, current_shopify_version:)) + "\n", ) end |
.integrations_output_path(base_output_path) ⇒ String
Generate the path to the integrations output directory.
132 133 134 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 132 def integrations_output_path(base_output_path) File.("en/integrations", base_output_path) end |
.load_all_from_source(current_shopify_version: nil, base_path: INTEGRATIONS_PATH) ⇒ Array<IntegrationVersion>
Load all integration versions from the source data directory.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 46 def load_all_from_source(current_shopify_version: nil, base_path: INTEGRATIONS_PATH) integrations_yaml = YAML.safe_load_file(File.("integrations.yml", base_path)) integrations_yaml.flat_map do |integration_yaml| versions = integration_yaml["available_versions"].sort.map do |version_path| load_from_source( integration_path: File.(version_path, base_path), current_shopify_version:, ) end resolve_to_shopify_mappings_chain(versions) if integration_yaml["name"] == "shopify" versions end end |
.load_from_source(integration_path:, current_shopify_version: nil) ⇒ IntegrationVersion
Load an integration version from the provided source data directory.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 77 def load_from_source(integration_path:, current_shopify_version: nil) full_names = YAML.safe_load_file(File.("full_names.yml", integration_path)) full_names_by_id = full_names.each_with_object({}) { |data, hash| hash[data["id"].to_s] = data } from_shopify_mappings = MappingRule.load_rules_from_source( integration_path:, direction: :from_shopify, full_names_by_id:, ) to_shopify_mappings = MappingRule.load_rules_from_source( integration_path:, direction: :to_shopify, full_names_by_id:, ) integration_pathname = Pathname.new(integration_path) new( name: integration_pathname.parent.basename.to_s, version: integration_pathname.basename.to_s, full_names_by_id:, from_shopify_mappings:, to_shopify_mappings:, current_shopify_version:, ) end |
.resolve_to_shopify_mappings_chain(versions) ⇒ Object
Resolve a set of IntegrationVersion to_shopify mappings so that each one maps to the latest version of the Shopify taxonomy.
66 67 68 69 70 71 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 66 def resolve_to_shopify_mappings_chain(versions) versions.reverse.each_with_object([]) do |version, resolved_versions| version.resolve_to_shopify_mappings(resolved_versions) resolved_versions.prepend(version) end end |
.to_json(current_shopify_version:, mappings:) ⇒ Hash
Generate a JSON representation for a given set of mappings and version of the Shopify taxonomy.
121 122 123 124 125 126 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 121 def to_json(current_shopify_version:, mappings:) { version: current_shopify_version, mappings:, } end |
Instance Method Details
#generate_distribution(output_path:, direction:) ⇒ Object
Generate JSON and TXT distribution files for a single direction of the integration version.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 176 def generate_distribution(output_path:, direction:) output_dir = File.(@name, self.class.integrations_output_path(output_path)) FileUtils.mkdir_p(output_dir) json = self.class.to_json(mappings: [to_json(direction:)], current_shopify_version: @current_shopify_version) File.write( File.("#{distribution_filename(direction:)}.json", output_dir), JSON.pretty_generate(json) + "\n", ) File.write( File.("#{distribution_filename(direction:)}.txt", output_dir), to_txt(direction:) + "\n", ) end |
#generate_distributions(output_path:) ⇒ Object
Generate all distribution files for the integration version.
167 168 169 170 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 167 def generate_distributions(output_path:) generate_distribution(output_path:, direction: :from_shopify) if @from_shopify_mappings.present? generate_distribution(output_path:, direction: :to_shopify) if @to_shopify_mappings.present? end |
#resolve_to_shopify_mappings(next_integration_versions) ⇒ Object
Resolve the output categories of to_shopify mappings to the current version of the Shopify taxonomy, taking into any mappings from later versions.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 196 def resolve_to_shopify_mappings(next_integration_versions) @to_shopify_mappings&.each do |mapping| newer_mapping = next_integration_versions.flat_map(&:to_shopify_mappings).compact.find do |mapping_rule| mapping_rule.input_category["id"] == mapping.output_category end mapping.output_category = newer_mapping&.output_category || Category.find_by(id: mapping.output_category) next unless mapping.output_category.nil? raise ArgumentError, "Failed to resolve Shopify mapping: " \ "\"#{mapping.input_category["id"]}\" to \"#{mapping.output_category}\" " \ "(input version: #{version})" end end |
#to_json(direction:) ⇒ Hash, ...
Generate a JSON representation of the integration version for a single direction.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 226 def to_json(direction:) if @to_json.key?(direction) @to_json[direction] elsif direction == :both [to_json(direction: :from_shopify), to_json(direction: :to_shopify)].compact else mappings = if direction == :from_shopify @from_shopify_mappings&.sort_by { _1.input_category.id_parts } else @to_shopify_mappings end @to_json[direction] = if mappings.present? { input_taxonomy: input_name_and_version(direction:), output_taxonomy: output_name_and_version(direction:), rules: mappings.map(&:to_json), } end end end |
#to_txt(direction:) ⇒ String
Generate a TXT representation of the integration version for a single direction.
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 252 def to_txt(direction:) mappings = direction == :from_shopify ? @from_shopify_mappings : @to_shopify_mappings header = <<~TXT # Shopify Product Taxonomy - Mapping #{input_name_and_version(direction:)} to #{output_name_and_version(direction:)} # Format: # → {base taxonomy category name} # ⇒ {mapped taxonomy category name} TXT visible_mappings = mappings.filter_map do |mapping| next if @name == "shopify" && direction == :to_shopify && mapping.input_txt_equals_output_txt? mapping.to_txt end header + visible_mappings.sort.join("\n").chomp end |
#unmapped_external_category_ids ⇒ Array<String>
For a mapping to an external taxonomy, get the IDs of external categories that are not mapped from Shopify.
215 216 217 218 219 220 |
# File 'lib/product_taxonomy/models/integration_version.rb', line 215 def unmapped_external_category_ids return [] if @from_shopify_mappings.blank? mappings_by_output_category_id = @from_shopify_mappings.index_by { _1.output_category["id"].to_s } @full_names_by_id.keys - mappings_by_output_category_id.keys end |