Skip to content

Commit

Permalink
WIP: Resolve to_shopify mappings from intermediate versions to latest
Browse files Browse the repository at this point in the history
  • Loading branch information
danielpgross committed Jan 2, 2025
1 parent dc00ac3 commit 2add753
Show file tree
Hide file tree
Showing 23 changed files with 541 additions and 113 deletions.
43 changes: 39 additions & 4 deletions dev/lib/product_taxonomy/models/integration_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,32 @@ def generate_all_distributions(output_path:, logger:, current_shopify_version: n
#
# @return [Array<IntegrationVersion>]
def load_all_from_source(current_shopify_version: nil, base_path: INTEGRATIONS_PATH)
integrations = YAML.safe_load_file(File.expand_path("integrations.yml", base_path))
integrations.pluck("available_versions").flatten.map do |integration_version|
integration_path = File.expand_path(integration_version, base_path)
load_from_source(integration_path:, current_shopify_version:)
integrations_yaml = YAML.safe_load_file(File.expand_path("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.expand_path(version_path, base_path),
current_shopify_version:,
)
end

resolve_to_shopify_mappings_chain(versions) if integration_yaml["name"] == "shopify"

versions
end
end

# Resolve a set of IntegrationVersion to_shopify mappings so that each one maps to the latest version of the
# Shopify taxonomy.
#
# @param versions [Array<IntegrationVersion>] The versions to resolve, ordered from oldest to newest.
def resolve_to_shopify_mappings_chain(versions)
# Resolve newest version against current taxonomy
versions.last.resolve_to_shopify_mappings(nil)

# Resolve each older version against the one following it
versions.each_cons(2).reverse_each do |previous, next_version|
previous.resolve_to_shopify_mappings(next_version)
end
end

Expand Down Expand Up @@ -155,6 +177,19 @@ def generate_distribution(output_path:, direction:)
)
end

# Resolve the output categories of to_shopify mappings to the next version of the Shopify taxonomy.
#
# @param next_integration_version [IntegrationVersion | nil] The IntegrationVersion defining mappings to the next
# newer version of the Shopify taxonomy. If nil, the latest version of the Shopify taxonomy is used.
def resolve_to_shopify_mappings(next_integration_version)
@to_shopify_mappings.each do |mapping|
newer_mapping = next_integration_version&.to_shopify_mappings&.find do
_1.input_category["id"] == mapping.output_category
end
mapping.output_category = newer_mapping&.output_category || Category.find_by(id: mapping.output_category)
end
end

# For a mapping to an external taxonomy, get the IDs of external categories that are not mapped from Shopify.
#
# @return [Array<String>] IDs of external categories not mapped from the Shopify taxonomy. Empty if there are no
Expand Down
16 changes: 12 additions & 4 deletions dev/lib/product_taxonomy/models/mapping_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ def load_rules_from_source(integration_path:, direction:, full_names_by_id:)

is_to_shopify = direction == :to_shopify
input_category = is_to_shopify ? full_names_by_id[input_id] : Category.find_by(id: input_id)
output_category = is_to_shopify ? Category.find_by(id: output_id) : full_names_by_id[output_id]
# We set output_category to be the raw output ID if is_to_shopify is true, with an expectation that it will
# be resolved to a `Category` before the rule is serialized to JSON or TXT.
# See `IntegrationVersion#resolve_to_shopify_mappings`.
output_category = is_to_shopify ? output_id : full_names_by_id[output_id]

raise ArgumentError, "Input category not found for mapping rule: #{rule}" unless input_category
raise ArgumentError, "Output category not found for mapping rule: #{rule}" unless output_category
Expand All @@ -41,7 +44,8 @@ def load_rules_from_source(integration_path:, direction:, full_names_by_id:)
end
end

attr_reader :input_category, :output_category
attr_reader :input_category
attr_accessor :output_category

def initialize(input_category:, output_category:)
@input_category = input_category
Expand Down Expand Up @@ -87,19 +91,23 @@ def category_json(category)
id: category["id"].to_s,
full_name: category["full_name"],
}
else
elsif category.is_a?(Category)
{
id: category.gid,
full_name: category.full_name,
}
else
raise ArgumentError, "Mapping rule category not resolved. Raw value: #{category}"
end
end

def category_txt(category)
if category.is_a?(Hash)
category["full_name"]
else
elsif category.is_a?(Category)
category.full_name
else
raise ArgumentError, "Mapping rule category not resolved. Raw value: #{category}"
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- id: 1
full_name: Animals & Pet Supplies (foocommerce)
full_name: Apparel & Accessories (foocommerce)
- id: 2
full_name: Animals & Pet Supplies > Live Animals (foocommerce)
full_name: Apparel & Accessories > Clothing (foocommerce)
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
rules:
- input:
product_category_id: ap
product_category_id: aa
output:
product_category_id:
- '1'
- input:
product_category_id: ap-1
product_category_id: aa-1
output:
product_category_id:
- '2'
2 changes: 2 additions & 0 deletions dev/test/fixtures/data/integrations/integrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
- name: shopify
available_versions:
- shopify/2020-01
- shopify/2021-01
- shopify/2022-01
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- id: 1
full_name: Animals & Pet Supplies (old shopify)
full_name: Apparel & Accessories (2020-01)
- id: 2
full_name: Animals & Pet Supplies > Live Animals (old shopify)
full_name: Apparel & Accessories > Clothing (2020-01)
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
input_taxonomy: shopify/2020-01
output_taxonomy: shopify/2021-01
rules:
- input:
product_category_id: 1
output:
product_category_id:
- ap
- aa
- input:
product_category_id: 2
output:
product_category_id:
- ap-1
- aa-1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- id: aa-1
full_name: Apparel & Accessories > Clothing (2021-01)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
input_taxonomy: shopify/2021-01
output_taxonomy: shopify/2022-01
rules:
- input:
product_category_id: aa-1
output:
product_category_id:
- aa-2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- id: aa-2
full_name: Apparel & Accessories > Clothing Accessories (2022-01)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
input_taxonomy: shopify/2022-01
output_taxonomy: shopify/2025-01-unstable
rules:
- input:
product_category_id: aa-2
output:
product_category_id:
- aa-3
125 changes: 125 additions & 0 deletions dev/test/fixtures/dist/en/integrations/all_mappings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"version": "2025-01-unstable",
"mappings": [
{
"input_taxonomy": "shopify/2025-01-unstable",
"output_taxonomy": "foocommerce/1.0.0",
"rules": [
{
"input": {
"category": {
"id": "gid://shopify/TaxonomyCategory/aa",
"full_name": "Apparel & Accessories"
}
},
"output": {
"category": [
{
"id": "1",
"full_name": "Apparel & Accessories (foocommerce)"
}
]
}
},
{
"input": {
"category": {
"id": "gid://shopify/TaxonomyCategory/aa-1",
"full_name": "Apparel & Accessories > Clothing"
}
},
"output": {
"category": [
{
"id": "2",
"full_name": "Apparel & Accessories > Clothing (foocommerce)"
}
]
}
}
]
},
{
"input_taxonomy": "shopify/2020-01",
"output_taxonomy": "shopify/2025-01-unstable",
"rules": [
{
"input": {
"category": {
"id": "1",
"full_name": "Apparel & Accessories (2020-01)"
}
},
"output": {
"category": [
{
"id": "gid://shopify/TaxonomyCategory/aa",
"full_name": "Apparel & Accessories"
}
]
}
},
{
"input": {
"category": {
"id": "2",
"full_name": "Apparel & Accessories > Clothing (2020-01)"
}
},
"output": {
"category": [
{
"id": "gid://shopify/TaxonomyCategory/aa-3",
"full_name": "Apparel & Accessories > Costumes & Accessories"
}
]
}
}
]
},
{
"input_taxonomy": "shopify/2021-01",
"output_taxonomy": "shopify/2025-01-unstable",
"rules": [
{
"input": {
"category": {
"id": "aa-1",
"full_name": "Apparel & Accessories > Clothing (2021-01)"
}
},
"output": {
"category": [
{
"id": "gid://shopify/TaxonomyCategory/aa-3",
"full_name": "Apparel & Accessories > Costumes & Accessories"
}
]
}
}
]
},
{
"input_taxonomy": "shopify/2022-01",
"output_taxonomy": "shopify/2025-01-unstable",
"rules": [
{
"input": {
"category": {
"id": "aa-2",
"full_name": "Apparel & Accessories > Clothing Accessories (2022-01)"
}
},
"output": {
"category": [
{
"id": "gid://shopify/TaxonomyCategory/aa-3",
"full_name": "Apparel & Accessories > Costumes & Accessories"
}
]
}
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "2025-01-unstable",
"mappings": [
{
"input_taxonomy": "shopify/2025-01-unstable",
"output_taxonomy": "foocommerce/1.0.0",
"rules": [
{
"input": {
"category": {
"id": "gid://shopify/TaxonomyCategory/aa",
"full_name": "Apparel & Accessories"
}
},
"output": {
"category": [
{
"id": "1",
"full_name": "Apparel & Accessories (foocommerce)"
}
]
}
},
{
"input": {
"category": {
"id": "gid://shopify/TaxonomyCategory/aa-1",
"full_name": "Apparel & Accessories > Clothing"
}
},
"output": {
"category": [
{
"id": "2",
"full_name": "Apparel & Accessories > Clothing (foocommerce)"
}
]
}
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Shopify Product Taxonomy - Mapping shopify/2025-01-unstable to foocommerce/1.0.0
# Format:
# → {base taxonomy category name}
# ⇒ {mapped taxonomy category name}

→ Apparel & Accessories
⇒ Apparel & Accessories (foocommerce)

→ Apparel & Accessories > Clothing
⇒ Apparel & Accessories > Clothing (foocommerce)
Loading

0 comments on commit 2add753

Please sign in to comment.