Class: Inquirex::Tools::VersionBumper

Inherits:
Object
  • Object
show all
Defined in:
lib/inquirex/tools/version_bumper.rb

Overview

Moves every lockstep package to one version, then proves each one still builds — the write half of the pair whose read half is VersionChecker.

The family shares a serialization format, so a version that identifies one package identifies all of them. Bumping is therefore all-or-nothing: there is no supported way to move a single package.

Writing a version and verifying it are one command on purpose. A version written but never checked is the failure this is meant to prevent: the number says the family agrees while one package no longer passes its own suite.

Examples:

Move the family to 0.9.2 and check every package

Inquirex::Tools::VersionBumper.new.call("0.9.2")   # => false if any check fails

Constant Summary collapse

SEMVER_RE =

A version must be exactly MAJOR.MINOR.PATCH — no prereleases, because the npm packages and the gems would spell them differently.

/\A\d+\.\d+\.\d+\z/
ERROR =

Prefix for the refusal messages. This command's only feedback is what it prints, so the word carries weight.

"ERROR"
CHECK =

What each package is verified with. One recipe for gems and npm packages alike — every repo's justfile defines it, which is the point of having a justfile in each.

%w[just check-all].freeze
RULE =

Rule across the report, sized to the rows.

("" * 52).freeze
SYNC_STEPS =

Bringing a checkout level with origin/main before its suite runs, so a bump is verified against what is actually on main rather than whatever the local clone last saw.

[
  %w[fetch --tags origin],
  %w[rebase origin/main]
].freeze
DEFAULT_GIT =

Runs one git command, capturing stdout and stderr.

Capturing is the point. Left attached, a git run against a directory that is not a checkout writes "fatal: not a git repository" straight to the terminal — thirty such lines during the specs, which is noise the operator has to learn to ignore. The caller decides what is worth printing.

Returns:

  • (Array(Boolean, String))

    success, and the combined output

lambda { |dir, argv|
  output, status = Open3.capture2e("git", "-C", dir, *argv)
  [status.success?, output]
}
DEFAULT_RUNNER =

Runs a package's own checks in its own directory.

->(dir, argv) { Dir.chdir(dir) { system(*argv) } }

Instance Method Summary collapse

Constructor Details

#initialize(workspace: Workspace.new, out: $stdout, git: DEFAULT_GIT, runner: DEFAULT_RUNNER) ⇒ VersionBumper

Returns a new instance of VersionBumper.

Parameters:

  • workspace (Workspace) (defaults to: Workspace.new)

    the ecosystem checkout to rewrite

  • out (IO) (defaults to: $stdout)

    where report output goes

  • git (#call) (defaults to: DEFAULT_GIT)

    invoked with (dir, argv); returns [ok, output]. Injected so specs can assert what would run without touching a repo.

  • runner (#call) (defaults to: DEFAULT_RUNNER)

    invoked with (dir, argv) to run a package's checks. Injected for the same reason: a unit test must not shell out to six real suites.



73
74
75
76
77
78
# File 'lib/inquirex/tools/version_bumper.rb', line 73

def initialize(workspace: Workspace.new, out: $stdout, git: DEFAULT_GIT, runner: DEFAULT_RUNNER)
  @workspace = workspace
  @out = out
  @git = git
  @runner = runner
end

Instance Method Details

#call(version, verify: true) ⇒ Boolean

Rewrites every lockstep package to the target version, then runs each package's own just check-all.

Refuses to move backwards: a version already published cannot be reissued, so the target must be at least the highest current value.

Parameters:

  • version (String)

    target, MAJOR.MINOR.PATCH

  • verify (Boolean) (defaults to: true)

    run just check-all per package afterwards

Returns:

  • (Boolean)

    true when every package was written and checked



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/inquirex/tools/version_bumper.rb', line 89

def call(version, verify: true)
  return false unless valid?(version)

  out.puts "Setting all lockstep packages to #{version} 🚨:"
  each_package { |name, kind| write(name, kind, version) }
  return true unless verify

  out.puts
  out.puts "Verifying each package with `#{CHECK.join(" ")}`:"
  results = each_package { |name, _kind| check(name) }
  report(results)
end