Merge pull request #17449 from Homebrew/brew-mark

This commit is contained in:
Mike McQuaid 2024-06-13 09:11:00 +01:00 committed by GitHub
commit 4f35bc1e12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 217 additions and 3 deletions

View File

@ -0,0 +1,75 @@
# typed: strict
# frozen_string_literal: true
require "abstract_command"
require "formula"
require "tab"
module Homebrew
module Cmd
class TabCmd < AbstractCommand
cmd_args do
description <<~EOS
Edit tab information for installed formulae.
This can be useful when you want to control whether an installed
formula should be removed by `brew autoremove`.
To prevent removal, mark the formula as installed on request;
to allow removal, mark the formula as not installed on request.
EOS
switch "--installed-on-request",
description: "Mark <formula> as installed on request."
switch "--no-installed-on-request",
description: "Mark <formula> as not installed on request."
conflicts "--installed-on-request", "--no-installed-on-request"
named_args :formula, min: 1
end
sig { override.void }
def run
installed_on_request = if args.installed_on_request?
true
elsif args.no_installed_on_request?
false
end
raise UsageError, "No marking option specified." if installed_on_request.nil?
formulae = args.named.to_formulae
if (formulae_not_installed = formulae.reject(&:any_version_installed?)).any?
formula_names = formulae_not_installed.map(&:name)
is_or_are = (formula_names.length == 1) ? "is" : "are"
odie "#{formula_names.to_sentence} #{is_or_are} not installed."
end
formulae.each do |formula|
update_tab formula, installed_on_request:
end
end
private
sig { params(formula: Formula, installed_on_request: T::Boolean).void }
def update_tab(formula, installed_on_request:)
tab = Tab.for_formula(formula)
unless tab.tabfile.exist?
raise ArgumentError,
"Tab file for #{formula.name} does not exist."
end
installed_on_request_str = "#{"not " unless installed_on_request}installed on request"
if (tab.installed_on_request && installed_on_request) ||
(!tab.installed_on_request && !installed_on_request)
ohai "#{formula.name} is already marked as #{installed_on_request_str}."
return
end
tab.installed_on_request = installed_on_request
tab.write
ohai "#{formula.name} is now marked as #{installed_on_request_str}."
end
end
end
end

View File

@ -0,0 +1,19 @@
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Homebrew::Cmd::TabCmd`.
# Please instead update this file by running `bin/tapioca dsl Homebrew::Cmd::TabCmd`.
class Homebrew::Cmd::TabCmd
sig { returns(Homebrew::Cmd::TabCmd::Args) }
def args; end
end
class Homebrew::Cmd::TabCmd::Args < Homebrew::CLI::Args
sig { returns(T::Boolean) }
def installed_on_request?; end
sig { returns(T::Boolean) }
def no_installed_on_request?; end
end

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
require "cmd/tab"
require "cmd/shared_examples/args_parse"
require "tab"
RSpec.describe Homebrew::Cmd::TabCmd do
def installed_on_request?(formula)
# `brew` subprocesses can change the tab, invalidating the cached values.
Tab.clear_cache
Tab.for_formula(formula).installed_on_request
end
it_behaves_like "parseable arguments"
it "marks or unmarks a formula as installed on request", :integration_test do
setup_test_formula "foo",
tab_attributes: { "installed_on_request" => false }
foo = Formula["foo"]
expect { brew "tab", "--installed-on-request", "foo" }
.to be_a_success
.and output(/foo is now marked as installed on request/).to_stdout
.and not_to_output.to_stderr
expect(installed_on_request?(foo)).to be true
expect { brew "tab", "--no-installed-on-request", "foo" }
.to be_a_success
.and output(/foo is now marked as not installed on request/).to_stdout
.and not_to_output.to_stderr
expect(installed_on_request?(foo)).to be false
end
end

View File

@ -129,7 +129,8 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin
end end
end end
def setup_test_formula(name, content = nil, tap: CoreTap.instance, bottle_block: nil) def setup_test_formula(name, content = nil, tap: CoreTap.instance,
bottle_block: nil, tab_attributes: nil)
case name case name
when /^testball/ when /^testball/
tarball = if OS.linux? tarball = if OS.linux?
@ -174,8 +175,8 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin
RUBY RUBY
end end
Formulary.find_formula_in_tap(name.downcase, tap).tap do |formula_path| formula_path = Formulary.find_formula_in_tap(name.downcase, tap).tap do |path|
formula_path.write <<~RUBY path.write <<~RUBY
class #{Formulary.class_s(name)} < Formula class #{Formulary.class_s(name)} < Formula
#{content.gsub(/^(?!$)/, " ")} #{content.gsub(/^(?!$)/, " ")}
end end
@ -183,6 +184,20 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin
tap.clear_cache tap.clear_cache
end end
return formula_path if tab_attributes.nil?
keg = Formula[name].prefix
keg.mkpath
tab = Tab.for_name(name)
tab.tabfile ||= keg/Tab::FILENAME
tab_attributes.each do |key, value|
tab.instance_variable_set(:"@#{key}", value)
end
tab.write
formula_path
end end
def install_test_formula(name, content = nil, build_bottle: false) def install_test_formula(name, content = nil, build_bottle: false)

View File

@ -2107,6 +2107,25 @@ _brew_style() {
__brew_complete_casks __brew_complete_casks
} }
_brew_tab() {
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${cur}" in
-*)
__brewcomp "
--debug
--help
--installed-on-request
--no-installed-on-request
--quiet
--verbose
"
return
;;
*) ;;
esac
__brew_complete_formulae
}
_brew_tap() { _brew_tap() {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
case "${cur}" in case "${cur}" in
@ -2765,6 +2784,7 @@ _brew() {
search) _brew_search ;; search) _brew_search ;;
sh) _brew_sh ;; sh) _brew_sh ;;
style) _brew_style ;; style) _brew_style ;;
tab) _brew_tab ;;
tap) _brew_tap ;; tap) _brew_tap ;;
tap-info) _brew_tap_info ;; tap-info) _brew_tap_info ;;
tap-new) _brew_tap_new ;; tap-new) _brew_tap_new ;;

View File

@ -1413,6 +1413,16 @@ __fish_brew_complete_arg 'style; and not __fish_seen_argument -l cask -l casks'
__fish_brew_complete_arg 'style; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_all)' __fish_brew_complete_arg 'style; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_all)'
__fish_brew_complete_cmd 'tab' 'Edit tab information for installed formulae'
__fish_brew_complete_arg 'tab' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'tab' -l help -d 'Show this message'
__fish_brew_complete_arg 'tab' -l installed-on-request -d 'Mark formula as installed on request'
__fish_brew_complete_arg 'tab' -l no-installed-on-request -d 'Mark formula as not installed on request'
__fish_brew_complete_arg 'tab' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_arg 'tab' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_arg 'tab' -a '(__fish_brew_suggest_formulae_all)'
__fish_brew_complete_cmd 'tap' 'Tap a formula repository' __fish_brew_complete_cmd 'tap' 'Tap a formula repository'
__fish_brew_complete_arg 'tap' -l custom-remote -d 'Install or change a tap with a custom remote. Useful for mirrors' __fish_brew_complete_arg 'tap' -l custom-remote -d 'Install or change a tap with a custom remote. Useful for mirrors'
__fish_brew_complete_arg 'tap' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'tap' -l debug -d 'Display any debugging information'

View File

@ -90,6 +90,7 @@ setup-ruby
sh sh
shellenv shellenv
style style
tab
tap tap
tap-info tap-info
tap-new tap-new

View File

@ -210,6 +210,7 @@ __brew_internal_commands() {
'sh:Enter an interactive shell for Homebrew'\''s build environment' 'sh:Enter an interactive shell for Homebrew'\''s build environment'
'shellenv:Print export statements' 'shellenv:Print export statements'
'style:Check formulae or files for conformance to Homebrew style guidelines' 'style:Check formulae or files for conformance to Homebrew style guidelines'
'tab:Edit tab information for installed formulae'
'tap:Tap a formula repository' 'tap:Tap a formula repository'
'tap-info:Show detailed information about one or more taps' 'tap-info:Show detailed information about one or more taps'
'tap-new:Generate the template files for a new tap' 'tap-new:Generate the template files for a new tap'
@ -1747,6 +1748,19 @@ _brew_style() {
'*::cask:__brew_casks' '*::cask:__brew_casks'
} }
# brew tab
_brew_tab() {
_arguments \
'--debug[Display any debugging information]' \
'--help[Show this message]' \
'(--no-installed-on-request)--installed-on-request[Mark formula as installed on request]' \
'(--installed-on-request)--no-installed-on-request[Mark formula as not installed on request]' \
'--quiet[Make some output more quiet]' \
'--verbose[Make some output more verbose]' \
- formula \
'*::formula:__brew_formulae'
}
# brew tap # brew tap
_brew_tap() { _brew_tap() {
_arguments \ _arguments \

View File

@ -1162,6 +1162,23 @@ evaluation of this command's output to your dotfiles (e.g. `~/.bash_profile` or
The shell can be specified explicitly with a supported shell name parameter. The shell can be specified explicitly with a supported shell name parameter.
Unknown shells will output POSIX exports. Unknown shells will output POSIX exports.
### `tab` \[`--installed-on-request`\] \[`--no-installed-on-request`\] *`formula`* \[...\]
Edit tab information for installed formulae.
This can be useful when you want to control whether an installed formula should
be removed by `brew autoremove`. To prevent removal, mark the formula as
installed on request; to allow removal, mark the formula as not installed on
request.
`--installed-on-request`
: Mark *`formula`* as installed on request.
`--no-installed-on-request`
: Mark *`formula`* as not installed on request.
### `tap` \[*`options`*\] \[*`user`*`/`*`repo`*\] \[*`URL`*\] ### `tap` \[*`options`*\] \[*`user`*`/`*`repo`*\] \[*`URL`*\]
Tap a formula repository. If no arguments are provided, list all installed taps. Tap a formula repository. If no arguments are provided, list all installed taps.

View File

@ -727,6 +727,16 @@ Print export statements\. When run in a shell, this installation of Homebrew wil
The variables \fBHOMEBREW_PREFIX\fP, \fBHOMEBREW_CELLAR\fP and \fBHOMEBREW_REPOSITORY\fP are also exported to avoid querying them multiple times\. To help guarantee idempotence, this command produces no output when Homebrew\[u2019]s \fBbin\fP and \fBsbin\fP directories are first and second respectively in your \fBPATH\fP\&\. Consider adding evaluation of this command\[u2019]s output to your dotfiles (e\.g\. \fB~/\.bash_profile\fP or \fB~/\.zprofile\fP on macOS and \fB~/\.bashrc\fP or \fB~/\.zshrc\fP on Linux) with: \fBeval "$(brew shellenv)"\fP The variables \fBHOMEBREW_PREFIX\fP, \fBHOMEBREW_CELLAR\fP and \fBHOMEBREW_REPOSITORY\fP are also exported to avoid querying them multiple times\. To help guarantee idempotence, this command produces no output when Homebrew\[u2019]s \fBbin\fP and \fBsbin\fP directories are first and second respectively in your \fBPATH\fP\&\. Consider adding evaluation of this command\[u2019]s output to your dotfiles (e\.g\. \fB~/\.bash_profile\fP or \fB~/\.zprofile\fP on macOS and \fB~/\.bashrc\fP or \fB~/\.zshrc\fP on Linux) with: \fBeval "$(brew shellenv)"\fP
.P .P
The shell can be specified explicitly with a supported shell name parameter\. Unknown shells will output POSIX exports\. The shell can be specified explicitly with a supported shell name parameter\. Unknown shells will output POSIX exports\.
.SS "\fBtab\fP \fR[\fB\-\-installed\-on\-request\fP] \fR[\fB\-\-no\-installed\-on\-request\fP] \fIformula\fP \fR[\.\.\.]"
Edit tab information for installed formulae\.
.P
This can be useful when you want to control whether an installed formula should be removed by \fBbrew autoremove\fP\&\. To prevent removal, mark the formula as installed on request; to allow removal, mark the formula as not installed on request\.
.TP
\fB\-\-installed\-on\-request\fP
Mark \fIformula\fP as installed on request\.
.TP
\fB\-\-no\-installed\-on\-request\fP
Mark \fIformula\fP as not installed on request\.
.SS "\fBtap\fP \fR[\fIoptions\fP] \fR[\fIuser\fP\fB/\fP\fIrepo\fP] \fR[\fIURL\fP]" .SS "\fBtap\fP \fR[\fIoptions\fP] \fR[\fIuser\fP\fB/\fP\fIrepo\fP] \fR[\fIURL\fP]"
Tap a formula repository\. If no arguments are provided, list all installed taps\. Tap a formula repository\. If no arguments are provided, list all installed taps\.
.P .P