Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions Library/Homebrew/dev-cmd/bump-compatibility-version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# typed: strict
# frozen_string_literal: true

require "abstract_command"
require "formula"

module Homebrew
module DevCmd
class BumpCompatibilityVersion < AbstractCommand
cmd_args do
description <<~EOS
Create a commit to increment the compatibility_version of <formula>. If no
compatibility_version is present, "compatibility_version 1" will be added.
EOS
switch "-n", "--dry-run",
description: "Print what would be done rather than doing it."
switch "--write-only",
description: "Make the expected file modifications without taking any Git actions."
flag "--message=",
description: "Append <message> to the default commit message."

conflicts "--dry-run", "--write-only"

named_args :formula, min: 1, without_api: true
end

sig { override.void }
def run
# As this command is simplifying user-run commands then let's just use a
# user path, too.
ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s

Homebrew.install_bundler_gems!(groups: ["ast"]) unless args.dry_run?

args.named.to_formulae.each do |formula|
current_compatibility_version = formula.compatibility_version || 0
new_compatibility_version = current_compatibility_version + 1

if args.dry_run?
unless args.quiet?
old_text = "compatibility_version #{current_compatibility_version}"
new_text = "compatibility_version #{new_compatibility_version}"
if formula.compatibility_version.nil?
ohai "add #{new_text.inspect}"
else
ohai "replace #{old_text.inspect} with #{new_text.inspect}"
end
end
else
require "utils/ast"

formula_ast = Utils::AST::FormulaAST.new(formula.path.read)
if formula.compatibility_version.nil?
formula_ast.add_stanza(:compatibility_version, new_compatibility_version)
else
formula_ast.replace_stanza(:compatibility_version, new_compatibility_version)
end
formula.path.atomic_write(formula_ast.process)
end

message = "#{formula.name}: compatibility_version bump #{args.message}"
if args.dry_run?
ohai "git commit --no-edit --verbose --message=#{message} -- #{formula.path}"
elsif !args.write_only?
formula.path.parent.cd do
safe_system "git", "commit", "--no-edit", "--verbose",
"--message=#{message}", "--", formula.path
end
end
end
end
end
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions Library/Homebrew/test/dev-cmd/bump-compatibility-version_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# typed: true
# frozen_string_literal: true

require "cmd/shared_examples/args_parse"
require "dev-cmd/bump-compatibility-version"

RSpec.describe Homebrew::DevCmd::BumpCompatibilityVersion do
it_behaves_like "parseable arguments"

describe "#run" do
before do
allow(Homebrew).to receive(:install_bundler_gems!)
end

it "adds compatibility_version 1 with --write-only" do
formula_path = mktmpdir/"foo.rb"
formula_path.write <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0"
end
RUBY
formula = formula("foo", path: formula_path) do
T.bind(self, T.class_of(Formula))
url "https://brew.sh/foo-1.0"
end
command = described_class.new(["--write-only", "foo"])
allow(command.args.named).to receive(:to_formulae).and_return([formula])

command.run

expect(formula_path.read).to include " compatibility_version 1\n"
end

it "increments compatibility_version with --write-only" do
formula_path = mktmpdir/"foo.rb"
formula_path.write <<~RUBY
class Foo < Formula
url "https://brew.sh/foo-1.0"
compatibility_version 2
end
RUBY
formula = formula("foo", path: formula_path) do
T.bind(self, T.class_of(Formula))
url "https://brew.sh/foo-1.0"
compatibility_version 2
end
command = described_class.new(["--write-only", "foo"])
allow(command.args.named).to receive(:to_formulae).and_return([formula])

command.run

expect(formula_path.read).to include " compatibility_version 3\n"
end
end
end
21 changes: 21 additions & 0 deletions completions/bash/brew
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,26 @@ _brew_bump_cask_pr() {
__brew_complete_casks
}

_brew_bump_compatibility_version() {
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${cur}" in
-*)
__brewcomp "
--debug
--dry-run
--help
--message
--quiet
--verbose
--write-only
"
return
;;
*) ;;
esac
__brew_complete_formulae
}

_brew_bump_formula_pr() {
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${cur}" in
Expand Down Expand Up @@ -3678,6 +3698,7 @@ _brew() {
bottle) _brew_bottle ;;
bump) _brew_bump ;;
bump-cask-pr) _brew_bump_cask_pr ;;
bump-compatibility-version) _brew_bump_compatibility_version ;;
bump-formula-pr) _brew_bump_formula_pr ;;
bump-revision) _brew_bump_revision ;;
bump-unversioned-casks) _brew_bump_unversioned_casks ;;
Expand Down
11 changes: 11 additions & 0 deletions completions/fish/brew.fish
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,17 @@ __fish_brew_complete_arg 'bump-cask-pr' -l write-only -d 'Make the expected file
__fish_brew_complete_arg 'bump-cask-pr' -a '(__fish_brew_suggest_casks_all)'


__fish_brew_complete_cmd 'bump-compatibility-version' 'Create a commit to increment the compatibility_version of formula'
__fish_brew_complete_arg 'bump-compatibility-version' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'bump-compatibility-version' -l dry-run -d 'Print what would be done rather than doing it'
__fish_brew_complete_arg 'bump-compatibility-version' -l help -d 'Show this message'
__fish_brew_complete_arg 'bump-compatibility-version' -l message -d 'Append message to the default commit message'
__fish_brew_complete_arg 'bump-compatibility-version' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_arg 'bump-compatibility-version' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_arg 'bump-compatibility-version' -l write-only -d 'Make the expected file modifications without taking any Git actions'
__fish_brew_complete_arg 'bump-compatibility-version' -a '(__fish_brew_suggest_formulae_all)'


__fish_brew_complete_cmd 'bump-formula-pr' 'Create a pull request to update formula with a new URL or a new tag'
__fish_brew_complete_arg 'bump-formula-pr' -l commit -d 'When passed with `--write-only`, generate a new commit after writing changes to the formula file'
__fish_brew_complete_arg 'bump-formula-pr' -l debug -d 'Display any debugging information'
Expand Down
1 change: 1 addition & 0 deletions completions/internal_commands_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ autoremove
bottle
bump
bump-cask-pr
bump-compatibility-version
bump-formula-pr
bump-revision
bump-unversioned-casks
Expand Down
15 changes: 15 additions & 0 deletions completions/zsh/_brew
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ __brew_internal_commands() {
'bottle:Generate a bottle (binary package) from a formula that was installed with `--build-bottle`'
'bump:Displays out-of-date packages and the latest version available'
'bump-cask-pr:Create a pull request to update cask with a new version'
'bump-compatibility-version:Create a commit to increment the compatibility_version of formula'
'bump-formula-pr:Create a pull request to update formula with a new URL or a new tag'
'bump-revision:Create a commit to increment the revision of formula'
'bump-unversioned-casks:Check all casks with unversioned URLs in a given tap for updates'
Expand Down Expand Up @@ -624,6 +625,20 @@ _brew_bump_cask_pr() {
'*:cask:__brew_casks'
}

# brew bump-compatibility-version
_brew_bump_compatibility_version() {
_arguments \
'--debug[Display any debugging information]' \
'(--write-only)--dry-run[Print what would be done rather than doing it]' \
'--help[Show this message]' \
'--message[Append message to the default commit message]' \
'--quiet[Make some output more quiet]' \
'--verbose[Make some output more verbose]' \
'(--dry-run)--write-only[Make the expected file modifications without taking any Git actions]' \
- formula \
'*:formula:__brew_formulae'
}

# brew bump-formula-pr
_brew_bump_formula_pr() {
_arguments \
Expand Down
2 changes: 2 additions & 0 deletions docs/Formula-Cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ Bump `compatibility_version` by `1` when a formula update requires any recursive

Do not change `compatibility_version` for updates that do not require dependent `revision` bumps. It should never decrease and should only increment by `1` at a time.

Use [`brew bump-compatibility-version`](Manpage.md#bump-compatibility-version-options-formula-) to increment `compatibility_version` mechanically.

[`brew audit`](Manpage.md) checks this relationship in both directions. If a formula's `compatibility_version` increases, at least one recursive dependent in the same pull request must also increase `revision` by `1`. If a formula's `revision` increases because a changed recursive dependency also changed versions, that dependency must increase `compatibility_version` by `1`.

These checks are based on dependent `revision` bumps in the pull request, not on general ABI analysis. Homebrew cannot automatically detect every compatibility break that is not covered by linkage or formula tests, so maintainers may still need to bump `compatibility_version` and dependent `revision`s manually when they know a rebuild is required.
Expand Down
1 change: 1 addition & 0 deletions docs/Homebrew-homebrew-core-Maintainer-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ The following checklist is intended to help maintainers decide on whether to mer
- due to other formulae needing revision bumps - suggest using the following command:

# in this example: PR is for `libuv` formula and `urbit` needs revision bump
brew bump-compatibility-version --write-only libuv
brew bump-revision --message 'for libuv' urbit

- make sure it has one commit per revision bump
Expand Down
17 changes: 17 additions & 0 deletions docs/Manpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2922,6 +2922,23 @@ supplied by the user.

: Use the specified GitHub organization for forking.

### `bump-compatibility-version` \[*`options`*\] *`formula`* \[...\]

Create a commit to increment the compatibility\_version of *`formula`*. If no
compatibility\_version is present, "compatibility\_version 1" will be added.

`-n`, `--dry-run`

: Print what would be done rather than doing it.

`--write-only`

: Make the expected file modifications without taking any Git actions.

`--message`

: Append *`message`* to the default commit message.

### `bump-formula-pr` \[*`options`*\] \[*`formula`*\]

Create a pull request to update *`formula`* with a new URL or a new tag.
Expand Down
11 changes: 11 additions & 0 deletions manpages/brew.1
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,17 @@ Specify the \fISHA\-256\fP checksum of the new download\.
.TP
\fB\-\-fork\-org\fP
Use the specified GitHub organization for forking\.
.SS "\fBbump\-compatibility\-version\fP \fR[\fIoptions\fP] \fIformula\fP \fR[\.\.\.]"
Create a commit to increment the compatibility_version of \fIformula\fP\&\. If no compatibility_version is present, \[u201c]compatibility_version 1\[u201d] will be added\.
.TP
\fB\-n\fP, \fB\-\-dry\-run\fP
Print what would be done rather than doing it\.
.TP
\fB\-\-write\-only\fP
Make the expected file modifications without taking any Git actions\.
.TP
\fB\-\-message\fP
Append \fImessage\fP to the default commit message\.
.SS "\fBbump\-formula\-pr\fP \fR[\fIoptions\fP] \fR[\fIformula\fP]"
Create a pull request to update \fIformula\fP with a new URL or a new tag\.
.P
Expand Down
Loading