Skip to content

Commit

Permalink
Merge pull request #15740 from EricFromCanada/tap-suggestion
Browse files Browse the repository at this point in the history
dev-cmd/edit: suggest tapping core repositories if untapped
  • Loading branch information
MikeMcQuaid authored Aug 2, 2023
2 parents 7994173 + b3ecd91 commit d2863d0
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 49 deletions.
2 changes: 1 addition & 1 deletion Library/Homebrew/cask/cask_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def self.can_load?(ref)

def initialize(token, from_json: nil)
@token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "")
@path = CaskLoader.default_path(token)
@path = CaskLoader.default_path(@token)
@from_json = from_json
end

Expand Down
15 changes: 11 additions & 4 deletions Library/Homebrew/cli/named_args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,9 @@ def to_resolved_formulae_to_casks(only: parent&.only_formula_or_cask)
def to_paths(only: parent&.only_formula_or_cask, recurse_tap: false)
@to_paths ||= {}
@to_paths[only] ||= downcased_unique_named.flat_map do |name|
path = Pathname(name)
if File.exist?(name)
Pathname(name)
path
elsif name.count("/") == 1 && !name.start_with?("./", "/")
tap = Tap.fetch(name)

Expand All @@ -248,10 +249,16 @@ def to_paths(only: parent&.only_formula_or_cask, recurse_tap: false)

paths = []

paths << formula_path if formula_path.exist?
paths << cask_path if cask_path.exist?
if formula_path.exist? ||
(!CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(path.basename))
paths << formula_path
end
if cask_path.exist? ||
(!CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(path.basename))
paths << cask_path
end

paths.empty? ? Pathname(name) : paths
paths.empty? ? path : paths
end
end.uniq.freeze
end
Expand Down
76 changes: 45 additions & 31 deletions Library/Homebrew/dev-cmd/edit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ module Homebrew
def edit_args
Homebrew::CLI::Parser.new do
description <<~EOS
Open a <formula> or <cask> in the editor set by `EDITOR` or `HOMEBREW_EDITOR`,
or open the Homebrew repository for editing if no formula is provided.
Open a <formula>, <cask> or <tap> in the editor set by `EDITOR` or `HOMEBREW_EDITOR`,
or open the Homebrew repository for editing if no argument is provided.
EOS

switch "--formula", "--formulae",
Expand All @@ -24,7 +24,7 @@ def edit_args

conflicts "--formula", "--cask"

named_args [:formula, :cask], without_api: true
named_args [:formula, :cask, :tap], without_api: true
end
end

Expand All @@ -50,42 +50,56 @@ def edit
[HOMEBREW_REPOSITORY]
end
else
edit_api_message_displayed = T.let(false, T::Boolean)
args.named.to_paths.select do |path|
next path if path.exist?
core_formula_path = path.fnmatch?("**/homebrew-core/Formula/**.rb", File::FNM_DOTMATCH)
core_cask_path = path.fnmatch?("**/homebrew-cask/Casks/**.rb", File::FNM_DOTMATCH)
core_formula_tap = path == CoreTap.instance.path
core_cask_tap = path == CoreCaskTap.instance.path

not_exist_message = if args.cask?
"#{path.basename(".rb")} doesn't exist on disk."
else
"#{path} doesn't exist on disk."
if path.exist?
if (core_formula_path || core_cask_path || core_formula_tap || core_cask_tap) &&
!edit_api_message_displayed &&
!Homebrew::EnvConfig.no_install_from_api? &&
!Homebrew::EnvConfig.no_env_hints?
opoo <<~EOS
Unless `HOMEBREW_NO_INSTALL_FROM_API` is set when running `brew install`,
it will ignore any locally edited #{(core_cask_path || core_cask_tap) ? "casks" : "formulae"}.
EOS
edit_api_message_displayed = true
end
next path
end

message = if args.cask?
<<~EOS
#{not_exist_message}
Run #{Formatter.identifier("brew create --cask --set-name #{path.basename(".rb")} $URL")} \
to create a new cask!
EOS
name = path.basename(".rb").to_s

if (tap_match = Regexp.new(HOMEBREW_TAP_DIR_REGEX.source + /$/.source).match(path.to_s))
raise TapUnavailableError, CoreTap.instance.name if core_formula_tap
raise TapUnavailableError, CoreCaskTap.instance.name if core_cask_tap

raise TapUnavailableError, "#{tap_match[:user]}/#{tap_match[:repo]}"
elsif args.cask? || core_cask_path
if !CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(name)
command = "brew tap --force #{CoreCaskTap.instance.name}"
action = "tap #{CoreCaskTap.instance.name}"
else
command = "brew create --cask --set-name #{name} $URL"
action = "create a new cask"
end
elsif core_formula_path && !CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(name)
command = "brew tap --force #{CoreTap.instance.name}"
action = "tap #{CoreTap.instance.name}"
else
<<~EOS
#{not_exist_message}
Run #{Formatter.identifier("brew create --set-name #{path.basename} $URL")} \
to create a new formula!
EOS
command = "brew create --set-name #{name} $URL"
action = "create a new formula"
end
raise UsageError, message
end.presence
end

if !Homebrew::EnvConfig.no_install_from_api? && !Homebrew::EnvConfig.no_env_hints?
paths.each do |path|
next if !path.fnmatch?("**/homebrew-core/Formula/*.rb") && !path.fnmatch?("**/homebrew-cask/Casks/*.rb")

opoo <<~EOS
Unless `HOMEBREW_NO_INSTALL_FROM_API` is set when running
`brew install`, it will ignore your locally edited formula.
message = <<~EOS
#{name} doesn't exist on disk.
Run #{Formatter.identifier(command)} to #{action}!
EOS
break
end
raise UsageError, message
end.presence
end

if args.print_path?
Expand Down
16 changes: 13 additions & 3 deletions Library/Homebrew/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,19 @@ class TapUnavailableError < RuntimeError
def initialize(name)
@name = name

super <<~EOS
No available tap #{name}.
EOS
message = "No available tap #{name}.\n"
if [CoreTap.instance.name, CoreCaskTap.instance.name].include?(name)
command = "brew tap --force #{name}"
message += <<~EOS
Run #{Formatter.identifier(command)} to tap #{name}!
EOS
else
command = "brew tap-new #{name}"
message += <<~EOS
Run #{Formatter.identifier(command)} to create a new #{name} tap!
EOS
end
super message.freeze
end
end

Expand Down
3 changes: 2 additions & 1 deletion Library/Homebrew/formulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,8 @@ def self.tap_paths(name, taps = Tap)
end

def self.find_formula_in_tap(name, tap)
filename = "#{name}.rb"
filename = name.dup
filename << ".rb" unless filename.end_with?(".rb")

Tap.formula_files_by_name(tap).fetch(filename, tap.formula_dir/filename)
end
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/test/exceptions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class Baz < Formula; end
describe TapUnavailableError do
subject { described_class.new("foo") }

its(:to_s) { is_expected.to eq("No available tap foo.\n") }
its(:to_s) { is_expected.to eq("No available tap foo.\nRun brew tap-new foo to create a new foo tap!\n") }
end

describe TapAlreadyTappedError do
Expand Down
1 change: 1 addition & 0 deletions completions/bash/brew
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ _brew_edit() {
esac
__brew_complete_formulae
__brew_complete_casks
__brew_complete_tapped
}

_brew_environment() {
Expand Down
3 changes: 2 additions & 1 deletion completions/fish/brew.fish
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ __fish_brew_complete_arg 'dr' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_arg 'dr' -a '(__fish_brew_suggest_diagnostic_checks)'


__fish_brew_complete_cmd 'edit' 'Open a formula or cask in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no formula is provided'
__fish_brew_complete_cmd 'edit' 'Open a formula, cask or tap in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided'
__fish_brew_complete_arg 'edit' -l cask -d 'Treat all named arguments as casks'
__fish_brew_complete_arg 'edit' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'edit' -l formula -d 'Treat all named arguments as formulae'
Expand All @@ -680,6 +680,7 @@ __fish_brew_complete_arg 'edit' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_arg 'edit' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_arg 'edit; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)'
__fish_brew_complete_arg 'edit; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_all)'
__fish_brew_complete_arg 'edit' -a '(__fish_brew_suggest_taps_installed)'


__fish_brew_complete_cmd 'environment' 'Summarise Homebrew\'s build environment as a plain list'
Expand Down
6 changes: 4 additions & 2 deletions completions/zsh/_brew
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ __brew_internal_commands() {
'dispatch-build-bottle:Build bottles for these formulae with GitHub Actions'
'docs:Open Homebrew'\''s online documentation (https://docs.brew.sh) in a browser'
'doctor:Check your system for potential problems'
'edit:Open a formula or cask in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no formula is provided'
'edit:Open a formula, cask or tap in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the Homebrew repository for editing if no argument is provided'
'extract:Look through repository history to find the most recent version of formula and create a copy in tap'
'fetch:Download a bottle (if available) or source packages for formulae and binaries for casks'
'formula:Display the path where formula is located'
Expand Down Expand Up @@ -853,7 +853,9 @@ _brew_edit() {
'*::formula:__brew_formulae' \
- cask \
'(--formula)--cask[Treat all named arguments as casks]' \
'*::cask:__brew_casks'
'*::cask:__brew_casks' \
- tap \
'*::tap:__brew_any_tap'
}

# brew environment
Expand Down
6 changes: 3 additions & 3 deletions docs/Manpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -1240,10 +1240,10 @@ Build bottles for these formulae with GitHub Actions.
* `--linux-wheezy`:
Use Debian Wheezy container for building the bottle on Linux.

### `edit` [*`options`*] [*`formula`*|*`cask`* ...]
### `edit` [*`options`*] [*`formula`*|*`cask`*|*`tap`* ...]

Open a *`formula`* or *`cask`* in the editor set by `EDITOR` or `HOMEBREW_EDITOR`,
or open the Homebrew repository for editing if no formula is provided.
Open a *`formula`*, *`cask`* or *`tap`* in the editor set by `EDITOR` or `HOMEBREW_EDITOR`,
or open the Homebrew repository for editing if no argument is provided.

* `--formula`:
Treat all named arguments as formulae.
Expand Down
4 changes: 2 additions & 2 deletions manpages/brew.1
Original file line number Diff line number Diff line change
Expand Up @@ -1804,8 +1804,8 @@ Dispatch bottle for Linux (using self\-hosted runner)\.
\fB\-\-linux\-wheezy\fR
Use Debian Wheezy container for building the bottle on Linux\.
.
.SS "\fBedit\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR \.\.\.]"
Open a \fIformula\fR or \fIcask\fR in the editor set by \fBEDITOR\fR or \fBHOMEBREW_EDITOR\fR, or open the Homebrew repository for editing if no formula is provided\.
.SS "\fBedit\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR|\fItap\fR \.\.\.]"
Open a \fIformula\fR, \fIcask\fR or \fItap\fR in the editor set by \fBEDITOR\fR or \fBHOMEBREW_EDITOR\fR, or open the Homebrew repository for editing if no argument is provided\.
.
.TP
\fB\-\-formula\fR
Expand Down

0 comments on commit d2863d0

Please sign in to comment.