mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
dev-cmd/unbottled: add new command.
Add a new command to list formulae that aren't bottled for a given OS.
This commit is contained in:
parent
4b1ef4e41b
commit
135b5a3679
166
Library/Homebrew/dev-cmd/unbottled.rb
Normal file
166
Library/Homebrew/dev-cmd/unbottled.rb
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
# typed: true
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "cli/parser"
|
||||||
|
require "formula"
|
||||||
|
|
||||||
|
module Homebrew
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
|
module_function
|
||||||
|
|
||||||
|
sig { returns(CLI::Parser) }
|
||||||
|
def unbottled_args
|
||||||
|
Homebrew::CLI::Parser.new do
|
||||||
|
usage_banner <<~EOS
|
||||||
|
`unbottled` [<formula>]
|
||||||
|
|
||||||
|
Outputs the unbottled dependents of formulae.
|
||||||
|
EOS
|
||||||
|
flag "--tag=",
|
||||||
|
description: "Use the specified bottle tag (e.g. big_sur) instead of the current OS."
|
||||||
|
switch "--dependents",
|
||||||
|
description: "Don't get analytics data and sort by number of dependents instead."
|
||||||
|
switch "--total",
|
||||||
|
description: "Output the number of unbottled and total formulae."
|
||||||
|
conflicts "--dependents", "--total"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
|
def unbottled
|
||||||
|
args = unbottled_args.parse
|
||||||
|
|
||||||
|
Formulary.enable_factory_cache!
|
||||||
|
|
||||||
|
@bottle_tag = if args.tag.present?
|
||||||
|
args.tag.to_sym
|
||||||
|
else
|
||||||
|
Utils::Bottles.tag
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.named.blank?
|
||||||
|
ohai "Getting formulae..."
|
||||||
|
elsif args.total?
|
||||||
|
raise UsageError, "cannot specify `<formula>` and `--total`."
|
||||||
|
end
|
||||||
|
|
||||||
|
formulae, all_formulae, sort, formula_installs =
|
||||||
|
formulae_all_sort_installs_from_args(args)
|
||||||
|
deps_hash, uses_hash = deps_uses_from_formulae(all_formulae)
|
||||||
|
|
||||||
|
if args.dependents?
|
||||||
|
formula_dependents = {}
|
||||||
|
formulae = formulae.sort_by do |f|
|
||||||
|
dependents = uses_hash[f.name]&.length || 0
|
||||||
|
formula_dependents[f.name] ||= dependents
|
||||||
|
end.reverse
|
||||||
|
end
|
||||||
|
|
||||||
|
if args.total?
|
||||||
|
output_total(formulae)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
noun, hash = if args.named.present?
|
||||||
|
[nil, {}]
|
||||||
|
elsif args.dependents?
|
||||||
|
["dependents", formula_dependents]
|
||||||
|
else
|
||||||
|
["installs", formula_installs]
|
||||||
|
end
|
||||||
|
output_unbottled(sort, formulae, deps_hash, noun, hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def formulae_all_sort_installs_from_args(args)
|
||||||
|
if args.named.present?
|
||||||
|
formulae = all_formulae = args.named.to_formulae
|
||||||
|
elsif args.total?
|
||||||
|
formulae = all_formulae = Formula.to_a
|
||||||
|
elsif args.dependents?
|
||||||
|
formulae = all_formulae = Formula.to_a
|
||||||
|
|
||||||
|
sort = " (sorted by installs in the last 90 days)"
|
||||||
|
else
|
||||||
|
formula_installs = {}
|
||||||
|
|
||||||
|
ohai "Getting analytics data..."
|
||||||
|
analytics = Utils::Analytics.formulae_brew_sh_json("analytics/install/90d.json")
|
||||||
|
formulae = analytics["items"].map do |i|
|
||||||
|
f = i["formula"].split.first
|
||||||
|
next if f.include?("/")
|
||||||
|
next if formula_installs[f].present?
|
||||||
|
|
||||||
|
formula_installs[f] = i["count"]
|
||||||
|
begin
|
||||||
|
Formula[f]
|
||||||
|
rescue FormulaUnavailableError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
sort = " (sorted by installs in the last 90 days)"
|
||||||
|
|
||||||
|
all_formulae = Formula
|
||||||
|
end
|
||||||
|
|
||||||
|
[formulae, all_formulae, sort, formula_installs]
|
||||||
|
end
|
||||||
|
|
||||||
|
def deps_uses_from_formulae(all_formulae)
|
||||||
|
ohai "Populating dependency tree..."
|
||||||
|
|
||||||
|
deps_hash = {}
|
||||||
|
uses_hash = {}
|
||||||
|
|
||||||
|
all_formulae.each do |f|
|
||||||
|
next unless f.core_formula?
|
||||||
|
|
||||||
|
deps = f.recursive_dependencies do |_, dep|
|
||||||
|
Dependency.prune if dep.optional?
|
||||||
|
end.map(&:to_formula)
|
||||||
|
deps_hash[f.name] = deps
|
||||||
|
|
||||||
|
deps.each do |dep|
|
||||||
|
uses_hash[dep.name] ||= []
|
||||||
|
uses_hash[dep.name] << f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[deps_hash, uses_hash]
|
||||||
|
end
|
||||||
|
|
||||||
|
def output_total(formulae)
|
||||||
|
ohai "Unbottled :#{@bottle_tag} formulae"
|
||||||
|
unbottled_formulae = 0
|
||||||
|
|
||||||
|
formulae.each do |f|
|
||||||
|
next if f.bottle_specification.tag?(@bottle_tag)
|
||||||
|
next if f.bottle_unneeded?
|
||||||
|
|
||||||
|
unbottled_formulae += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "#{unbottled_formulae}/#{formulae.length} remaining."
|
||||||
|
end
|
||||||
|
|
||||||
|
def output_unbottled(sort, formulae, deps_hash, noun, hash)
|
||||||
|
ohai "Unbottled :#{@bottle_tag} dependencies#{sort}"
|
||||||
|
any_found = T.let(false, T::Boolean)
|
||||||
|
|
||||||
|
formulae.each do |f|
|
||||||
|
next if f.bottle_specification.tag?(@bottle_tag)
|
||||||
|
|
||||||
|
deps = Array(deps_hash[f.name]).reject do |dep|
|
||||||
|
dep.bottle_specification.tag?(@bottle_tag) || dep.bottle_unneeded?
|
||||||
|
end
|
||||||
|
next if deps.blank?
|
||||||
|
|
||||||
|
any_found ||= true
|
||||||
|
count = " (#{hash[f.name]} #{noun})" if noun
|
||||||
|
puts "#{f.name}#{count}: #{deps.join(" ")}"
|
||||||
|
end
|
||||||
|
return if any_found
|
||||||
|
|
||||||
|
puts "No unbottled dependencies found!"
|
||||||
|
end
|
||||||
|
end
|
8
Library/Homebrew/test/dev-cmd/unbottled_spec.rb
Normal file
8
Library/Homebrew/test/dev-cmd/unbottled_spec.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# typed: false
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "cmd/shared_examples/args_parse"
|
||||||
|
|
||||||
|
describe "Homebrew.unbottled_args" do
|
||||||
|
it_behaves_like "parseable arguments"
|
||||||
|
end
|
@ -87,6 +87,7 @@ tc
|
|||||||
test
|
test
|
||||||
tests
|
tests
|
||||||
typecheck
|
typecheck
|
||||||
|
unbottled
|
||||||
uninstal
|
uninstal
|
||||||
uninstall
|
uninstall
|
||||||
unlink
|
unlink
|
||||||
|
@ -1278,6 +1278,17 @@ Check for typechecking errors using Sorbet.
|
|||||||
* `--ignore`:
|
* `--ignore`:
|
||||||
Ignores input files that contain the given string in their paths (relative to the input path passed to Sorbet).
|
Ignores input files that contain the given string in their paths (relative to the input path passed to Sorbet).
|
||||||
|
|
||||||
|
### `unbottled` [*`formula`*]
|
||||||
|
|
||||||
|
Outputs the unbottled dependents of formulae.
|
||||||
|
|
||||||
|
* `--tag`:
|
||||||
|
Use the specified bottle tag (e.g. big_sur) instead of the current OS.
|
||||||
|
* `--dependents`:
|
||||||
|
Don't get analytics data and sort by number of dependents instead.
|
||||||
|
* `--total`:
|
||||||
|
Output the number of unbottled and total formulae.
|
||||||
|
|
||||||
### `unpack` [*`options`*] *`formula`*
|
### `unpack` [*`options`*] *`formula`*
|
||||||
|
|
||||||
Unpack the source files for *`formula`* into subdirectories of the current
|
Unpack the source files for *`formula`* into subdirectories of the current
|
||||||
|
@ -1768,6 +1768,21 @@ Typecheck a single file\.
|
|||||||
\fB\-\-ignore\fR
|
\fB\-\-ignore\fR
|
||||||
Ignores input files that contain the given string in their paths (relative to the input path passed to Sorbet)\.
|
Ignores input files that contain the given string in their paths (relative to the input path passed to Sorbet)\.
|
||||||
.
|
.
|
||||||
|
.SS "\fBunbottled\fR [\fIformula\fR]"
|
||||||
|
Outputs the unbottled dependents of formulae\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-\-tag\fR
|
||||||
|
Use the specified bottle tag (e\.g\. big_sur) instead of the current OS\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-\-dependents\fR
|
||||||
|
Don\'t get analytics data and sort by number of dependents instead\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fB\-\-total\fR
|
||||||
|
Output the number of unbottled and total formulae\.
|
||||||
|
.
|
||||||
.SS "\fBunpack\fR [\fIoptions\fR] \fIformula\fR"
|
.SS "\fBunpack\fR [\fIoptions\fR] \fIformula\fR"
|
||||||
Unpack the source files for \fIformula\fR into subdirectories of the current working directory\.
|
Unpack the source files for \fIformula\fR into subdirectories of the current working directory\.
|
||||||
.
|
.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user