Created
December 24, 2025 01:13
-
-
Save Kerrick/0499439695e8f0ced21fb62a562ab87d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| # SPDX-FileCopyrightText: 2025 Kerrick Long <[email protected]> | |
| # SPDX-License-Identifier: MIT-0 | |
| # This rake task includes creative contributions from Gemini 3 Pro. | |
| # https://declare-ai.org/1.0.0/creative.html | |
| require "rubygems" | |
| # 1. The Value Object | |
| # It is not a Calculator; it is the SemVer itself. | |
| # It responds to 'next', returning a new SemVer. | |
| class SemVer | |
| SEGMENTS = [:major, :minor, :patch].freeze | |
| def initialize(version_string) | |
| @gem_version = Gem::Version.new(version_string) | |
| end | |
| def next(segment) | |
| index = SEGMENTS.index(segment) | |
| raise ArgumentError, "Invalid segment: #{segment}" unless index | |
| raw_segments = @gem_version.segments.fill(0, 3).first(3) | |
| raw_segments[index] += 1 | |
| raw_segments.fill(0, (index + 1)..2) | |
| SemVer.new(raw_segments.join(".")) | |
| end | |
| def to_s | |
| @gem_version.to_s | |
| end | |
| end | |
| # 2. The Manifest | |
| # Not an "Updater". This object REPRESENTS the file on the disk. | |
| # We don't "run" it. We write to it. | |
| class Manifest < Data.define(:path, :pattern, :template) | |
| def read | |
| File.read(path) | |
| end | |
| # The verb is 'write', specific to the object (a file). | |
| def write(version) | |
| return unless File.exist?(path) | |
| new_content = read.gsub(pattern, template % version) | |
| File.write(path, new_content) | |
| puts "Wrote #{version} to #{path}" | |
| end | |
| end | |
| # 3. The Lockfile | |
| # This represents the binary/complex state of the Cargo.lock. | |
| # It doesn't "update"; it "refreshes" or "synchronizes". | |
| class Lockfile | |
| PATH = "ext/ratatui_ruby/Cargo.lock" | |
| DIR = "ext/ratatui_ruby" | |
| def exists? | |
| File.exist?(PATH) | |
| end | |
| def refresh | |
| return unless exists? | |
| Dir.chdir(DIR) do | |
| # "system" is the verb here. | |
| system("cargo update -p ratatui_ruby --offline") | |
| end | |
| puts "Refreshed #{PATH}" | |
| end | |
| end | |
| # 4. The Aggregate Root: Project | |
| # The Project is the noun that holds the state. | |
| # It allows us to issue commands ("bump") or ask queries ("version"). | |
| class Project | |
| def initialize(manifests:, lockfile:) | |
| @manifests = manifests | |
| @lockfile = lockfile | |
| end | |
| # Query: Noun | |
| def version | |
| # The first manifest is the source of truth | |
| source = @manifests.first.read | |
| match = source.match(@manifests.first.pattern) | |
| raise "Version missing in manifest" unless match | |
| SemVer.new(match[1]) | |
| end | |
| # Command: Verb | |
| def bump(segment) | |
| target = version.next(segment) | |
| puts "Bumping #{segment}: #{version} -> #{target}" | |
| # We iterate over the nouns (manifests) and issue the verb (write) | |
| @manifests.each { |manifest| manifest.write(target) } | |
| # We command the lockfile to refresh | |
| @lockfile.refresh | |
| end | |
| end | |
| # --- Rake Task Integration --- | |
| namespace :bump do | |
| # Composition: The Project is made of these parts. | |
| project = Project.new( | |
| manifests: [ | |
| Manifest.new( | |
| path: "lib/ratatui_ruby/version.rb", | |
| pattern: /VERSION = "(.*)"/, | |
| template: 'VERSION = "%s"' | |
| ), | |
| Manifest.new( | |
| path: "ext/ratatui_ruby/Cargo.toml", | |
| pattern: /^version = "(.*)"/, | |
| template: 'version = "%s"' | |
| ) | |
| ], | |
| lockfile: Lockfile.new | |
| ) | |
| SemVer::SEGMENTS.each do |segment| | |
| desc "Bump #{segment} version" | |
| task segment do | |
| project.bump(segment) | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment