From ad61fe26710bf1156423752b653057c678cd2c59 Mon Sep 17 00:00:00 2001 From: Daniel Gross Date: Wed, 22 Jan 2025 17:29:08 -0500 Subject: [PATCH] WIP: Migrate `generate_docs` command to new tool --- dev/lib/product_taxonomy.rb | 3 + dev/lib/product_taxonomy/cli.rb | 6 ++ .../commands/generate_docs_command.rb | 89 +++++++++++++++++++ .../attribute_docs_all_serializer.rb | 19 ++++ .../attribute_docs_reversed_serializer.rb | 19 ++++ .../attribute_docs_search_serializer.rb | 19 ++++ .../category_docs_search_serializer.rb | 33 +++++++ .../category_docs_siblings_serializer.rb | 37 ++++++++ 8 files changed, 225 insertions(+) create mode 100644 dev/lib/product_taxonomy/commands/generate_docs_command.rb create mode 100644 dev/lib/product_taxonomy/models/serializers/attribute_docs_all_serializer.rb create mode 100644 dev/lib/product_taxonomy/models/serializers/attribute_docs_reversed_serializer.rb create mode 100644 dev/lib/product_taxonomy/models/serializers/attribute_docs_search_serializer.rb create mode 100644 dev/lib/product_taxonomy/models/serializers/category_docs_search_serializer.rb create mode 100644 dev/lib/product_taxonomy/models/serializers/category_docs_siblings_serializer.rb diff --git a/dev/lib/product_taxonomy.rb b/dev/lib/product_taxonomy.rb index bfb4d4be1..a8e9fc9b1 100644 --- a/dev/lib/product_taxonomy.rb +++ b/dev/lib/product_taxonomy.rb @@ -19,6 +19,9 @@ module ProductTaxonomy require_relative "product_taxonomy/models/taxonomy" require_relative "product_taxonomy/models/mapping_rule" require_relative "product_taxonomy/models/integration_version" +require_relative "product_taxonomy/models/serializers/category_docs_siblings_serializer" +require_relative "product_taxonomy/models/serializers/category_docs_search_serializer" require_relative "product_taxonomy/commands/command" require_relative "product_taxonomy/commands/generate_dist_command" require_relative "product_taxonomy/commands/find_unmapped_external_categories_command" +require_relative "product_taxonomy/commands/generate_docs_command" diff --git a/dev/lib/product_taxonomy/cli.rb b/dev/lib/product_taxonomy/cli.rb index a35070f96..221c0156a 100644 --- a/dev/lib/product_taxonomy/cli.rb +++ b/dev/lib/product_taxonomy/cli.rb @@ -26,5 +26,11 @@ def dist def unmapped_external_categories(name_and_version) FindUnmappedExternalCategoriesCommand.new(options).run(name_and_version) end + + desc "docs", "Generate documentation files" + option :version, type: :string, desc: "The version of the documentation to generate" + def docs + GenerateDocsCommand.new(options).run + end end end diff --git a/dev/lib/product_taxonomy/commands/generate_docs_command.rb b/dev/lib/product_taxonomy/commands/generate_docs_command.rb new file mode 100644 index 000000000..f7f1de3be --- /dev/null +++ b/dev/lib/product_taxonomy/commands/generate_docs_command.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module ProductTaxonomy + class GenerateDocsCommand < Command + UNSTABLE = "unstable" + + def initialize(options) + super + + @version = options[:version] || UNSTABLE + end + + def execute + logger.info("Version: #{@version}") + + load_taxonomy + generate_data_files + # generate_release_folder unless params[:version] == UNSTABLE + end + + private + + def generate_data_files + data_target = File.expand_path("../docs/_data/#{@version}", DATA_PATH) + + logger.info("Generating sibling groups...") + sibling_groups_yaml = YAML.dump(Serializers::CategoryDocsSiblingsSerializer.serialize_all, line_width: -1) + File.write("#{data_target}/sibling_groups.yml", sibling_groups_yaml + "\n") + + logger.info("Generating category search index...") + search_index_json = JSON.fast_generate(Serializers::CategoryDocsSearchSerializer.serialize_all) + File.write("#{data_target}/search_index.json", search_index_json + "\n") + + # logger.info("Generating attributes...") + # attributes_yml = YAML.dump(AttributeDocsAllSerializer.serialize_all, line_width: -1) + # File.write("#{data_target}/attributes.yml", attributes_yml + "\n") + + # logger.info("Generating mappings...") + # mappings_json = JSON.parse(File.read("dist/en/integrations/all_mappings.json")).fetch("mappings") + # mappings_data = reverse_shopify_mapping_rules(mappings_json) + # mappings_yml = YAML.dump(mappings_data, line_width: -1) + # File.write("#{data_target}/mappings.yml", mappings_yml + "\n") + + # logger.info("Generating attributes with categories...") + # reversed_attributes_yml = YAML.dump(AttributeDocsReversedSerializer.serialize_all, line_width: -1) + # File.write("#{data_target}/reversed_attributes.yml", reversed_attributes_yml + "\n") + + # logger.info("Generating attribute with categories search index...") + # attribute_search_index_json = JSON.fast_generate(AttributeDocsSearchSerializer.serialize_all) + # File.write("#{data_target}/attribute_search_index.json", attribute_search_index_json + "\n") + end + + def generate_release_folder + spinner("Generating release folder") do |sp| + sys.write_file("docs/_releases/#{params[:version]}/index.html") do |file| + content = sys.read_file("docs/_releases/_index_template.html") + content.gsub!("TITLE", params[:version].upcase) + content.gsub!("TARGET", params[:version]) + content.gsub!("GH_URL", "https://github.com/Shopify/product-taxonomy/releases/tag/v#{params[:version]}") + file.write(content) + end + sys.write_file("docs/_releases/#{params[:version]}/attributes.html") do |file| + content = sys.read_file("docs/_releases/_attributes_template.html") + content.gsub!("TITLE", params[:version].upcase) + content.gsub!("TARGET", params[:version]) + content.gsub!("GH_URL", "https://github.com/Shopify/product-taxonomy/releases/tag/v#{params[:version]}") + file.write(content) + end + sp.update_title("Generated release folder") + end + end + + def reverse_shopify_mapping_rules(mappings) + mappings.each do |mapping| + next unless mapping["output_taxonomy"].include?("shopify") + + mapping["input_taxonomy"], mapping["output_taxonomy"] = mapping["output_taxonomy"], mapping["input_taxonomy"] + mapping["rules"] = mapping["rules"].flat_map do |rule| + rule["output"]["category"].map do |output_category| + { + "input" => { "category" => output_category }, + "output" => { "category" => [rule["input"]["category"]] }, + } + end + end + end + end + end +end diff --git a/dev/lib/product_taxonomy/models/serializers/attribute_docs_all_serializer.rb b/dev/lib/product_taxonomy/models/serializers/attribute_docs_all_serializer.rb new file mode 100644 index 000000000..865792b54 --- /dev/null +++ b/dev/lib/product_taxonomy/models/serializers/attribute_docs_all_serializer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ProductTaxonomy + module Serializers + class AttributeDocsAllSerializer + class << self + def serialize_all + end + end + + def initialize(attribute) + @attribute = attribute + end + + def serialize + end + end + end +end diff --git a/dev/lib/product_taxonomy/models/serializers/attribute_docs_reversed_serializer.rb b/dev/lib/product_taxonomy/models/serializers/attribute_docs_reversed_serializer.rb new file mode 100644 index 000000000..a568b2a9d --- /dev/null +++ b/dev/lib/product_taxonomy/models/serializers/attribute_docs_reversed_serializer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ProductTaxonomy + module Serializers + class AttributeDocsReversedSerializer + class << self + def serialize_all + end + end + + def initialize(attribute) + @attribute = attribute + end + + def serialize + end + end + end +end diff --git a/dev/lib/product_taxonomy/models/serializers/attribute_docs_search_serializer.rb b/dev/lib/product_taxonomy/models/serializers/attribute_docs_search_serializer.rb new file mode 100644 index 000000000..8cc9d934f --- /dev/null +++ b/dev/lib/product_taxonomy/models/serializers/attribute_docs_search_serializer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ProductTaxonomy + module Serializers + class AttributeDocsSearchSerializer + class << self + def serialize_all + end + end + + def initialize(attribute) + @attribute = attribute + end + + def serialize + end + end + end +end diff --git a/dev/lib/product_taxonomy/models/serializers/category_docs_search_serializer.rb b/dev/lib/product_taxonomy/models/serializers/category_docs_search_serializer.rb new file mode 100644 index 000000000..1e4ff87bb --- /dev/null +++ b/dev/lib/product_taxonomy/models/serializers/category_docs_search_serializer.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module ProductTaxonomy + module Serializers + class CategoryDocsSearchSerializer + class << self + def serialize_all + Category.verticals.flat_map(&:descendants_and_self).flat_map do |category| + new(category).serialize + end + end + end + + def initialize(category) + @category = category + end + + def serialize + { + "searchIdentifier" => @category.id, + "title" => @category.full_name, + "url" => "?categoryId=#{CGI.escapeURIComponent(@category.id)}", + "category" => { + "id" => @category.id, + "name" => @category.name, + "fully_qualified_type" => @category.full_name, + "depth" => @category.level, + }, + } + end + end + end +end diff --git a/dev/lib/product_taxonomy/models/serializers/category_docs_siblings_serializer.rb b/dev/lib/product_taxonomy/models/serializers/category_docs_siblings_serializer.rb new file mode 100644 index 000000000..52beaed10 --- /dev/null +++ b/dev/lib/product_taxonomy/models/serializers/category_docs_siblings_serializer.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module ProductTaxonomy + module Serializers + class CategoryDocsSiblingsSerializer + class << self + def serialize_all + Category.verticals.flat_map(&:descendants_and_self).each_with_object({}) do |category, groups| + parent_id = category.parent&.gid.presence || "root" + sibling = new(category).serialize + + groups[category.level] ||= {} + groups[category.level][parent_id] ||= [] + groups[category.level][parent_id] << sibling + end + end + end + + def initialize(category) + @category = category + end + + def serialize + { + "id" => @category.gid, + "name" => @category.name, + "fully_qualified_type" => @category.full_name, + "depth" => @category.level, + "parent_id" => @category.parent&.gid.presence || "root", + "node_type" => @category.level.zero? ? "root" : "leaf", + "ancestor_ids" => @category.ancestors.map { _1.gid }.join(","), + "attribute_handles" => @category.attributes.map { _1.handle }.join(","), + } + end + end + end +end