Skip to content

Commit

Permalink
Migrate generate_release command to new tool (#543)
Browse files Browse the repository at this point in the history
### TL;DR

Migrated `generate_release` command from old tool version. It takes ~40s to run for all locales on my machine.

### What changed?

- Added a new `GenerateReleaseCommand` that orchestrates the release process
- Introduced a new CLI command `release` with options for version and locales
- Enhanced error handling in the base Command class
- Added helper methods for version file path and locale detection
- Updated the distribution generation to use consistent version file paths

### How to test?
1. Run `product_taxonomy release --version=YYYY-MM`
2. Verify that:
   - Distribution files are generated
   - Documentation is updated
   - VERSION file contains the new version
   - Git tag is created
   - README badge is updated with the new version
3. Run with `--locales=all` to test multi-locale generation

Sample command output:
```
❯ bin/product_taxonomy release --version=2025-01 --locales=all
Generating release for version: 2025-01
Generating distribution files...
Version: 2025-01
Locales: bg-BG, cs, da, de, el, en, es, fi, fr, hr-HR, hu, id-ID, it, ja, ko, lt-LT, nb, nl, pl, pt-BR, pt-PT, ro-RO, ru, sk-SK, sl-SI, sv, th, tr, vi, zh-CN, zh-TW
Validating localizations
Generating files for bg-BG
Generating files for cs
Generating files for da
Generating files for de
Generating files for el
Generating files for en
Generating files for es
Generating files for fi
Generating files for fr
Generating files for hr-HR
Generating files for hu
Generating files for id-ID
Generating files for it
Generating files for ja
Generating files for ko
Generating files for lt-LT
Generating files for nb
Generating files for nl
Generating files for pl
Generating files for pt-BR
Generating files for pt-PT
Generating files for ro-RO
Generating files for ru
Generating files for sk-SK
Generating files for sl-SI
Generating files for sv
Generating files for th
Generating files for tr
Generating files for vi
Generating files for zh-CN
Generating files for zh-TW
Generating integration mappings for google/2021-09-21
Generating integration mappings for shopify/2022-02
Generating integration mappings for shopify/2024-07
Generating integration mappings for shopify/2024-10
Generating documentation files...
Version: 2025-01
Generating sibling groups...
Generating category search index...
Generating attributes...
Generating mappings...
Generating attributes with categories...
Generating attribute with categories search index...
Generating release folder...
Generating index.html...
Generating attributes.html...
Updating VERSION file...
Creating git tag...
Updating README.md...
Completed in 38.7 seconds
```
  • Loading branch information
danielpgross authored Jan 29, 2025
2 parents 16cf66d + efa01d4 commit 5756ade
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 1 deletion.
1 change: 1 addition & 0 deletions dev/lib/product_taxonomy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ def data_path = DATA_PATH
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"
require_relative "product_taxonomy/commands/generate_release_command"
7 changes: 7 additions & 0 deletions dev/lib/product_taxonomy/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,12 @@ def unmapped_external_categories(name_and_version)
def docs
GenerateDocsCommand.new(options).run
end

desc "release", "Generate a release"
option :version, type: :string, desc: "The version of the release to generate"
option :locales, type: :array, default: ["en"], desc: "The locales to generate"
def release
GenerateReleaseCommand.new(options).run
end
end
end
14 changes: 14 additions & 0 deletions dev/lib/product_taxonomy/commands/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ def run(...)
execute(...)
end
logger.info("Completed in #{elapsed.round(2)} seconds")
rescue => e
logger.error("\e[1;31mError:\e[0m #{e.message}")
exit(1)
end

def execute(...)
raise NotImplementedError, "#{self.class}#execute must be implemented"
end

def load_taxonomy
return if ProductTaxonomy::Category.all.any?

ProductTaxonomy::Value.load_from_source(YAML.load_file(File.expand_path(
"values.yml",
ProductTaxonomy.data_path,
Expand Down Expand Up @@ -54,5 +59,14 @@ def validate_and_sanitize_version!(version)

sanitized_version
end

def version_file_path
File.expand_path("../VERSION", ProductTaxonomy.data_path)
end

def locales_defined_in_data_path
glob = Dir.glob(File.expand_path("localizations/categories/*.yml", ProductTaxonomy.data_path))
glob.map { File.basename(_1, ".yml") }
end
end
end
2 changes: 1 addition & 1 deletion dev/lib/product_taxonomy/commands/generate_dist_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class GenerateDistCommand < Command
def initialize(options)
super

@version = options[:version] || File.read(File.expand_path("../../../../VERSION", __dir__)).strip
@version = options[:version] || File.read(version_file_path).strip
@locales = if options[:locales] == ["all"]
glob = Dir.glob(File.expand_path("localizations/categories/*.yml", ProductTaxonomy.data_path))
glob.map { File.basename(_1, ".yml") }
Expand Down
47 changes: 47 additions & 0 deletions dev/lib/product_taxonomy/commands/generate_release_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module ProductTaxonomy
class GenerateReleaseCommand < Command
def initialize(options)
super

@version = options[:version] || File.read(version_file_path).strip
@locales = if options[:locales] == ["all"]
locales_defined_in_data_path
else
options[:locales]
end
end

def execute
logger.info("Generating release for version: #{@version}")

logger.info("Generating distribution files...")
GenerateDistCommand.new(version: @version, locales: @locales).execute

logger.info("Generating documentation files...")
GenerateDocsCommand.new(version: @version, locales: @locales).execute

logger.info("Updating VERSION file...")
File.write(version_file_path, @version)

logger.info("Creating git tag...")
system("git", "tag", "v#{@version}")

logger.info("Updating README.md...")
update_readme
end

private

def update_readme
readme_path = File.expand_path("../dist/README.md", ProductTaxonomy.data_path)
content = File.read(readme_path)
content.gsub!(%r{badge/Version-.*?-blue\.svg}) do
badge_version = @version.gsub("-", "--")
"badge/Version-#{badge_version}-blue.svg"
end
File.write(readme_path, content)
end
end
end
77 changes: 77 additions & 0 deletions dev/test/commands/generate_release_command_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require "test_helper"
require "tmpdir"

module ProductTaxonomy
class GenerateReleaseCommandTest < TestCase
setup do
@tmp_base_path = Dir.mktmpdir
@version = "2024-01"
@version_file_path = File.expand_path("VERSION", @tmp_base_path)

# Create test files and directories
FileUtils.mkdir_p(File.expand_path("dist", @tmp_base_path))
File.write(@version_file_path, "2023-12")
File.write(
File.expand_path("dist/README.md", @tmp_base_path),
'<img src="https://img.shields.io/badge/Version-2023--12-blue.svg" alt="Version">',
)

# Stub dependencies
Command.any_instance.stubs(:version_file_path).returns(@version_file_path)
Command.any_instance.stubs(:load_taxonomy)
GenerateDistCommand.any_instance.stubs(:execute)
GenerateDocsCommand.any_instance.stubs(:execute)
ProductTaxonomy.stubs(:data_path).returns("#{@tmp_base_path}/data")
end

teardown do
FileUtils.remove_entry(@tmp_base_path)
end

test "initialize sets version from options if provided" do
command = GenerateReleaseCommand.new(version: @version)
assert_equal @version, command.instance_variable_get(:@version)
end

test "initialize reads version from file if not provided in options" do
command = GenerateReleaseCommand.new({})
assert_equal "2023-12", command.instance_variable_get(:@version)
end

test "initialize sets all locales when 'all' is specified" do
Command.any_instance.stubs(:locales_defined_in_data_path).returns(["en", "fr", "es"])
command = GenerateReleaseCommand.new(locales: ["all"])
assert_equal ["en", "fr", "es"], command.instance_variable_get(:@locales)
end

test "initialize sets specific locales when provided" do
command = GenerateReleaseCommand.new(locales: ["en", "fr"])
assert_equal ["en", "fr"], command.instance_variable_get(:@locales)
end

test "execute performs all required steps in order" do
command = GenerateReleaseCommand.new(version: @version, locales: ["en"])

# Set up expectations
GenerateDistCommand.any_instance.expects(:execute)
GenerateDocsCommand.any_instance.expects(:execute)
command.expects(:system).with("git", "tag", "v#{@version}")

command.execute

# Verify VERSION file was updated
assert_equal @version, File.read(@version_file_path)
end

test "execute updates README.md version badge" do
command = GenerateReleaseCommand.new(version: @version)

command.execute

readme_content = File.read(File.expand_path("dist/README.md", @tmp_base_path))
assert_equal '<img src="https://img.shields.io/badge/Version-2024--01-blue.svg" alt="Version">', readme_content
end
end
end

0 comments on commit 5756ade

Please sign in to comment.