Merge branch 'master' into mlh-outdated-packages
This commit is contained in:
commit
9ec93f78d6
50
.github/workflows/doctor.yml
vendored
Normal file
50
.github/workflows/doctor.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: brew doctor
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/doctor.yml
|
||||
- Library/Homebrew/cmd/doctor.rb
|
||||
- Library/Homebrew/diagnostic.rb
|
||||
- Library/Homebrew/extend/os/diagnostic.rb
|
||||
- Library/Homebrew/extend/os/mac/diagnostic.rb
|
||||
- Library/Homebrew/os/mac/xcode.rb
|
||||
jobs:
|
||||
tests:
|
||||
strategy:
|
||||
matrix:
|
||||
version: [10.15, 10.14, 10.13]
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.version }}
|
||||
env:
|
||||
PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
|
||||
HOMEBREW_DEVELOPER: 1
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
steps:
|
||||
- name: Update Homebrew
|
||||
run: brew update-reset
|
||||
|
||||
- name: Set up Git repository
|
||||
run: |
|
||||
cd $(brew --repo)
|
||||
git clean -ffdx
|
||||
git fetch --prune --force origin master
|
||||
git fetch --prune --force origin ${{github.sha}}
|
||||
git checkout --force ${{github.sha}}
|
||||
git log -1
|
||||
|
||||
- name: Run brew test-bot --only-cleanup-before
|
||||
run: brew test-bot --only-cleanup-before
|
||||
|
||||
- name: Run brew test-bot --only-setup
|
||||
run: brew test-bot --only-setup
|
||||
|
||||
- name: Run brew test-bot --only-cleanup-after
|
||||
if: always()
|
||||
run: brew test-bot --only-cleanup-after
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: |
|
||||
find .
|
||||
rm -rf *
|
||||
41
.github/workflows/spdx.yml
vendored
Normal file
41
.github/workflows/spdx.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
name: Update license data
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
|
||||
jobs:
|
||||
spdx:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Configure Git
|
||||
uses: Homebrew/actions/git-user-config@master
|
||||
with:
|
||||
username: BrewTestBot
|
||||
|
||||
- name: Setup Homebrew
|
||||
run: |
|
||||
HOMEBREW_REPOSITORY="$(brew --repo)"
|
||||
rm -rf "$HOMEBREW_REPOSITORY"
|
||||
ln -s "$GITHUB_WORKSPACE" "$HOMEBREW_REPOSITORY"
|
||||
|
||||
- name: Update license data
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE/Library/Homebrew"
|
||||
if brew update-license-data --commit --fail-if-not-changed; then
|
||||
SPDX_VERSION=$(jq -er .licenseListVersion data/spdx.json)
|
||||
if ! git ls-remote --exit-code --heads origin "spdx-$SPDX_VERSION"; then
|
||||
git checkout -b "spdx-$SPDX_VERSION"
|
||||
git push origin "spdx-$SPDX_VERSION"
|
||||
hub pull-request -m "$(git log -1 --format='%s')"
|
||||
fi
|
||||
fi
|
||||
9
.github/workflows/tests.yml
vendored
9
.github/workflows/tests.yml
vendored
@ -62,12 +62,12 @@ jobs:
|
||||
|
||||
- name: Run brew doctor
|
||||
run: |
|
||||
# minimally fix brew doctor failures (a full clean takes ~5m)
|
||||
if [ "$RUNNER_OS" = "Linux" ]; then
|
||||
# Cleanup some Linux `brew doctor` failures
|
||||
sudo rm -rf /usr/local/include/node/
|
||||
else
|
||||
# Link old gettext (otherwise `brew doctor` is sad)
|
||||
brew link gettext
|
||||
# link old formulae
|
||||
brew link --overwrite --force gettext python@3.8
|
||||
|
||||
# remove deleted formula
|
||||
brew uninstall --force python@2
|
||||
@ -114,9 +114,6 @@ jobs:
|
||||
- name: Run brew man
|
||||
run: brew man --fail-if-changed
|
||||
|
||||
- name: Check for outdated license data
|
||||
run: brew update-license-data --fail-if-changed
|
||||
|
||||
- name: Run brew tests
|
||||
run: |
|
||||
# brew tests doesn't like world writable directories
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -85,6 +85,7 @@
|
||||
**/vendor/bundle/ruby/*/gems/bundler-*/
|
||||
**/vendor/bundle/ruby/*/gems/byebug-*/
|
||||
**/vendor/bundle/ruby/*/gems/coderay-*/
|
||||
**/vendor/bundle/ruby/*/gems/colorize-*/
|
||||
**/vendor/bundle/ruby/*/gems/connection_pool-*/
|
||||
**/vendor/bundle/ruby/*/gems/codecov-*/
|
||||
**/vendor/bundle/ruby/*/gems/diff-lcs-*/
|
||||
@ -129,7 +130,6 @@
|
||||
**/vendor/bundle/ruby/*/gems/simplecov-*/
|
||||
**/vendor/bundle/ruby/*/gems/simplecov-html-*/
|
||||
**/vendor/bundle/ruby/*/gems/thor-*/
|
||||
**/vendor/bundle/ruby/*/gems/url-*/
|
||||
**/vendor/bundle/ruby/*/gems/unf_ext-*/
|
||||
**/vendor/bundle/ruby/*/gems/unf-*/
|
||||
**/vendor/bundle/ruby/*/gems/unicode-display_width-*/
|
||||
|
||||
@ -9,10 +9,11 @@ GEM
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
ast (2.4.1)
|
||||
byebug (11.1.3)
|
||||
codecov (0.1.17)
|
||||
codecov (0.2.2)
|
||||
colorize
|
||||
json
|
||||
simplecov
|
||||
url
|
||||
colorize (0.8.1)
|
||||
concurrent-ruby (1.1.6)
|
||||
connection_pool (2.2.3)
|
||||
diff-lcs (1.4.4)
|
||||
@ -22,7 +23,7 @@ GEM
|
||||
hpricot (0.8.6)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (1.8.3)
|
||||
i18n (1.8.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.3.1)
|
||||
mechanize (2.7.6)
|
||||
@ -80,7 +81,7 @@ GEM
|
||||
rspec-support (3.9.3)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
rubocop (0.87.0)
|
||||
rubocop (0.88.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.7.1.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
@ -89,12 +90,12 @@ GEM
|
||||
rubocop-ast (>= 0.1.0, < 1.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 2.0)
|
||||
rubocop-ast (0.1.0)
|
||||
rubocop-ast (0.2.0)
|
||||
parser (>= 2.7.0.1)
|
||||
rubocop-performance (1.6.1)
|
||||
rubocop (>= 0.71.0)
|
||||
rubocop-rspec (1.41.0)
|
||||
rubocop (>= 0.68.1)
|
||||
rubocop-performance (1.7.1)
|
||||
rubocop (>= 0.82.0)
|
||||
rubocop-rspec (1.42.0)
|
||||
rubocop (>= 0.87.0)
|
||||
ruby-macho (2.2.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
simplecov (0.18.5)
|
||||
@ -108,9 +109,8 @@ GEM
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
url (0.3.2)
|
||||
webrobots (0.1.2)
|
||||
zeitwerk (2.3.1)
|
||||
zeitwerk (2.4.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
@ -127,7 +127,7 @@ begin
|
||||
ENV.delete("HOMEBREW_HELP") if help_flag
|
||||
tap_commands = []
|
||||
cgroup = Utils.popen_read("cat", "/proc/1/cgroup")
|
||||
if !cgroup.include?("azpl_job") && !cgroup.include?("docker")
|
||||
if %w[azpl_job actions_job docker garden kubepods].none? { |container| cgroup.include?(container) }
|
||||
brew_uid = HOMEBREW_BREW_FILE.stat.uid
|
||||
tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}] if Process.uid.zero? && !brew_uid.zero?
|
||||
end
|
||||
|
||||
@ -1,7 +1,19 @@
|
||||
HOMEBREW_PROCESSOR="$(uname -m)"
|
||||
HOMEBREW_SYSTEM="$(uname -s)"
|
||||
case "$HOMEBREW_SYSTEM" in
|
||||
Darwin) HOMEBREW_MACOS="1" ;;
|
||||
Linux) HOMEBREW_LINUX="1" ;;
|
||||
esac
|
||||
|
||||
# Force UTF-8 to avoid encoding issues for users with broken locale settings.
|
||||
if [[ "$(locale charmap 2>/dev/null)" != "UTF-8" ]]
|
||||
then
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
if [[ -n "$HOMEBREW_MACOS" ]]
|
||||
then
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
else
|
||||
export LC_ALL="C.UTF-8"
|
||||
fi
|
||||
fi
|
||||
|
||||
# USER isn't always set so provide a fall back for `brew` and subprocesses.
|
||||
@ -87,12 +99,6 @@ then
|
||||
odie "Cowardly refusing to continue at this prefix: $HOMEBREW_PREFIX"
|
||||
fi
|
||||
|
||||
HOMEBREW_SYSTEM="$(uname -s)"
|
||||
case "$HOMEBREW_SYSTEM" in
|
||||
Darwin) HOMEBREW_MACOS="1" ;;
|
||||
Linux) HOMEBREW_LINUX="1" ;;
|
||||
esac
|
||||
|
||||
if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" &&
|
||||
-x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]] &&
|
||||
"$HOMEBREW_PREFIX/opt/curl/bin/curl" --version >/dev/null
|
||||
@ -119,11 +125,9 @@ fi
|
||||
|
||||
if [[ -n "$HOMEBREW_MACOS" ]]
|
||||
then
|
||||
HOMEBREW_PROCESSOR="$(uname -p)"
|
||||
HOMEBREW_PRODUCT="Homebrew"
|
||||
HOMEBREW_SYSTEM="Macintosh"
|
||||
# This is i386 even on x86_64 machines
|
||||
[[ "$HOMEBREW_PROCESSOR" = "i386" ]] && HOMEBREW_PROCESSOR="Intel"
|
||||
[[ "$HOMEBREW_PROCESSOR" = "x86_64" ]] && HOMEBREW_PROCESSOR="Intel"
|
||||
HOMEBREW_MACOS_VERSION="$(/usr/bin/sw_vers -productVersion)"
|
||||
HOMEBREW_OS_VERSION="macOS $HOMEBREW_MACOS_VERSION"
|
||||
# Don't change this from Mac OS X to match what macOS itself does in Safari on 10.12
|
||||
@ -166,7 +170,6 @@ then
|
||||
HOMEBREW_MACOS_SYSTEM_RUBY_NEW_ENOUGH="1"
|
||||
fi
|
||||
else
|
||||
HOMEBREW_PROCESSOR="$(uname -m)"
|
||||
HOMEBREW_PRODUCT="${HOMEBREW_SYSTEM}brew"
|
||||
[[ -n "$HOMEBREW_LINUX" ]] && HOMEBREW_OS_VERSION="$(lsb_release -sd 2>/dev/null)"
|
||||
: "${HOMEBREW_OS_VERSION:=$(uname -r)}"
|
||||
@ -271,6 +274,11 @@ export HOMEBREW_USER_AGENT
|
||||
export HOMEBREW_USER_AGENT_CURL
|
||||
export HOMEBREW_BOTTLE_DEFAULT_DOMAIN
|
||||
|
||||
if [[ -n "$HOMEBREW_DEVELOPER" ]] && [[ -z "$HOMEBREW_NO_PATCHELF_RB" ]]
|
||||
then
|
||||
export HOMEBREW_PATCHELF_RB="1"
|
||||
fi
|
||||
|
||||
if [[ -n "$HOMEBREW_MACOS" && -x "/usr/bin/xcode-select" ]]
|
||||
then
|
||||
XCODE_SELECT_PATH=$('/usr/bin/xcode-select' --print-path 2>/dev/null)
|
||||
@ -430,8 +438,8 @@ fi
|
||||
check-run-command-as-root() {
|
||||
[[ "$(id -u)" = 0 ]] || return
|
||||
|
||||
# Allow Azure Pipelines/Docker/Concourse/Kubernetes to do everything as root (as it's normal there)
|
||||
[[ -f /proc/1/cgroup ]] && grep -E "azpl_job|docker|garden|kubepods" -q /proc/1/cgroup && return
|
||||
# Allow Azure Pipelines/GitHub Actions/Docker/Concourse/Kubernetes to do everything as root (as it's normal there)
|
||||
[[ -f /proc/1/cgroup ]] && grep -E "azpl_job|actions_job|docker|garden|kubepods" -q /proc/1/cgroup && return
|
||||
|
||||
# Homebrew Services may need `sudo` for system-wide daemons.
|
||||
[[ "$HOMEBREW_COMMAND" = "services" ]] && return
|
||||
|
||||
@ -208,11 +208,12 @@ rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
# BuildErrors are specific to build processes and not other
|
||||
# children, which is why we create the necessary state here
|
||||
# and not in Utils.safe_fork.
|
||||
if error_hash["json_class"] == "BuildError"
|
||||
case error_hash["json_class"]
|
||||
when "BuildError"
|
||||
error_hash["cmd"] = e.cmd
|
||||
error_hash["args"] = e.args
|
||||
error_hash["env"] = e.env
|
||||
elsif error_hash["json_class"] == "ErrorDuringExecution"
|
||||
when "ErrorDuringExecution"
|
||||
error_hash["cmd"] = e.cmd
|
||||
error_hash["status"] = e.status.exitstatus
|
||||
error_hash["output"] = e.output
|
||||
|
||||
@ -77,7 +77,7 @@ module Cask
|
||||
Manpage,
|
||||
PostflightBlock,
|
||||
Zap,
|
||||
].each_with_index.flat_map { |classes, i| [*classes].map { |c| [c, i] } }.to_h
|
||||
].each_with_index.flat_map { |classes, i| Array(classes).map { |c| [c, i] } }.to_h
|
||||
|
||||
(@@sort_order[self.class] <=> @@sort_order[other.class]).to_i
|
||||
end
|
||||
|
||||
@ -34,7 +34,7 @@ module Cask
|
||||
directives.assert_valid_keys!(*ORDERED_DIRECTIVES)
|
||||
|
||||
super(cask)
|
||||
directives[:signal] = [*directives[:signal]].flatten.each_slice(2).to_a
|
||||
directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a
|
||||
@directives = directives
|
||||
|
||||
return unless directives.key?(:kext)
|
||||
@ -49,7 +49,7 @@ module Cask
|
||||
end
|
||||
|
||||
def summarize
|
||||
to_h.flat_map { |key, val| [*val].map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ")
|
||||
to_h.flat_map { |key, val| Array(val).map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -3,58 +3,69 @@
|
||||
module Cask
|
||||
class Cmd
|
||||
class List < AbstractCommand
|
||||
option "-1", :one, false
|
||||
option "--versions", :versions, false
|
||||
option "--full-name", :full_name, false
|
||||
option "-1", :one, false
|
||||
option "--versions", :versions, false
|
||||
option "--full-name", :full_name, false
|
||||
option "--json", :json, false
|
||||
|
||||
def run
|
||||
args.any? ? list : list_installed
|
||||
def self.usage
|
||||
<<~EOS
|
||||
`cask list`, `cask ls` [<options>] [<casks>]
|
||||
|
||||
-1 - Force output to be one entry per line.
|
||||
This is the default when output is not to a terminal.
|
||||
--versions - Show the version number for installed formulae, or only the specified
|
||||
casks if <casks> are provided.
|
||||
--full-name - Print casks with fully-qualified names.
|
||||
--json - Print a JSON representation of <cask>. See the docs for examples of using the JSON
|
||||
output: <https://docs.brew.sh/Querying-Brew>
|
||||
|
||||
List all installed casks.
|
||||
|
||||
If <casks> are provided, limit information to just those casks.
|
||||
EOS
|
||||
end
|
||||
|
||||
def list
|
||||
def self.help
|
||||
"lists installed Casks or the casks provided in the arguments"
|
||||
end
|
||||
|
||||
def run
|
||||
output = args.any? ? provided_list : Caskroom.casks
|
||||
|
||||
if json?
|
||||
puts JSON.generate(output.map(&:to_h))
|
||||
elsif one?
|
||||
puts output.map(&:to_s)
|
||||
elsif full_name?
|
||||
puts output.map(&:full_name).sort(&tap_and_name_comparison)
|
||||
elsif versions?
|
||||
puts output.map(&self.class.method(:format_versioned))
|
||||
elsif !output.empty? && args.any?
|
||||
puts output.map(&self.class.method(:list_artifacts))
|
||||
elsif !output.empty?
|
||||
puts Formatter.columns(output.map(&:to_s))
|
||||
end
|
||||
end
|
||||
|
||||
def provided_list
|
||||
casks.each do |cask|
|
||||
raise CaskNotInstalledError, cask unless cask.installed?
|
||||
|
||||
if one?
|
||||
puts cask.token
|
||||
elsif versions?
|
||||
puts self.class.format_versioned(cask)
|
||||
else
|
||||
cask = CaskLoader.load(cask.installed_caskfile)
|
||||
self.class.list_artifacts(cask)
|
||||
end
|
||||
end
|
||||
casks
|
||||
end
|
||||
|
||||
def self.list_artifacts(cask)
|
||||
cask.artifacts.group_by(&:class).each do |klass, artifacts|
|
||||
next unless klass.respond_to?(:english_description)
|
||||
|
||||
ohai klass.english_description, artifacts.map(&:summarize_installed)
|
||||
end
|
||||
end
|
||||
|
||||
def list_installed
|
||||
installed_casks = Caskroom.casks
|
||||
|
||||
if one?
|
||||
puts installed_casks.map(&:to_s)
|
||||
elsif versions?
|
||||
puts installed_casks.map(&self.class.method(:format_versioned))
|
||||
elsif full_name?
|
||||
puts installed_casks.map(&:full_name).sort(&tap_and_name_comparison)
|
||||
elsif !installed_casks.empty?
|
||||
puts Formatter.columns(installed_casks.map(&:to_s))
|
||||
return "==> #{klass.english_description}", artifacts.map(&:summarize_installed)
|
||||
end
|
||||
end
|
||||
|
||||
def self.format_versioned(cask)
|
||||
cask.to_s.concat(cask.versions.map(&:to_s).join(" ").prepend(" "))
|
||||
end
|
||||
|
||||
def self.help
|
||||
"with no args, lists installed Casks; given installed Casks, lists staged files"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -18,7 +18,7 @@ module Cask
|
||||
def initialize(**pairs)
|
||||
pairs.assert_valid_keys!(*VALID_KEYS)
|
||||
|
||||
super(pairs.transform_values { |v| Set.new([*v]) })
|
||||
super(pairs.transform_values { |v| Set.new(Array(v)) })
|
||||
|
||||
self.default = Set.new
|
||||
end
|
||||
|
||||
@ -328,8 +328,12 @@ module Cask
|
||||
|
||||
def missing_cask_and_formula_dependencies
|
||||
collect_cask_and_formula_dependencies.reject do |cask_or_formula|
|
||||
(cask_or_formula.try(:installed?) || cask_or_formula.try(:any_version_installed?)) &&
|
||||
(cask_or_formula.respond_to?(:opt_linked?) ? cask_or_formula.opt_linked? : true)
|
||||
installed = if cask_or_formula.respond_to?(:any_version_installed?)
|
||||
cask_or_formula.any_version_installed?
|
||||
else
|
||||
cask_or_formula.try(:installed?)
|
||||
end
|
||||
installed && (cask_or_formula.respond_to?(:opt_linked?) ? cask_or_formula.opt_linked? : true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -15,13 +15,21 @@ module CleanupRefinement
|
||||
end
|
||||
|
||||
def nested_cache?
|
||||
directory? && %w[cargo_cache go_cache glide_home java_cache npm_cache gclient_cache].include?(basename.to_s)
|
||||
directory? && %w[
|
||||
cargo_cache
|
||||
go_cache
|
||||
go_mod_cache
|
||||
glide_home
|
||||
java_cache
|
||||
npm_cache
|
||||
gclient_cache
|
||||
].include?(basename.to_s)
|
||||
end
|
||||
|
||||
def go_cache_directory?
|
||||
# Go makes its cache contents read-only to ensure cache integrity,
|
||||
# which makes sense but is something we need to undo for cleanup.
|
||||
directory? && %w[go_cache].include?(basename.to_s)
|
||||
directory? && %w[go_cache go_mod_cache].include?(basename.to_s)
|
||||
end
|
||||
|
||||
def prune?(days)
|
||||
@ -302,6 +310,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def cleanup_path(path)
|
||||
return unless path.exist?
|
||||
return unless @cleaned_up_paths.add?(path)
|
||||
|
||||
disk_usage = path.disk_usage
|
||||
|
||||
@ -213,10 +213,11 @@ module Homebrew
|
||||
end
|
||||
|
||||
def min_named(count_or_type)
|
||||
if count_or_type.is_a?(Integer)
|
||||
case count_or_type
|
||||
when Integer
|
||||
@min_named_args = count_or_type
|
||||
@min_named_type = nil
|
||||
elsif count_or_type.is_a?(Symbol)
|
||||
when Symbol
|
||||
@min_named_args = 1
|
||||
@min_named_type = count_or_type
|
||||
else
|
||||
@ -225,10 +226,11 @@ module Homebrew
|
||||
end
|
||||
|
||||
def named(count_or_type)
|
||||
if count_or_type.is_a?(Integer)
|
||||
case count_or_type
|
||||
when Integer
|
||||
@max_named_args = @min_named_args = count_or_type
|
||||
@min_named_type = nil
|
||||
elsif count_or_type.is_a?(Symbol)
|
||||
when Symbol
|
||||
@max_named_args = @min_named_args = 1
|
||||
@min_named_type = count_or_type
|
||||
else
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
require "metafiles"
|
||||
require "formula"
|
||||
require "cli/parser"
|
||||
require "cask/cmd"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
@ -31,6 +32,8 @@ module Homebrew
|
||||
switch "--pinned",
|
||||
description: "Show the versions of pinned formulae, or only the specified (pinned) "\
|
||||
"formulae if <formula> are provided. See also `pin`, `unpin`."
|
||||
switch "--cask",
|
||||
description: "List casks"
|
||||
# passed through to ls
|
||||
switch "-1",
|
||||
description: "Force output to be one entry per line. " \
|
||||
@ -44,12 +47,15 @@ module Homebrew
|
||||
description: "Sort by time modified, listing most recently modified first."
|
||||
switch :verbose
|
||||
switch :debug
|
||||
["--unbrewed", "--multiple", "--pinned", "-l", "-r", "-t"].each { |flag| conflicts "--cask", flag }
|
||||
end
|
||||
end
|
||||
|
||||
def list
|
||||
list_args.parse
|
||||
|
||||
return list_casks if args.cask?
|
||||
|
||||
return list_unbrewed if args.unbrewed?
|
||||
|
||||
# Unbrewed uses the PREFIX, which will exist
|
||||
@ -150,6 +156,14 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def list_casks
|
||||
cask_list = Cask::Cmd::List.new args.named
|
||||
cask_list.one = ARGV.include? "-1"
|
||||
cask_list.versions = args.versions?
|
||||
cask_list.full_name = args.full_name?
|
||||
cask_list.run
|
||||
end
|
||||
end
|
||||
|
||||
class PrettyListing
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
#: Consider adding evaluation of this command's output to your dotfiles (e.g. `~/.profile`, `~/.bash_profile`, or `~/.zprofile`) with: `eval $(brew shellenv)`
|
||||
|
||||
homebrew-shellenv() {
|
||||
case "$SHELL" in
|
||||
*/fish|fish)
|
||||
case "$(/bin/ps -p $PPID -o comm=)" in
|
||||
fish|-fish)
|
||||
echo "set -gx HOMEBREW_PREFIX \"$HOMEBREW_PREFIX\";"
|
||||
echo "set -gx HOMEBREW_CELLAR \"$HOMEBREW_CELLAR\";"
|
||||
echo "set -gx HOMEBREW_REPOSITORY \"$HOMEBREW_REPOSITORY\";"
|
||||
@ -15,7 +15,7 @@ homebrew-shellenv() {
|
||||
echo "set -q MANPATH; or set MANPATH ''; set -gx MANPATH \"$HOMEBREW_PREFIX/share/man\" \$MANPATH;"
|
||||
echo "set -q INFOPATH; or set INFOPATH ''; set -gx INFOPATH \"$HOMEBREW_PREFIX/share/info\" \$INFOPATH;"
|
||||
;;
|
||||
*/csh|csh|*/tcsh|tcsh)
|
||||
csh|-csh|tcsh|-tcsh)
|
||||
echo "setenv HOMEBREW_PREFIX $HOMEBREW_PREFIX;"
|
||||
echo "setenv HOMEBREW_CELLAR $HOMEBREW_CELLAR;"
|
||||
echo "setenv HOMEBREW_REPOSITORY $HOMEBREW_REPOSITORY;"
|
||||
@ -29,7 +29,7 @@ homebrew-shellenv() {
|
||||
echo "export HOMEBREW_REPOSITORY=\"$HOMEBREW_REPOSITORY\";"
|
||||
echo "export PATH=\"$HOMEBREW_PREFIX/bin:$HOMEBREW_PREFIX/sbin\${PATH+:\$PATH}\";"
|
||||
echo "export MANPATH=\"$HOMEBREW_PREFIX/share/man\${MANPATH+:\$MANPATH}:\";"
|
||||
echo "export INFOPATH=\"$HOMEBREW_PREFIX/share/info:\${INFOPATH}\";"
|
||||
echo "export INFOPATH=\"$HOMEBREW_PREFIX/share/info:\${INFOPATH:-}\";"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -199,10 +199,11 @@ class Reporter
|
||||
|
||||
if paths.any? { |p| tap.cask_file?(p) }
|
||||
# Currently only need to handle Cask deletion/migration.
|
||||
if status == "D"
|
||||
case status
|
||||
when "D"
|
||||
# Have a dedicated report array for deleted casks.
|
||||
@report[:DC] << tap.formula_file_to_name(src)
|
||||
elsif status == "M"
|
||||
when "M"
|
||||
# Report updated casks
|
||||
@report[:MC] << tap.formula_file_to_name(src)
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
||||
|
||||
require "irb"
|
||||
|
||||
# @private
|
||||
module IRB
|
||||
@setup_done = false
|
||||
|
||||
|
||||
@ -231,11 +231,6 @@ module Homebrew
|
||||
end
|
||||
|
||||
def audit_file
|
||||
# TODO: check could be in RuboCop
|
||||
if text.to_s.match?(/inreplace [^\n]* do [^\n]*\n[^\n]*\.gsub![^\n]*\n\ *end/m)
|
||||
problem "'inreplace ... do' was used for a single substitution (use the non-block form instead)."
|
||||
end
|
||||
|
||||
if formula.core_formula? && @versioned_formula
|
||||
unversioned_formula = begin
|
||||
# build this ourselves as we want e.g. homebrew/core to be present
|
||||
@ -564,6 +559,7 @@ module Homebrew
|
||||
|
||||
_, user, repo = *regex.match(formula.stable.url) if formula.stable
|
||||
_, user, repo = *regex.match(formula.homepage) unless user
|
||||
_, user, repo = *regex.match(formula.head.url) if !user && formula.head
|
||||
return if !user || !repo
|
||||
|
||||
repo.delete_suffix!(".git")
|
||||
@ -576,13 +572,13 @@ module Homebrew
|
||||
imagemagick@6
|
||||
].freeze
|
||||
|
||||
THROTTLED_DENYLIST = {
|
||||
"aws-sdk-cpp" => "10",
|
||||
"awscli@1" => "10",
|
||||
"balena-cli" => "10",
|
||||
"gatsby-cli" => "10",
|
||||
"quicktype" => "10",
|
||||
"vim" => "50",
|
||||
THROTTLED_FORMULAE = {
|
||||
"aws-sdk-cpp" => 10,
|
||||
"awscli@1" => 10,
|
||||
"balena-cli" => 10,
|
||||
"gatsby-cli" => 10,
|
||||
"quicktype" => 10,
|
||||
"vim" => 50,
|
||||
}.freeze
|
||||
|
||||
UNSTABLE_ALLOWLIST = {
|
||||
@ -611,7 +607,7 @@ module Homebrew
|
||||
"libepoxy" => "1.5",
|
||||
}.freeze
|
||||
|
||||
GITHUB_PRERELEASE_ALLOWLIST = %w[cake].freeze
|
||||
GITHUB_PRERELEASE_ALLOWLIST = %w[].freeze
|
||||
|
||||
# version_prefix = stable_version_string.sub(/\d+$/, "")
|
||||
# version_prefix = stable_version_string.split(".")[0..1].join(".")
|
||||
@ -668,19 +664,10 @@ module Homebrew
|
||||
problem "Formulae in homebrew/core should not have a `devel` spec" if formula.devel
|
||||
|
||||
if formula.head && @versioned_formula
|
||||
head_spec_message = "Formulae should not have a `HEAD` spec"
|
||||
head_spec_message = "Versioned formulae should not have a `HEAD` spec"
|
||||
problem head_spec_message unless VERSIONED_HEAD_SPEC_ALLOWLIST.include?(formula.name)
|
||||
end
|
||||
|
||||
THROTTLED_DENYLIST.each do |f, v|
|
||||
next if formula.stable.nil?
|
||||
|
||||
version = formula.stable.version.to_s.split(".").last.to_i
|
||||
if f == formula.name && version.modulo(v.to_i).nonzero?
|
||||
problem "should only be updated every #{v} releases on multiples of #{v}"
|
||||
end
|
||||
end
|
||||
|
||||
stable = formula.stable
|
||||
return unless stable
|
||||
return unless stable.url
|
||||
@ -691,6 +678,12 @@ module Homebrew
|
||||
.split(".", 3)
|
||||
.map(&:to_i)
|
||||
|
||||
formula_suffix = stable_version_string.split(".").last.to_i
|
||||
throttled_rate = THROTTLED_FORMULAE[formula.name]
|
||||
if throttled_rate && formula_suffix.modulo(throttled_rate).nonzero?
|
||||
problem "should only be updated every #{throttled_rate} releases on multiples of #{throttled_rate}"
|
||||
end
|
||||
|
||||
case (url = stable.url)
|
||||
when /[\d._-](alpha|beta|rc\d)/
|
||||
matched = Regexp.last_match(1)
|
||||
@ -830,73 +823,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def audit_lines
|
||||
text.without_patch.split("\n").each_with_index do |line, lineno|
|
||||
line_problems(line, lineno + 1)
|
||||
end
|
||||
end
|
||||
|
||||
def line_problems(line, _lineno)
|
||||
# Check for string interpolation of single values.
|
||||
if line =~ /(system|inreplace|gsub!|change_make_var!).*[ ,]"#\{([\w.]+)\}"/
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Don't need to interpolate \"#{Regexp.last_match(2)}\" with #{Regexp.last_match(1)}"
|
||||
end
|
||||
|
||||
# Check for string concatenation; prefer interpolation
|
||||
if line =~ /(#\{\w+\s*\+\s*['"][^}]+\})/
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Try not to concatenate paths in string interpolation:\n #{Regexp.last_match(1)}"
|
||||
end
|
||||
|
||||
# Prefer formula path shortcuts in Pathname+
|
||||
if line =~ %r{\(\s*(prefix\s*\+\s*(['"])(bin|include|libexec|lib|sbin|share|Frameworks)[/'"])}
|
||||
# TODO: check could be in RuboCop
|
||||
problem(
|
||||
"\"(#{Regexp.last_match(1)}...#{Regexp.last_match(2)})\" should" \
|
||||
" be \"(#{Regexp.last_match(3).downcase}+...)\"",
|
||||
)
|
||||
end
|
||||
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Use separate make calls" if line.include?("make && make")
|
||||
|
||||
if line =~ /JAVA_HOME/i &&
|
||||
[formula.name, *formula.deps.map(&:name)].none? { |name| name.match?(/^openjdk(@|$)/) } &&
|
||||
formula.requirements.none? { |req| req.is_a?(JavaRequirement) }
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Use `depends_on :java` to set JAVA_HOME"
|
||||
end
|
||||
|
||||
return unless @strict
|
||||
|
||||
# TODO: check could be in RuboCop
|
||||
problem "`env :userpaths` in formulae is deprecated" if line.include?("env :userpaths")
|
||||
|
||||
# TODO: check could be in RuboCop
|
||||
problem "`#{Regexp.last_match(1)}` is now unnecessary" if line =~ /(require ["']formula["'])/
|
||||
|
||||
if line.match?(%r{#\{share\}/#{Regexp.escape(formula.name)}[/'"]})
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Use \#{pkgshare} instead of \#{share}/#{formula.name}"
|
||||
end
|
||||
|
||||
if !@core_tap && line =~ /depends_on .+ if build\.with(out)?\?\(?["']\w+["']\)?/
|
||||
# TODO: check could be in RuboCop
|
||||
problem "`Use :optional` or `:recommended` instead of `#{Regexp.last_match(0)}`"
|
||||
end
|
||||
|
||||
if line =~ %r{share(\s*[/+]\s*)(['"])#{Regexp.escape(formula.name)}(?:\2|/)}
|
||||
# TODO: check could be in RuboCop
|
||||
problem "Use pkgshare instead of (share#{Regexp.last_match(1)}\"#{formula.name}\")"
|
||||
end
|
||||
|
||||
return unless @core_tap
|
||||
|
||||
# TODO: check could be in RuboCop
|
||||
problem "`env :std` in homebrew/core formulae is deprecated" if line.include?("env :std")
|
||||
end
|
||||
|
||||
def audit_reverse_migration
|
||||
# Only enforce for new formula being re-added to core
|
||||
return unless @strict
|
||||
|
||||
@ -446,10 +446,10 @@ module Homebrew
|
||||
first
|
||||
elsif second.start_with?("/")
|
||||
second
|
||||
elsif cellars.include?(:any)
|
||||
:any
|
||||
elsif cellars.include?(:any_skip_relocation)
|
||||
:any_skip_relocation
|
||||
elsif cellars.include?("any")
|
||||
"any"
|
||||
elsif cellars.include?("any_skip_relocation")
|
||||
"any_skip_relocation"
|
||||
else
|
||||
second
|
||||
end
|
||||
|
||||
@ -18,7 +18,11 @@ module Homebrew
|
||||
be made if either or both values are not supplied by the user.
|
||||
|
||||
If a <tag> is specified, the Git commit <revision> corresponding to that tag
|
||||
must also be specified.
|
||||
should also be specified. A best effort to determine the <revision> will be made
|
||||
if the value is not supplied by the user.
|
||||
|
||||
If a <version> is specified, a best effort to determine the <URL> and <SHA-256> or
|
||||
the <tag> and <revision> will be made if both values are not supplied by the user.
|
||||
|
||||
*Note:* this command cannot be used to transition a formula from a
|
||||
URL-and-SHA-256 style specification into a tag-and-revision style specification,
|
||||
@ -58,8 +62,8 @@ module Homebrew
|
||||
flag "--tag=",
|
||||
description: "Specify the new git commit <tag> for the formula."
|
||||
flag "--revision=",
|
||||
required_for: "--tag=",
|
||||
description: "Specify the new git commit <revision> corresponding to the specified <tag>."
|
||||
depends_on: "--tag=",
|
||||
description: "Specify the new git commit <revision> corresponding to the specified <tag>."
|
||||
switch :force
|
||||
switch :quiet
|
||||
switch :verbose
|
||||
@ -119,34 +123,14 @@ module Homebrew
|
||||
formula = args.formulae.first
|
||||
|
||||
new_url = args.url
|
||||
if new_url && !formula
|
||||
# Split the new URL on / and find any formulae that have the same URL
|
||||
# except for the last component, but don't try to match any more than the
|
||||
# first five components since sometimes the last component isn't the only
|
||||
# one to change.
|
||||
new_url_split = new_url.split("/")
|
||||
maximum_url_components_to_match = 5
|
||||
components_to_match = [new_url_split.count - 1, maximum_url_components_to_match].min
|
||||
base_url = new_url_split.first(components_to_match).join("/")
|
||||
base_url = /#{Regexp.escape(base_url)}/
|
||||
is_devel = args.devel?
|
||||
guesses = []
|
||||
Formula.each do |f|
|
||||
if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url)
|
||||
guesses << f
|
||||
elsif f.stable&.url && f.stable.url.match(base_url)
|
||||
guesses << f
|
||||
end
|
||||
end
|
||||
if guesses.count == 1
|
||||
formula = guesses.shift
|
||||
elsif guesses.count > 1
|
||||
odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}"
|
||||
end
|
||||
end
|
||||
formula ||= determine_formula_from_url(new_url, args.devel?) if new_url
|
||||
raise FormulaUnspecifiedError unless formula
|
||||
|
||||
tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
|
||||
check_open_pull_requests(formula, tap_full_name)
|
||||
|
||||
new_version = args.version
|
||||
check_all_pull_requests(formula, tap_full_name, version: new_version) if new_version
|
||||
|
||||
requested_spec, formula_spec = if args.devel?
|
||||
devel_message = " (devel)"
|
||||
@ -175,28 +159,44 @@ module Homebrew
|
||||
new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian"
|
||||
end
|
||||
new_mirrors ||= [new_mirror] unless new_mirror.nil?
|
||||
forced_version = args.version
|
||||
old_url = formula_spec.url
|
||||
old_tag = formula_spec.specs[:tag]
|
||||
old_formula_version = formula_version(formula, requested_spec)
|
||||
old_version = old_formula_version.to_s
|
||||
forced_version = new_version.present?
|
||||
new_url_hash = if new_url && new_hash
|
||||
check_all_pull_requests(formula, tap_full_name, url: new_url) unless new_version
|
||||
true
|
||||
elsif new_tag && new_revision
|
||||
check_all_pull_requests(formula, tap_full_name, url: old_url, tag: new_tag) unless new_version
|
||||
false
|
||||
elsif !hash_type
|
||||
odie "#{formula}: no --tag=/--revision= arguments specified!"
|
||||
elsif !new_url
|
||||
odie "#{formula}: no --url= argument specified!"
|
||||
else
|
||||
resource = Resource.new { @url = new_url }
|
||||
resource.download_strategy = DownloadStrategyDetector.detect_from_url(new_url)
|
||||
resource.owner = Resource.new(formula.name)
|
||||
if forced_version
|
||||
if forced_version == resource.version
|
||||
forced_version = nil
|
||||
else
|
||||
resource.version = forced_version
|
||||
end
|
||||
odie "#{formula}: no --tag= or --version= argument specified!" if !new_tag && !new_version
|
||||
new_tag ||= old_tag.gsub(old_version, new_version)
|
||||
if new_tag == old_tag
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since the new tag
|
||||
and old tag are both #{new_tag}.
|
||||
EOS
|
||||
end
|
||||
odie "No --version= argument specified!" unless resource.version
|
||||
resource_path = resource.fetch
|
||||
check_all_pull_requests(formula, tap_full_name, url: old_url, tag: new_tag) unless new_version
|
||||
resource_path, forced_version = fetch_resource(formula, new_version, old_url, tag: new_tag)
|
||||
new_revision = Utils.popen_read("git -C \"#{resource_path}\" rev-parse -q --verify HEAD")
|
||||
new_revision = new_revision.strip
|
||||
false
|
||||
elsif !new_url && !new_version
|
||||
odie "#{formula}: no --url= or --version= argument specified!"
|
||||
else
|
||||
new_url ||= old_url.gsub(old_version, new_version)
|
||||
if new_url == old_url
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since the new URL
|
||||
and old URL are both:
|
||||
#{new_url}
|
||||
EOS
|
||||
end
|
||||
check_all_pull_requests(formula, tap_full_name, url: new_url) unless new_version
|
||||
resource_path, forced_version = fetch_resource(formula, new_version, new_url)
|
||||
tar_file_extensions = %w[.tar .tb2 .tbz .tbz2 .tgz .tlz .txz .tZ]
|
||||
if tar_file_extensions.any? { |extension| new_url.include? extension }
|
||||
gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar"
|
||||
@ -212,8 +212,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
old_formula_version = formula_version(formula, requested_spec)
|
||||
|
||||
replacement_pairs = []
|
||||
if requested_spec == :stable && formula.revision.nonzero?
|
||||
replacement_pairs << [
|
||||
@ -253,7 +251,7 @@ module Homebrew
|
||||
]
|
||||
end
|
||||
|
||||
backup_file = File.read(formula.path) unless args.dry_run?
|
||||
old_contents = File.read(formula.path) unless args.dry_run?
|
||||
|
||||
if new_mirrors
|
||||
replacement_pairs << [
|
||||
@ -273,44 +271,46 @@ module Homebrew
|
||||
]
|
||||
end
|
||||
|
||||
if forced_version && forced_version != "0"
|
||||
if requested_spec == :stable
|
||||
if forced_version && new_version != "0"
|
||||
case requested_spec
|
||||
when :stable
|
||||
replacement_pairs << if File.read(formula.path).include?("version \"#{old_formula_version}\"")
|
||||
[
|
||||
old_formula_version.to_s,
|
||||
forced_version,
|
||||
new_version,
|
||||
]
|
||||
elsif new_mirrors
|
||||
[
|
||||
/^( +)(mirror "#{Regexp.escape(new_mirrors.last)}"\n)/m,
|
||||
"\\1\\2\\1version \"#{forced_version}\"\n",
|
||||
"\\1\\2\\1version \"#{new_version}\"\n",
|
||||
]
|
||||
else
|
||||
[
|
||||
/^( +)(url "#{Regexp.escape(new_url)}"\n)/m,
|
||||
"\\1\\2\\1version \"#{forced_version}\"\n",
|
||||
"\\1\\2\\1version \"#{new_version}\"\n",
|
||||
]
|
||||
end
|
||||
elsif requested_spec == :devel
|
||||
when :devel
|
||||
replacement_pairs << [
|
||||
/( devel do.+?version ")#{old_formula_version}("\n.+?end\n)/m,
|
||||
"\\1#{forced_version}\\2",
|
||||
"\\1#{new_version}\\2",
|
||||
]
|
||||
end
|
||||
elsif forced_version && forced_version == "0"
|
||||
if requested_spec == :stable
|
||||
elsif forced_version && new_version == "0"
|
||||
case requested_spec
|
||||
when :stable
|
||||
replacement_pairs << [
|
||||
/^ version "[\w.\-+]+"\n/m,
|
||||
"",
|
||||
]
|
||||
elsif requested_spec == :devel
|
||||
when :devel
|
||||
replacement_pairs << [
|
||||
/( devel do.+?)^ +version "[^\n]+"\n(.+?end\n)/m,
|
||||
"\\1\\2",
|
||||
]
|
||||
end
|
||||
end
|
||||
new_contents = inreplace_pairs(formula.path, replacement_pairs)
|
||||
new_contents = inreplace_pairs(formula.path, replacement_pairs.uniq)
|
||||
|
||||
new_formula_version = formula_version(formula, requested_spec, new_contents)
|
||||
|
||||
@ -328,13 +328,13 @@ module Homebrew
|
||||
end
|
||||
|
||||
if new_formula_version < old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless args.dry_run?
|
||||
formula.path.atomic_write(old_contents) unless args.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since changing the
|
||||
version from #{old_formula_version} to #{new_formula_version} would be a downgrade.
|
||||
EOS
|
||||
elsif new_formula_version == old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless args.dry_run?
|
||||
formula.path.atomic_write(old_contents) unless args.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since the new version
|
||||
and old version are both #{new_formula_version}.
|
||||
@ -347,7 +347,7 @@ module Homebrew
|
||||
alias_rename.map! { |a| formula.tap.alias_dir/a }
|
||||
end
|
||||
|
||||
run_audit(formula, alias_rename, backup_file)
|
||||
run_audit(formula, alias_rename, old_contents)
|
||||
|
||||
formula.path.parent.cd do
|
||||
branch = "#{formula.name}-#{new_formula_version}"
|
||||
@ -372,7 +372,7 @@ module Homebrew
|
||||
remote_url = Utils.popen_read("git remote get-url --push origin").chomp
|
||||
username = formula.tap.user
|
||||
else
|
||||
remote_url, username = forked_repo_info(formula, tap_full_name, backup_file)
|
||||
remote_url, username = forked_repo_info(formula, tap_full_name, old_contents)
|
||||
end
|
||||
|
||||
safe_system "git", "fetch", "--unshallow", "origin" if shallow
|
||||
@ -411,10 +411,44 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def forked_repo_info(formula, tap_full_name, backup_file)
|
||||
def determine_formula_from_url(url, is_devel)
|
||||
# Split the new URL on / and find any formulae that have the same URL
|
||||
# except for the last component, but don't try to match any more than the
|
||||
# first five components since sometimes the last component isn't the only
|
||||
# one to change.
|
||||
url_split = url.split("/")
|
||||
maximum_url_components_to_match = 5
|
||||
components_to_match = [url_split.count - 1, maximum_url_components_to_match].min
|
||||
base_url = url_split.first(components_to_match).join("/")
|
||||
base_url = /#{Regexp.escape(base_url)}/
|
||||
guesses = []
|
||||
Formula.each do |f|
|
||||
if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url)
|
||||
guesses << f
|
||||
elsif f.stable&.url && f.stable.url.match(base_url)
|
||||
guesses << f
|
||||
end
|
||||
end
|
||||
return guesses.shift if guesses.count == 1
|
||||
return unless guesses.count > 1
|
||||
|
||||
odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}"
|
||||
end
|
||||
|
||||
def fetch_resource(formula, new_version, url, **specs)
|
||||
resource = Resource.new
|
||||
resource.url(url, specs)
|
||||
resource.owner = Resource.new(formula.name)
|
||||
forced_version = new_version && new_version != resource.version
|
||||
resource.version = new_version if forced_version
|
||||
odie "No --version= argument specified!" unless resource.version
|
||||
[resource.fetch, forced_version]
|
||||
end
|
||||
|
||||
def forked_repo_info(formula, tap_full_name, old_contents)
|
||||
response = GitHub.create_fork(tap_full_name)
|
||||
rescue GitHub::AuthenticationFailedError, *GitHub.api_errors => e
|
||||
formula.path.atomic_write(backup_file)
|
||||
formula.path.atomic_write(old_contents)
|
||||
odie "Unable to fork: #{e.message}!"
|
||||
else
|
||||
# GitHub API responds immediately but fork takes a few seconds to be ready.
|
||||
@ -503,7 +537,7 @@ module Homebrew
|
||||
[versioned_alias, "#{name}@#{new_alias_version}"]
|
||||
end
|
||||
|
||||
def run_audit(formula, alias_rename, backup_file)
|
||||
def run_audit(formula, alias_rename, old_contents)
|
||||
if args.dry_run?
|
||||
if args.no_audit?
|
||||
ohai "Skipping `brew audit`"
|
||||
@ -527,7 +561,7 @@ module Homebrew
|
||||
end
|
||||
return unless failed_audit
|
||||
|
||||
formula.path.atomic_write(backup_file)
|
||||
formula.path.atomic_write(old_contents)
|
||||
FileUtils.mv alias_rename.last, alias_rename.first if alias_rename.present?
|
||||
odie "`brew audit` failed!"
|
||||
end
|
||||
|
||||
@ -42,7 +42,12 @@ module Homebrew
|
||||
[checksum.hash_type, checksum.hexdigest]
|
||||
end
|
||||
|
||||
old = if formula.path.read.include?("stable do\n")
|
||||
old = if formula.license
|
||||
# insert replacement revision after license
|
||||
<<~EOS
|
||||
license "#{formula.license}"
|
||||
EOS
|
||||
elsif formula.path.read.include?("stable do\n")
|
||||
# insert replacement revision after homepage
|
||||
<<~EOS
|
||||
homepage "#{formula.homepage}"
|
||||
|
||||
@ -29,6 +29,8 @@ module Homebrew
|
||||
description: "Create a basic template for a Go build."
|
||||
switch "--meson",
|
||||
description: "Create a basic template for a Meson-style build."
|
||||
switch "--node",
|
||||
description: "Create a basic template for a Node build."
|
||||
switch "--perl",
|
||||
description: "Create a basic template for a Perl build."
|
||||
switch "--python",
|
||||
@ -54,7 +56,7 @@ module Homebrew
|
||||
switch :force
|
||||
switch :verbose
|
||||
switch :debug
|
||||
conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--perl", "--python", "--rust"
|
||||
conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--node", "--perl", "--python", "--rust"
|
||||
named 1
|
||||
end
|
||||
end
|
||||
@ -92,6 +94,8 @@ module Homebrew
|
||||
:crystal
|
||||
elsif args.go?
|
||||
:go
|
||||
elsif args.node?
|
||||
:node
|
||||
elsif args.perl?
|
||||
:perl
|
||||
elsif args.python?
|
||||
|
||||
@ -124,10 +124,11 @@ module Homebrew
|
||||
ronn.close_write
|
||||
ronn_output = ronn.read
|
||||
odie "Got no output from ronn!" if ronn_output.blank?
|
||||
if format_flag == "--markdown"
|
||||
case format_flag
|
||||
when "--markdown"
|
||||
ronn_output = ronn_output.gsub(%r{<var>(.*?)</var>}, "*`\\1`*")
|
||||
.gsub(/\n\n\n+/, "\n\n")
|
||||
elsif format_flag == "--roff"
|
||||
when "--roff"
|
||||
ronn_output = ronn_output.gsub(%r{<code>(.*?)</code>}, "\\fB\\1\\fR")
|
||||
.gsub(%r{<var>(.*?)</var>}, "\\fI\\1\\fR")
|
||||
.gsub(/(^\[?\\fB.+): /, "\\1\n ")
|
||||
|
||||
@ -1,28 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "commands"
|
||||
require "cli/parser"
|
||||
require "json"
|
||||
require "net/http"
|
||||
require "open-uri"
|
||||
require "utils/github"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
|
||||
SPDX_PATH = (HOMEBREW_LIBRARY_PATH/"data/spdx.json").freeze
|
||||
SPDX_DATA_URL = "https://raw.githubusercontent.com/spdx/license-list-data/HEAD/json/licenses.json"
|
||||
SPDX_API_URL = "https://api.github.com/repos/spdx/license-list-data/releases/latest"
|
||||
|
||||
def update_license_data_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
usage_banner <<~EOS
|
||||
`update_license_data` <cmd>
|
||||
`update-license-data` [<options>]
|
||||
|
||||
Update SPDX license data in the Homebrew repository.
|
||||
EOS
|
||||
switch "--fail-if-changed",
|
||||
description: "Return a failing status code if current license data's version is different from " \
|
||||
switch "--fail-if-not-changed",
|
||||
description: "Return a failing status code if current license data's version is the same as " \
|
||||
"the upstream. This can be used to notify CI when the SPDX license data is out of date."
|
||||
|
||||
switch "--commit",
|
||||
description: "Commit changes to the SPDX license data."
|
||||
max_named 0
|
||||
end
|
||||
end
|
||||
@ -30,10 +28,18 @@ module Homebrew
|
||||
def update_license_data
|
||||
update_license_data_args.parse
|
||||
ohai "Updating SPDX license data..."
|
||||
curl_download(SPDX_DATA_URL, to: SPDX_PATH, partial: false)
|
||||
|
||||
return unless args.fail_if_changed?
|
||||
latest_tag = GitHub.open_api(SPDX_API_URL)["tag_name"]
|
||||
data_url = "https://raw.githubusercontent.com/spdx/license-list-data/#{latest_tag}/json/licenses.json"
|
||||
curl_download(data_url, to: SPDX_PATH, partial: false)
|
||||
|
||||
safe_system "git", "diff", "--stat", "--exit-code", SPDX_PATH
|
||||
Homebrew.failed = system("git", "diff", "--stat", "--exit-code", SPDX_PATH) if args.fail_if_not_changed?
|
||||
|
||||
return unless args.commit?
|
||||
|
||||
ohai "git add"
|
||||
safe_system "git", "add", SPDX_PATH
|
||||
ohai "git commit"
|
||||
system "git", "commit", "--message", "data/spdx.json: update to #{latest_tag}"
|
||||
end
|
||||
end
|
||||
|
||||
@ -392,11 +392,11 @@ module Homebrew
|
||||
message = inject_file_list conflicts, <<~EOS
|
||||
/usr/bin occurs before #{HOMEBREW_PREFIX}/bin
|
||||
This means that system-provided programs will be used instead of those
|
||||
provided by Homebrew. The following tools exist at both paths:
|
||||
|
||||
Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin
|
||||
occurs before /usr/bin. Here is a one-liner:
|
||||
provided by Homebrew. Consider setting your PATH so that
|
||||
#{HOMEBREW_PREFIX}/bin occurs before /usr/bin. Here is a one-liner:
|
||||
#{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")}
|
||||
|
||||
The following tools exist at both paths:
|
||||
EOS
|
||||
end
|
||||
end
|
||||
@ -561,7 +561,7 @@ module Homebrew
|
||||
return if !Utils.git_available? || !(coretap_path/".git").exist?
|
||||
|
||||
branch = coretap_path.git_branch
|
||||
return if branch.nil? || branch =~ /master/
|
||||
return if branch.blank? || branch.include?("master")
|
||||
|
||||
<<~EOS
|
||||
#{CoreTap.instance.full_name} is not on the master branch.
|
||||
|
||||
@ -111,6 +111,10 @@ module Homebrew
|
||||
description: "Output this many lines of output on formula `system` failures.",
|
||||
default: 15,
|
||||
},
|
||||
HOMEBREW_FORBIDDEN_LICENSES: {
|
||||
description: "A space-separated list of licenses. Homebrew will refuse to install a " \
|
||||
"formula if that formula or any of its dependencies has a license on this list.",
|
||||
},
|
||||
HOMEBREW_FORCE_BREWED_CURL: {
|
||||
description: "If set, always use a Homebrew-installed `curl`(1) rather than the system version. " \
|
||||
"Automatically set if the system version of `curl` is too old.",
|
||||
|
||||
@ -320,6 +320,18 @@ class FormulaConflictError < RuntimeError
|
||||
end
|
||||
end
|
||||
|
||||
class FormulaUnknownPythonError < RuntimeError
|
||||
def initialize(formula)
|
||||
super <<~EOS
|
||||
The version of Python to use with the virtualenv in the `#{formula.full_name}` formula
|
||||
cannot be guessed automatically because a recognised Python dependency could not be found.
|
||||
|
||||
If you are using a non-standard Python depedency, please add `:using => "python@x.y"` to
|
||||
`virtualenv_install_with_resources` to resolve the issue manually.
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
class FormulaAmbiguousPythonError < RuntimeError
|
||||
def initialize(formula)
|
||||
super <<~EOS
|
||||
@ -494,7 +506,7 @@ class CurlDownloadStrategyError < RuntimeError
|
||||
end
|
||||
end
|
||||
|
||||
# Raised by {#safe_system} in `utils.rb`.
|
||||
# Raised by {Kernel#safe_system} in `utils.rb`.
|
||||
class ErrorDuringExecution < RuntimeError
|
||||
attr_reader :cmd, :status, :output
|
||||
|
||||
@ -512,7 +524,7 @@ class ErrorDuringExecution < RuntimeError
|
||||
redacted_cmd = redact_secrets(cmd.shelljoin.gsub('\=', "="), secrets)
|
||||
s = +"Failure while executing; `#{redacted_cmd}` exited with #{exitstatus}."
|
||||
|
||||
unless [*output].empty?
|
||||
if Array(output).present?
|
||||
format_output_line = lambda do |type_line|
|
||||
type, line = *type_line
|
||||
if type == :stderr
|
||||
@ -531,7 +543,7 @@ class ErrorDuringExecution < RuntimeError
|
||||
end
|
||||
|
||||
def stderr
|
||||
[*output].select { |type,| type == :stderr }.map(&:last).join
|
||||
Array(output).select { |type,| type == :stderr }.map(&:last).join
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -7,11 +7,38 @@ class Formula
|
||||
"#{name}.so#{"." unless version.nil?}#{version}"
|
||||
end
|
||||
|
||||
undef allowed_missing_lib?
|
||||
def allowed_missing_lib?(lib)
|
||||
# lib: Full path to the missing library
|
||||
# Ex.: /home/linuxbrew/.linuxbrew/lib/libsomething.so.1
|
||||
# x - Name of or a pattern for a library, linkage to which is allowed to be missing.
|
||||
# Ex. 1: "libONE.so.1"
|
||||
# Ex. 2: %r{(libONE|libTWO)\.so}
|
||||
self.class.allowed_missing_libraries.any? do |x|
|
||||
case x
|
||||
when Regexp
|
||||
x.match? lib
|
||||
when String
|
||||
lib.include? x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
undef on_linux
|
||||
|
||||
def on_linux(&_block)
|
||||
yield
|
||||
end
|
||||
|
||||
def ignore_missing_libraries(*libs)
|
||||
libs.flatten!
|
||||
allowed_missing_libraries.merge(libs)
|
||||
end
|
||||
|
||||
# @private
|
||||
def allowed_missing_libraries
|
||||
@allowed_missing_libraries ||= Set.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -191,7 +191,8 @@ module Homebrew
|
||||
def check_xcode_license_approved
|
||||
# If the user installs Xcode-only, they have to approve the
|
||||
# license or no "xc*" tool will work.
|
||||
return unless `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?
|
||||
return unless `/usr/bin/xcrun clang 2>&1`.include?("license")
|
||||
return if $CHILD_STATUS.success?
|
||||
|
||||
<<~EOS
|
||||
You have not agreed to the Xcode license.
|
||||
|
||||
@ -2,7 +2,9 @@
|
||||
|
||||
module Hardware
|
||||
def self.oldest_cpu(version = MacOS.version)
|
||||
if version >= :mojave
|
||||
if CPU.arch == :arm64
|
||||
:arm_vortex_tempest
|
||||
elsif version >= :mojave
|
||||
:nehalem
|
||||
else
|
||||
generic_oldest_cpu
|
||||
|
||||
@ -6,9 +6,11 @@ module Utils
|
||||
undef tag
|
||||
|
||||
def tag
|
||||
tag = MacOS.version.to_sym
|
||||
tag = "#{tag}_arm".to_sym if Hardware::CPU.arm?
|
||||
tag
|
||||
if Hardware::CPU.intel?
|
||||
MacOS.version.to_sym
|
||||
else
|
||||
"#{Hardware::CPU.arch}_#{MacOS.version.to_sym}".to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -352,6 +352,8 @@ class Formula
|
||||
delegate desc: :"self.class"
|
||||
|
||||
# The SPDX ID of the software license.
|
||||
# @method license
|
||||
# @see .license=
|
||||
delegate license: :"self.class"
|
||||
|
||||
# The homepage for the software.
|
||||
@ -495,6 +497,10 @@ class Formula
|
||||
# The link status symlink directory for this {Formula}.
|
||||
# You probably want {#opt_prefix} instead.
|
||||
def linked_keg
|
||||
linked_keg = possible_names.map { |name| HOMEBREW_LINKED_KEGS/name }
|
||||
.find(&:directory?)
|
||||
return linked_keg if linked_keg.present?
|
||||
|
||||
HOMEBREW_LINKED_KEGS/name
|
||||
end
|
||||
|
||||
@ -598,7 +604,10 @@ class Formula
|
||||
# All currently installed prefix directories.
|
||||
# @private
|
||||
def installed_prefixes
|
||||
rack.directory? ? rack.subdirs.sort : []
|
||||
possible_names.map { |name| HOMEBREW_CELLAR/name }
|
||||
.select(&:directory?)
|
||||
.flat_map(&:subdirs)
|
||||
.sort_by(&:basename)
|
||||
end
|
||||
|
||||
# All currently installed kegs.
|
||||
@ -934,14 +943,10 @@ class Formula
|
||||
end
|
||||
|
||||
# @private
|
||||
def plist_manual
|
||||
self.class.plist_manual
|
||||
end
|
||||
delegate plist_manual: :"self.class"
|
||||
|
||||
# @private
|
||||
def plist_startup
|
||||
self.class.plist_startup
|
||||
end
|
||||
delegate plist_startup: :"self.class"
|
||||
|
||||
# A stable path for this formula, when installed. Contains the formula name
|
||||
# but no version number. Only the active version will be linked here if
|
||||
@ -1001,9 +1006,7 @@ class Formula
|
||||
end
|
||||
|
||||
# @private
|
||||
def pour_bottle_check_unsatisfied_reason
|
||||
self.class.pour_bottle_check_unsatisfied_reason
|
||||
end
|
||||
delegate pour_bottle_check_unsatisfied_reason: :"self.class"
|
||||
|
||||
# Can be overridden to run commands on both source and bottle installation.
|
||||
def post_install; end
|
||||
@ -1073,9 +1076,7 @@ class Formula
|
||||
end
|
||||
|
||||
# @private
|
||||
def keg_only_reason
|
||||
self.class.keg_only_reason
|
||||
end
|
||||
delegate keg_only_reason: :"self.class"
|
||||
|
||||
# sometimes the formula cleaner breaks things
|
||||
# skip cleaning paths in a formula with a class method like this:
|
||||
@ -1119,7 +1120,7 @@ class Formula
|
||||
return false # this keg belongs to another formula
|
||||
else
|
||||
# this keg belongs to another unrelated formula
|
||||
return false unless (Array(f.aliases) + Array(f.oldname)).include?(keg.name)
|
||||
return false unless f.possible_names.include?(keg.name)
|
||||
end
|
||||
end
|
||||
to_check = path.relative_path_from(HOMEBREW_PREFIX).to_s
|
||||
@ -1130,19 +1131,24 @@ class Formula
|
||||
end
|
||||
end
|
||||
|
||||
# Whether this {Formula} is deprecated (i.e. warns on installation).
|
||||
# Whether this {Formula} is allowed to have a broken linkage to specified library.
|
||||
# Defaults to false.
|
||||
# @return [Boolean]
|
||||
def deprecated?
|
||||
self.class.deprecated?
|
||||
def allowed_missing_lib?(*)
|
||||
false
|
||||
end
|
||||
|
||||
# Whether this {Formula} is deprecated (i.e. warns on installation).
|
||||
# Defaults to false.
|
||||
# @method deprecated?
|
||||
# @return [Boolean]
|
||||
delegate deprecated?: :"self.class"
|
||||
|
||||
# Whether this {Formula} is disabled (i.e. cannot be installed).
|
||||
# Defaults to false.
|
||||
# @method disabled?
|
||||
# @return [Boolean]
|
||||
def disabled?
|
||||
self.class.disabled?
|
||||
end
|
||||
delegate disabled?: :"self.class"
|
||||
|
||||
def skip_cxxstdlib_check?
|
||||
false
|
||||
@ -1305,29 +1311,19 @@ class Formula
|
||||
end
|
||||
|
||||
# @private
|
||||
def pinnable?
|
||||
@pin.pinnable?
|
||||
end
|
||||
delegate pinnable?: :@pin
|
||||
|
||||
# @private
|
||||
def pinned?
|
||||
@pin.pinned?
|
||||
end
|
||||
delegate pinned?: :@pin
|
||||
|
||||
# @private
|
||||
def pinned_version
|
||||
@pin.pinned_version
|
||||
end
|
||||
delegate pinned_version: :@pin
|
||||
|
||||
# @private
|
||||
def pin
|
||||
@pin.pin
|
||||
end
|
||||
delegate pin: :@pin
|
||||
|
||||
# @private
|
||||
def unpin
|
||||
@pin.unpin
|
||||
end
|
||||
delegate unpin: :@pin
|
||||
|
||||
# @private
|
||||
def ==(other)
|
||||
@ -1349,6 +1345,11 @@ class Formula
|
||||
name <=> other.name
|
||||
end
|
||||
|
||||
# @private
|
||||
def possible_names
|
||||
[name, oldname, *aliases].compact
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
@ -1408,7 +1409,7 @@ class Formula
|
||||
|
||||
# Standard parameters for meson builds.
|
||||
def std_meson_args
|
||||
["--prefix=#{prefix}", "--libdir=#{lib}"]
|
||||
["--prefix=#{prefix}", "--libdir=#{lib}", "--buildtype=release"]
|
||||
end
|
||||
|
||||
def shared_library(name, version = nil)
|
||||
@ -1577,14 +1578,10 @@ class Formula
|
||||
end
|
||||
|
||||
# @private
|
||||
def env
|
||||
self.class.env
|
||||
end
|
||||
delegate env: :"self.class"
|
||||
|
||||
# @private
|
||||
def conflicts
|
||||
self.class.conflicts
|
||||
end
|
||||
delegate conflicts: :"self.class"
|
||||
|
||||
# Returns a list of Dependency objects in an installable order, which
|
||||
# means if a depends on b then b will be ordered before a in this list
|
||||
@ -1606,8 +1603,8 @@ class Formula
|
||||
Formula.cache[:opt_or_installed_prefix_keg] ||= {}
|
||||
Formula.cache[:opt_or_installed_prefix_keg][name] ||= if optlinked? && opt_prefix.exist?
|
||||
Keg.new(opt_prefix)
|
||||
elsif installed_prefix.directory?
|
||||
Keg.new(installed_prefix)
|
||||
elsif (latest_installed_prefix = installed_prefixes.last)
|
||||
Keg.new(latest_installed_prefix)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1775,10 +1772,9 @@ class Formula
|
||||
}
|
||||
end
|
||||
|
||||
installed_kegs.each do |keg|
|
||||
hsh["installed"] = installed_kegs.sort_by(&:version).map do |keg|
|
||||
tab = Tab.for_keg keg
|
||||
|
||||
hsh["installed"] << {
|
||||
{
|
||||
"version" => keg.version.to_s,
|
||||
"used_options" => tab.used_options.as_flags,
|
||||
"built_as_bottle" => tab.built_as_bottle,
|
||||
@ -1789,8 +1785,6 @@ class Formula
|
||||
}
|
||||
end
|
||||
|
||||
hsh["installed"] = hsh["installed"].sort_by { |i| Version.create(i["version"]) }
|
||||
|
||||
hsh
|
||||
end
|
||||
|
||||
@ -1809,17 +1803,13 @@ class Formula
|
||||
@prefix_returns_versioned_prefix = true
|
||||
|
||||
test_env = {
|
||||
CURL_HOME: ENV["CURL_HOME"] || ENV["HOME"],
|
||||
TMPDIR: HOMEBREW_TEMP,
|
||||
TEMP: HOMEBREW_TEMP,
|
||||
TMP: HOMEBREW_TEMP,
|
||||
TERM: "dumb",
|
||||
PATH: PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"),
|
||||
HOMEBREW_PATH: nil,
|
||||
_JAVA_OPTIONS: "#{ENV["_JAVA_OPTIONS"]&.+(" ")}-Duser.home=#{HOMEBREW_CACHE}/java_cache",
|
||||
GOCACHE: "#{HOMEBREW_CACHE}/go_cache",
|
||||
CARGO_HOME: "#{HOMEBREW_CACHE}/cargo_cache",
|
||||
}
|
||||
}.merge(common_stage_test_env)
|
||||
|
||||
ENV.clear_sensitive_environment!
|
||||
Utils.set_git_name_email!
|
||||
@ -2140,6 +2130,17 @@ class Formula
|
||||
exit! 1 # never gets here unless exec threw or failed
|
||||
end
|
||||
|
||||
# Common environment variables used at both build and test time
|
||||
def common_stage_test_env
|
||||
{
|
||||
_JAVA_OPTIONS: "#{ENV["_JAVA_OPTIONS"]&.+(" ")}-Duser.home=#{HOMEBREW_CACHE}/java_cache",
|
||||
GOCACHE: "#{HOMEBREW_CACHE}/go_cache",
|
||||
GOPATH: "#{HOMEBREW_CACHE}/go_mod_cache",
|
||||
CARGO_HOME: "#{HOMEBREW_CACHE}/cargo_cache",
|
||||
CURL_HOME: ENV["CURL_HOME"] || ENV["HOME"],
|
||||
}
|
||||
end
|
||||
|
||||
def stage
|
||||
active_spec.stage do |staging|
|
||||
@source_modified_time = active_spec.source_modified_time
|
||||
@ -2153,12 +2154,7 @@ class Formula
|
||||
|
||||
unless Homebrew.args.interactive?
|
||||
stage_env[:HOME] = env_home
|
||||
stage_env[:_JAVA_OPTIONS] =
|
||||
"#{ENV["_JAVA_OPTIONS"]&.+(" ")}-Duser.home=#{HOMEBREW_CACHE}/java_cache"
|
||||
stage_env[:GOCACHE] = "#{HOMEBREW_CACHE}/go_cache"
|
||||
stage_env[:GOPATH] = "#{HOMEBREW_CACHE}/go_mod_cache"
|
||||
stage_env[:CARGO_HOME] = "#{HOMEBREW_CACHE}/cargo_cache"
|
||||
stage_env[:CURL_HOME] = ENV["CURL_HOME"] || ENV["HOME"]
|
||||
stage_env.merge!(common_stage_test_env)
|
||||
end
|
||||
|
||||
setup_home env_home
|
||||
|
||||
@ -84,6 +84,10 @@ module Homebrew
|
||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||
# https://rubydoc.brew.sh/Formula
|
||||
# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!
|
||||
<% if mode == :node %>
|
||||
require "language/node"
|
||||
|
||||
<% end %>
|
||||
class #{Formulary.class_s(name)} < Formula
|
||||
<% if mode == :python %>
|
||||
include Language::Python::Virtualenv
|
||||
@ -91,9 +95,7 @@ module Homebrew
|
||||
<% end %>
|
||||
desc "#{desc}"
|
||||
homepage "#{homepage}"
|
||||
<% if head? %>
|
||||
head "#{url}"
|
||||
<% else %>
|
||||
<% unless head? %>
|
||||
url "#{url}"
|
||||
<% unless version.nil? or version.detected_from_url? %>
|
||||
version "#{version}"
|
||||
@ -101,6 +103,9 @@ module Homebrew
|
||||
sha256 "#{sha256}"
|
||||
<% end %>
|
||||
license "#{license}"
|
||||
<% if head? %>
|
||||
head "#{url}"
|
||||
<% end %>
|
||||
|
||||
<% if mode == :cmake %>
|
||||
depends_on "cmake" => :build
|
||||
@ -111,6 +116,8 @@ module Homebrew
|
||||
<% elsif mode == :meson %>
|
||||
depends_on "meson" => :build
|
||||
depends_on "ninja" => :build
|
||||
<% elsif mode == :node %>
|
||||
depends_on "node"
|
||||
<% elsif mode == :perl %>
|
||||
uses_from_macos "perl"
|
||||
<% elsif mode == :python %>
|
||||
@ -152,6 +159,9 @@ module Homebrew
|
||||
system "ninja", "-v"
|
||||
system "ninja", "install", "-v"
|
||||
end
|
||||
<% elsif mode == :node %>
|
||||
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
|
||||
bin.install_symlink Dir["\#{libexec}/bin/*"]
|
||||
<% elsif mode == :perl %>
|
||||
ENV.prepend_create_path "PERL5LIB", libexec/"lib/perl5"
|
||||
ENV.prepend_path "PERL5LIB", libexec/"lib"
|
||||
|
||||
@ -17,6 +17,7 @@ require "linkage_checker"
|
||||
require "install"
|
||||
require "messages"
|
||||
require "cask/cask_loader"
|
||||
require "cmd/install"
|
||||
require "find"
|
||||
|
||||
class FormulaInstaller
|
||||
@ -148,6 +149,8 @@ class FormulaInstaller
|
||||
def prelude
|
||||
Tab.clear_cache
|
||||
verify_deps_exist unless ignore_deps?
|
||||
forbidden_license_check
|
||||
|
||||
check_install_sanity
|
||||
end
|
||||
|
||||
@ -857,7 +860,7 @@ class FormulaInstaller
|
||||
if formula.link_overwrite?(conflict_file) && !link_overwrite_backup.key?(conflict_file)
|
||||
backup_file = backup_dir/conflict_file.relative_path_from(HOMEBREW_PREFIX).to_s
|
||||
backup_file.parent.mkpath
|
||||
conflict_file.rename backup_file
|
||||
FileUtils.mv conflict_file, backup_file
|
||||
link_overwrite_backup[conflict_file] = backup_file
|
||||
retry
|
||||
end
|
||||
@ -889,7 +892,7 @@ class FormulaInstaller
|
||||
keg.unlink
|
||||
link_overwrite_backup.each do |origin, backup|
|
||||
origin.parent.mkpath
|
||||
backup.rename origin
|
||||
FileUtils.mv backup, origin
|
||||
end
|
||||
end
|
||||
Homebrew.failed = true
|
||||
@ -1102,4 +1105,27 @@ class FormulaInstaller
|
||||
|
||||
$stderr.puts @requirement_messages
|
||||
end
|
||||
|
||||
def forbidden_license_check
|
||||
forbidden_licenses = Homebrew::EnvConfig.forbidden_licenses.to_s.split(" ")
|
||||
return if forbidden_licenses.blank?
|
||||
|
||||
compute_dependencies.each do |dep, _|
|
||||
next if @ignore_deps
|
||||
|
||||
dep_f = dep.to_formula
|
||||
next unless forbidden_licenses.include? dep_f.license
|
||||
|
||||
raise CannotInstallFormulaError, <<~EOS
|
||||
The installation of #{formula.name} has a dependency on #{dep.name} with a forbidden license #{dep_f.license}.
|
||||
EOS
|
||||
end
|
||||
return if @only_deps
|
||||
|
||||
return unless forbidden_licenses.include? formula.license
|
||||
|
||||
raise CannotInstallFormulaError, <<~EOS
|
||||
#{formula.name} has a forbidden license #{formula.license}.
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,14 +12,16 @@ module Hardware
|
||||
class << self
|
||||
def optimization_flags
|
||||
@optimization_flags ||= {
|
||||
native: arch_flag("native"),
|
||||
nehalem: "-march=nehalem",
|
||||
core2: "-march=core2",
|
||||
core: "-march=prescott",
|
||||
armv6: "-march=armv6",
|
||||
armv8: "-march=armv8-a",
|
||||
ppc64: "-mcpu=powerpc64",
|
||||
ppc64le: "-mcpu=powerpc64le",
|
||||
native: arch_flag("native"),
|
||||
nehalem: "-march=nehalem",
|
||||
sandybridge: "-march=sandybridge",
|
||||
core2: "-march=core2",
|
||||
core: "-march=prescott",
|
||||
arm_vortex_tempest: "",
|
||||
armv6: "-march=armv6",
|
||||
armv8: "-march=armv8-a",
|
||||
ppc64: "-mcpu=powerpc64",
|
||||
ppc64le: "-mcpu=powerpc64le",
|
||||
}.freeze
|
||||
end
|
||||
alias generic_optimization_flags optimization_flags
|
||||
|
||||
@ -195,7 +195,7 @@ class Keg
|
||||
|
||||
def initialize(path)
|
||||
path = path.resolved_path if path.to_s.start_with?("#{HOMEBREW_PREFIX}/opt/")
|
||||
raise "#{path} is not a valid keg" unless path.parent.parent.realpath == HOMEBREW_CELLAR.realpath
|
||||
raise "#{path} is not a valid keg" if path.parent.parent.realpath != HOMEBREW_CELLAR.realpath
|
||||
raise "#{path} is not a directory" unless path.directory?
|
||||
|
||||
@path = path
|
||||
@ -255,6 +255,7 @@ class Keg
|
||||
|
||||
def remove_old_aliases
|
||||
opt = opt_record.parent
|
||||
linkedkegs = linked_keg_record.parent
|
||||
|
||||
tap = begin
|
||||
to_formula.tap
|
||||
@ -272,24 +273,28 @@ class Keg
|
||||
# versioned aliases are handled below
|
||||
next if a.match?(/.+@./)
|
||||
|
||||
alias_symlink = opt/a
|
||||
if alias_symlink.symlink? && alias_symlink.exist?
|
||||
alias_symlink.delete if alias_symlink.realpath == opt_record.realpath
|
||||
elsif alias_symlink.symlink? || alias_symlink.exist?
|
||||
alias_symlink.delete
|
||||
alias_opt_symlink = opt/a
|
||||
if alias_opt_symlink.symlink? && alias_opt_symlink.exist?
|
||||
alias_opt_symlink.delete if alias_opt_symlink.realpath == opt_record.realpath
|
||||
elsif alias_opt_symlink.symlink? || alias_opt_symlink.exist?
|
||||
alias_opt_symlink.delete
|
||||
end
|
||||
|
||||
alias_linkedkegs_symlink = linkedkegs/a
|
||||
alias_linkedkegs_symlink.delete if alias_linkedkegs_symlink.symlink? || alias_linkedkegs_symlink.exist?
|
||||
end
|
||||
|
||||
Pathname.glob("#{opt_record}@*").each do |a|
|
||||
a = a.basename.to_s
|
||||
next if aliases.include?(a)
|
||||
|
||||
alias_symlink = opt/a
|
||||
if alias_symlink.symlink? && alias_symlink.exist?
|
||||
next if rack != alias_symlink.realpath.parent
|
||||
alias_opt_symlink = opt/a
|
||||
if alias_opt_symlink.symlink? && alias_opt_symlink.exist?
|
||||
alias_opt_symlink.delete if rack == alias_opt_symlink.realpath.parent
|
||||
end
|
||||
|
||||
alias_symlink.delete
|
||||
alias_linkedkegs_symlink = linkedkegs/a
|
||||
alias_linkedkegs_symlink.delete if alias_linkedkegs_symlink.symlink? || alias_linkedkegs_symlink.exist?
|
||||
end
|
||||
end
|
||||
|
||||
@ -322,9 +327,9 @@ class Keg
|
||||
|
||||
dirs = []
|
||||
|
||||
KEG_LINK_DIRECTORIES.map { |d| path/d }.each do |dir|
|
||||
next unless dir.exist?
|
||||
|
||||
keg_directories = KEG_LINK_DIRECTORIES.map { |d| path/d }
|
||||
.select(&:exist?)
|
||||
keg_directories.each do |dir|
|
||||
dir.find do |src|
|
||||
dst = HOMEBREW_PREFIX + src.relative_path_from(path)
|
||||
dst.extend(ObserverPathnameExtension)
|
||||
@ -332,7 +337,8 @@ class Keg
|
||||
dirs << dst if dst.directory? && !dst.symlink?
|
||||
|
||||
# check whether the file to be unlinked is from the current keg first
|
||||
next unless dst.symlink? && src == dst.resolved_path
|
||||
next unless dst.symlink?
|
||||
next if src != dst.resolved_path
|
||||
|
||||
if mode.dry_run
|
||||
puts dst
|
||||
@ -509,7 +515,7 @@ class Keg
|
||||
|
||||
def remove_oldname_opt_record
|
||||
return unless oldname_opt_record
|
||||
return unless oldname_opt_record.resolved_path == path
|
||||
return if oldname_opt_record.resolved_path != path
|
||||
|
||||
@oldname_opt_record.unlink
|
||||
@oldname_opt_record.parent.rmdir_if_possible
|
||||
|
||||
@ -27,7 +27,7 @@ module Language
|
||||
f = find_openjdk_formula(version)
|
||||
return f.opt_libexec if f
|
||||
|
||||
req = JavaRequirement.new [*version]
|
||||
req = JavaRequirement.new Array(version)
|
||||
raise UnsatisfiedRequirements, req.message unless req.satisfied?
|
||||
|
||||
req.java_home
|
||||
|
||||
@ -180,8 +180,9 @@ module Language
|
||||
def virtualenv_install_with_resources(options = {})
|
||||
python = options[:using]
|
||||
if python.nil?
|
||||
pythons = %w[python python3 python@3 python@3.8 pypy pypy3]
|
||||
pythons = %w[python python3 python@3 python@3.7 python@3.8 pypy pypy3]
|
||||
wanted = pythons.select { |py| needs_python?(py) }
|
||||
raise FormulaUnknownPythonError, self if wanted.empty?
|
||||
raise FormulaAmbiguousPythonError, self if wanted.size > 1
|
||||
|
||||
python = wanted.first
|
||||
@ -261,14 +262,14 @@ module Language
|
||||
# the contents of a `requirements.txt`.
|
||||
# @return [void]
|
||||
def pip_install(targets)
|
||||
targets = [targets] unless targets.is_a? Array
|
||||
targets = Array(targets)
|
||||
targets.each do |t|
|
||||
if t.respond_to? :stage
|
||||
next if t.name == "homebrew-virtualenv"
|
||||
|
||||
t.stage { do_install Pathname.pwd }
|
||||
else
|
||||
t = t.lines.map(&:strip) if t.respond_to?(:lines) && t =~ /\n/
|
||||
t = t.lines.map(&:strip) if t.respond_to?(:lines) && t.include?("\n")
|
||||
do_install t
|
||||
end
|
||||
end
|
||||
@ -291,7 +292,7 @@ module Language
|
||||
private
|
||||
|
||||
def do_install(targets)
|
||||
targets = [targets] unless targets.is_a? Array
|
||||
targets = Array(targets)
|
||||
@formula.system @venv_root/"bin/pip", "install",
|
||||
"-v", "--no-deps", "--no-binary", ":all:",
|
||||
"--ignore-installed", *targets
|
||||
|
||||
@ -55,18 +55,35 @@ class LinkageChecker
|
||||
end
|
||||
|
||||
def display_test_output(puts_output: true)
|
||||
display_items "Missing libraries", @broken_dylibs, puts_output: puts_output
|
||||
display_items "Missing libraries", broken_dylibs_with_expectations, puts_output: puts_output
|
||||
display_items "Broken dependencies", @broken_deps, puts_output: puts_output
|
||||
display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output
|
||||
display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
|
||||
puts "No broken library linkage" unless broken_library_linkage?
|
||||
|
||||
if @broken_dylibs.empty?
|
||||
puts "No broken library linkage detected"
|
||||
elsif unexpected_broken_libs.empty?
|
||||
puts "No unexpected broken library linkage detected."
|
||||
else
|
||||
puts "Broken library linkage detected"
|
||||
end
|
||||
end
|
||||
|
||||
def broken_library_linkage?
|
||||
!@broken_dylibs.empty? ||
|
||||
!@broken_deps.empty? ||
|
||||
!@unwanted_system_dylibs.empty? ||
|
||||
!@version_conflict_deps.empty?
|
||||
issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps]
|
||||
[issues, unexpected_broken_libs].flatten.any?(&:present?)
|
||||
end
|
||||
|
||||
def unexpected_broken_libs
|
||||
@broken_dylibs.reject { |lib| @formula.allowed_missing_lib? lib }
|
||||
end
|
||||
|
||||
def broken_dylibs_with_expectations
|
||||
output = {}
|
||||
@broken_dylibs.each do |lib|
|
||||
output[lib] = (unexpected_broken_libs.include? lib) ? ["unexpected"] : ["expected"]
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -42,7 +42,7 @@ module OS
|
||||
end
|
||||
|
||||
def languages
|
||||
@languages ||= [*ENV["LANG"]&.slice(/[a-z]+/)].uniq
|
||||
@languages ||= Array(ENV["LANG"]&.slice(/[a-z]+/)).uniq
|
||||
end
|
||||
|
||||
def language
|
||||
|
||||
@ -93,7 +93,7 @@ module ELFShim
|
||||
return @dynamic_elf if defined? @dynamic_elf
|
||||
|
||||
@dynamic_elf = if HOMEBREW_PATCHELF_RB
|
||||
patchelf_patcher.instance_variable_get(:@elf).segment_by_type(:DYNAMIC).present?
|
||||
patchelf_patcher.elf.segment_by_type(:DYNAMIC).present?
|
||||
elsif which "readelf"
|
||||
Utils.popen_read("readelf", "-l", to_path).include?(" DYNAMIC ")
|
||||
elsif which "file"
|
||||
|
||||
@ -59,13 +59,30 @@ module OS
|
||||
end
|
||||
|
||||
def languages
|
||||
@languages ||= [
|
||||
return @languages if @languages
|
||||
|
||||
os_langs = Utils.popen_read("defaults", "read", "-g", "AppleLanguages")
|
||||
if os_langs.blank?
|
||||
# User settings don't exist so check the system-wide one.
|
||||
os_langs = Utils.popen_read("defaults", "read", "/Library/Preferences/.GlobalPreferences", "AppleLanguages")
|
||||
end
|
||||
os_langs = os_langs.scan(/[^ \n"(),]+/)
|
||||
|
||||
@languages = [
|
||||
*Homebrew.args.value("language")&.split(","),
|
||||
*ENV["HOMEBREW_LANGUAGES"]&.split(","),
|
||||
*Open3.capture2("defaults", "read", "-g", "AppleLanguages")
|
||||
.first
|
||||
.scan(/[^ \n"(),]+/),
|
||||
*os_langs,
|
||||
].uniq
|
||||
|
||||
# Ensure all languages are valid
|
||||
@languages.select! do |lang|
|
||||
Locale.parse(lang)
|
||||
true
|
||||
rescue Locale::ParserError
|
||||
false
|
||||
end
|
||||
|
||||
@languages
|
||||
end
|
||||
|
||||
def language
|
||||
|
||||
@ -43,6 +43,10 @@ module OS
|
||||
|
||||
# For OS::Mac::Version compatibility
|
||||
def requires_nehalem_cpu?
|
||||
unless Hardware::CPU.intel?
|
||||
raise "Unexpected architecture: #{Hardware::CPU.arch}. This only works with Intel architecture."
|
||||
end
|
||||
|
||||
Hardware.oldest_cpu(self) == :nehalem
|
||||
end
|
||||
# https://en.wikipedia.org/wiki/Nehalem_(microarchitecture)
|
||||
|
||||
@ -86,7 +86,7 @@ class JavaRequirement < Requirement
|
||||
end
|
||||
|
||||
def exact_version?
|
||||
@version && @version.to_s.chars.last != "+"
|
||||
@version && @version.to_s[-1] != "+"
|
||||
end
|
||||
|
||||
def fits_latest?
|
||||
|
||||
@ -29,7 +29,7 @@ class MacOSRequirement < Requirement
|
||||
end
|
||||
|
||||
satisfy(build_env: false) do
|
||||
next [*@version].any? { |v| MacOS.version.public_send(@comparator, v) } if version_specified?
|
||||
next Array(@version).any? { |v| MacOS.version.public_send(@comparator, v) } if version_specified?
|
||||
next true if OS.mac?
|
||||
next true if @version
|
||||
|
||||
|
||||
@ -104,6 +104,27 @@ module RuboCop
|
||||
@offensive_node = resource_block
|
||||
@offense_source_range = resource_block.source_range
|
||||
|
||||
next if on_macos_blocks.length.zero? && on_linux_blocks.length.zero?
|
||||
|
||||
if on_macos_blocks.length == 1
|
||||
on_macos_block = on_macos_blocks.first
|
||||
child_nodes = on_macos_block.body.child_nodes
|
||||
if child_nodes[0].method_name.to_s != "url" && child_nodes[1].method_name.to_s != "sha256"
|
||||
problem "only an url and a sha256 (in the right order) are allowed in a `on_macos` " \
|
||||
"block within a resource block."
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
if on_linux_blocks.length == 1
|
||||
on_linux_block = on_linux_blocks.first
|
||||
child_nodes = on_linux_block.body.child_nodes
|
||||
if child_nodes[0].method_name.to_s != "url" && child_nodes[1].method_name.to_s != "sha256"
|
||||
problem "only an url and a sha256 (in the right order) are allowed in a `on_linux` " \
|
||||
"block within a resource block."
|
||||
end
|
||||
end
|
||||
|
||||
if on_macos_blocks.length > 1
|
||||
problem "there can only be one `on_macos` block in a resource block."
|
||||
next
|
||||
@ -113,32 +134,6 @@ module RuboCop
|
||||
problem "there can only be one `on_linux` block in a resource block."
|
||||
next
|
||||
end
|
||||
|
||||
if on_macos_blocks.length == 1 && on_linux_blocks.length.zero?
|
||||
problem "you need to define an `on_linux` block within your resource block."
|
||||
next
|
||||
end
|
||||
|
||||
if on_macos_blocks.length.zero? && on_linux_blocks.length == 1
|
||||
problem "you need to define an `on_macos` block within your resource block."
|
||||
next
|
||||
end
|
||||
|
||||
on_macos_block = on_macos_blocks.first
|
||||
on_linux_block = on_linux_blocks.first
|
||||
|
||||
child_nodes = on_macos_block.body.child_nodes
|
||||
if child_nodes[0].method_name.to_s != "url" && child_nodes[1].method_name.to_s != "sha256"
|
||||
problem "only an url and a sha256 (in the right order) are allowed in a `on_macos` " \
|
||||
"block within a resource block."
|
||||
next
|
||||
end
|
||||
|
||||
child_nodes = on_linux_block.body.child_nodes
|
||||
if child_nodes[0].method_name.to_s != "url" && child_nodes[1].method_name.to_s != "sha256"
|
||||
problem "only an url and a sha256 (in the right order) are allowed in a `on_linux` " \
|
||||
"block within a resource block."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -15,11 +15,40 @@ module RuboCop
|
||||
bash-completion@2
|
||||
].freeze
|
||||
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body)
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
find_method_calls_by_name(body_node, :conflicts_with).each do |conflicts_with_call|
|
||||
next unless parameters(conflicts_with_call).last.respond_to? :values
|
||||
|
||||
reason = parameters(conflicts_with_call).last.values.first
|
||||
offending_node(reason)
|
||||
name = Regexp.new(@formula_name, Regexp::IGNORECASE)
|
||||
reason = string_content(reason).sub(name, "")
|
||||
first_word = reason.split.first
|
||||
|
||||
if reason.match?(/\A[A-Z]/)
|
||||
problem "'#{first_word}' from the `conflicts_with` reason should be '#{first_word.downcase}'."
|
||||
end
|
||||
|
||||
problem "`conflicts_with` reason should not end with a period." if reason.end_with?(".")
|
||||
end
|
||||
|
||||
return unless versioned_formula?
|
||||
|
||||
problem MSG if !ALLOWLIST.include?(@formula_name) &&
|
||||
method_called_ever?(body, :conflicts_with)
|
||||
method_called_ever?(body_node, :conflicts_with)
|
||||
end
|
||||
|
||||
def autocorrect(node)
|
||||
lambda do |corrector|
|
||||
if versioned_formula?
|
||||
corrector.replace(node.source_range, "keg_only :versioned_formula")
|
||||
else
|
||||
reason = string_content(node)
|
||||
reason[0] = reason[0].downcase
|
||||
reason = reason.delete_suffix(".")
|
||||
corrector.replace(node.source_range, "\"#{reason}\"")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -35,7 +35,7 @@ module RuboCop
|
||||
# Checks for regex match of pattern in the node and
|
||||
# sets the appropriate instance variables to report the match
|
||||
def regex_match_group(node, pattern)
|
||||
string_repr = string_content(node)
|
||||
string_repr = string_content(node).encode("UTF-8", invalid: :replace)
|
||||
match_object = string_repr.match(pattern)
|
||||
return unless match_object
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ module RuboCop
|
||||
|
||||
# Check if command-line is wrongly used in formula's desc
|
||||
if match = regex_match_group(desc, /(command ?line)/i)
|
||||
c = match.to_s.chars.first
|
||||
c = match.to_s[0]
|
||||
problem "Description should use \"#{c}ommand-line\" instead of \"#{match}\""
|
||||
end
|
||||
|
||||
@ -86,7 +86,7 @@ module RuboCop
|
||||
correction = node.source
|
||||
first_word = string_content(node).split.first
|
||||
unless VALID_LOWERCASE_WORDS.include?(first_word)
|
||||
first_char = first_word.to_s.chars.first
|
||||
first_char = first_word.to_s[0]
|
||||
correction.sub!(/^(['"]?)([a-z])/, "\\1#{first_char.upcase}") if first_char
|
||||
end
|
||||
correction.sub!(/^(['"]?)an?\s/i, "\\1")
|
||||
|
||||
@ -37,7 +37,7 @@ module RuboCop
|
||||
# https://wiki.freedesktop.org/project_name.
|
||||
# "Software" is redirected to https://wiki.freedesktop.org/www/Software/project_name
|
||||
when %r{^http://((?:www|nice|libopenraw|liboil|telepathy|xorg)\.)?freedesktop\.org/(?:wiki/)?}
|
||||
if homepage =~ /Software/
|
||||
if homepage.include?("Software")
|
||||
problem "#{homepage} should be styled `https://wiki.freedesktop.org/www/Software/project_name`"
|
||||
else
|
||||
problem "#{homepage} should be styled `https://wiki.freedesktop.org/project_name`"
|
||||
|
||||
@ -102,6 +102,23 @@ module RuboCop
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
problem "Use new-style option definitions" if find_method_def(body_node, :options)
|
||||
|
||||
if formula_tap == "homebrew-core"
|
||||
# Use of build.with? implies options, which are forbidden in homebrew/core
|
||||
find_instance_method_call(body_node, :build, :without?) do
|
||||
problem "Formulae in homebrew/core should not use `build.without?`."
|
||||
end
|
||||
find_instance_method_call(body_node, :build, :with?) do
|
||||
problem "Formulae in homebrew/core should not use `build.with?`."
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
depends_on_build_with(body_node) do |build_with_node|
|
||||
offending_node(build_with_node)
|
||||
problem "Use `:optional` or `:recommended` instead of `if #{build_with_node.source}`"
|
||||
end
|
||||
|
||||
find_instance_method_call(body_node, :build, :without?) do |method|
|
||||
next unless unless_modifier?(method.parent)
|
||||
|
||||
@ -143,29 +160,8 @@ module RuboCop
|
||||
problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\""
|
||||
end
|
||||
|
||||
find_instance_method_call(body_node, :build, :include?) do |method|
|
||||
arg = parameters(method).first
|
||||
next unless match = regex_match_group(arg, /^with(out)?-(.*)/)
|
||||
|
||||
problem "Use build.with#{match[1]}? \"#{match[2]}\" instead of " \
|
||||
"build.include? 'with#{match[1]}-#{match[2]}'"
|
||||
end
|
||||
|
||||
find_instance_method_call(body_node, :build, :include?) do |method|
|
||||
arg = parameters(method).first
|
||||
next unless match = regex_match_group(arg, /^--(.*)$/)
|
||||
|
||||
problem "Reference '#{match[1]}' without dashes"
|
||||
end
|
||||
|
||||
return if formula_tap != "homebrew-core"
|
||||
|
||||
# Use of build.with? implies options, which are forbidden in homebrew/core
|
||||
find_instance_method_call(body_node, :build, :without?) do
|
||||
problem "Formulae in homebrew/core should not use `build.without?`."
|
||||
end
|
||||
find_instance_method_call(body_node, :build, :with?) do
|
||||
problem "Formulae in homebrew/core should not use `build.with?`."
|
||||
find_instance_method_call(body_node, :build, :include?) do
|
||||
problem "`build.include?` is deprecated"
|
||||
end
|
||||
end
|
||||
|
||||
@ -174,6 +170,12 @@ module RuboCop
|
||||
|
||||
node.modifier_form? && node.unless?
|
||||
end
|
||||
|
||||
# Finds `depends_on "foo" if build.with?("bar")` or `depends_on "foo" if build.without?("bar")`
|
||||
def_node_search :depends_on_build_with, <<~EOS
|
||||
(if $(send (send nil? :build) {:with? :without?} str)
|
||||
(send nil? :depends_on str) nil?)
|
||||
EOS
|
||||
end
|
||||
|
||||
class MpiCheck < FormulaCop
|
||||
|
||||
@ -6,7 +6,19 @@ module RuboCop
|
||||
module Cop
|
||||
module FormulaAudit
|
||||
class Text < FormulaCop
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
def audit_formula(node, _class_node, _parent_class_node, body_node)
|
||||
@full_source_content = source_buffer(node).source
|
||||
|
||||
if match = @full_source_content.match(/^require ['"]formula['"]$/)
|
||||
@offensive_node = node
|
||||
@source_buf = source_buffer(node)
|
||||
@line_no = match.pre_match.count("\n") + 1
|
||||
@column = 0
|
||||
@length = match[0].length
|
||||
@offense_source_range = source_range(@source_buf, @line_no, @column, @length)
|
||||
problem "`#{match}` is now unnecessary"
|
||||
end
|
||||
|
||||
if !find_node_method_by_name(body_node, :plist_options) &&
|
||||
find_method_def(body_node, :plist)
|
||||
problem "Please set plist_options when using a formula-defined plist."
|
||||
@ -62,7 +74,50 @@ module RuboCop
|
||||
find_method_with_args(body_node, :system, "cargo", "build") do
|
||||
problem "use \"cargo\", \"install\", *std_cargo_args"
|
||||
end
|
||||
|
||||
find_every_method_call_by_name(body_node, :system).each do |m|
|
||||
next unless parameters_passed?(m, /make && make/)
|
||||
|
||||
offending_node(m)
|
||||
problem "Use separate `make` calls"
|
||||
end
|
||||
|
||||
body_node.each_descendant(:dstr) do |dstr_node|
|
||||
dstr_node.each_descendant(:begin) do |interpolation_node|
|
||||
next unless interpolation_node.source.match?(/#\{\w+\s*\+\s*['"][^}]+\}/)
|
||||
|
||||
offending_node(interpolation_node)
|
||||
problem "Do not concatenate paths in string interpolation"
|
||||
end
|
||||
end
|
||||
|
||||
find_strings(body_node).each do |n|
|
||||
next unless regex_match_group(n, /JAVA_HOME/i)
|
||||
|
||||
next if @formula_name.match?(/^openjdk(@|$)/)
|
||||
|
||||
next if find_every_method_call_by_name(body_node, :depends_on).any? do |dependency|
|
||||
dependency.each_descendant(:str).count.zero? ||
|
||||
regex_match_group(dependency.each_descendant(:str).first, /^openjdk(@|$)/) ||
|
||||
depends_on?(:java)
|
||||
end
|
||||
|
||||
offending_node(n)
|
||||
problem "Use `depends_on :java` to set JAVA_HOME"
|
||||
end
|
||||
|
||||
prefix_path(body_node) do |prefix_node, path|
|
||||
next unless match = path.match(%r{^(bin|include|libexec|lib|sbin|share|Frameworks)(?:/| |$)})
|
||||
|
||||
offending_node(prefix_node)
|
||||
problem "Use `#{match[1].downcase}` instead of `prefix + \"#{match[1]}\"`"
|
||||
end
|
||||
end
|
||||
|
||||
# Find: prefix + "foo"
|
||||
def_node_search :prefix_path, <<~EOS
|
||||
$(send (send nil? :prefix) :+ (str $_))
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
@ -72,7 +127,42 @@ module RuboCop
|
||||
find_method_with_args(body_node, :go_resource) do
|
||||
problem "`go_resource`s are deprecated. Please ask upstream to implement Go vendoring"
|
||||
end
|
||||
|
||||
find_method_with_args(body_node, :env, :userpaths) do
|
||||
problem "`env :userpaths` in homebrew/core formulae is deprecated"
|
||||
end
|
||||
|
||||
share_path_starts_with(body_node, @formula_name) do |share_node|
|
||||
offending_node(share_node)
|
||||
problem "Use `pkgshare` instead of `share/\"#{@formula_name}\"`"
|
||||
end
|
||||
|
||||
interpolated_share_path_starts_with(body_node, "/#{@formula_name}") do |share_node|
|
||||
offending_node(share_node)
|
||||
problem "Use `\#{pkgshare}` instead of `\#{share}/#{@formula_name}`"
|
||||
end
|
||||
|
||||
return unless formula_tap == "homebrew-core"
|
||||
|
||||
find_method_with_args(body_node, :env, :std) do
|
||||
problem "`env :std` in homebrew/core formulae is deprecated"
|
||||
end
|
||||
end
|
||||
|
||||
# Check whether value starts with the formula name and then a "/", " " or EOS
|
||||
def path_starts_with?(path, starts_with)
|
||||
path.match?(%r{^#{Regexp.escape(starts_with)}(/| |$)})
|
||||
end
|
||||
|
||||
# Find "#{share}/foo"
|
||||
def_node_search :interpolated_share_path_starts_with, <<~EOS
|
||||
$(dstr (begin (send nil? :share)) (str #path_starts_with?(%1)))
|
||||
EOS
|
||||
|
||||
# Find share/"foo"
|
||||
def_node_search :share_path_starts_with, <<~EOS
|
||||
$(send (send nil? :share) :/ (str #path_starts_with?(%1)))
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -247,7 +247,7 @@ module RuboCop
|
||||
# Don't use GitHub .zip files
|
||||
zip_gh_pattern = %r{https://.*github.*/(archive|releases)/.*\.zip$}
|
||||
audit_urls(urls, zip_gh_pattern) do |_, url|
|
||||
next if url.match?(%r{releases/download})
|
||||
next if url.include?("releases/download")
|
||||
|
||||
problem "Use GitHub tarballs rather than zipballs (url is #{url})."
|
||||
end
|
||||
@ -291,21 +291,22 @@ module RuboCop
|
||||
urls += mirrors
|
||||
|
||||
# Check pypi urls
|
||||
@pypi_pattern = %r{^https?://pypi.python.org/(.*)}
|
||||
audit_urls(urls, @pypi_pattern) do |match, url|
|
||||
problem "#{url} should be `https://files.pythonhosted.org/#{match[1]}`"
|
||||
pypi_pattern = %r{^https?://pypi.python.org/}
|
||||
audit_urls(urls, pypi_pattern) do |_, url|
|
||||
problem "use the `Source` url found on PyPI downloads page (`#{get_pypi_url(url)}`)"
|
||||
end
|
||||
|
||||
# Require long files.pythonhosted.org urls
|
||||
pythonhosted_pattern = %r{^https?://files.pythonhosted.org/packages/source/}
|
||||
audit_urls(urls, pythonhosted_pattern) do |_, url|
|
||||
problem "use the `Source` url found on PyPI downloads page (`#{get_pypi_url(url)}`)"
|
||||
end
|
||||
end
|
||||
|
||||
def autocorrect(node)
|
||||
lambda do |corrector|
|
||||
url_string_node = parameters(node).first
|
||||
url = string_content(url_string_node)
|
||||
match = regex_match_group(url_string_node, @pypi_pattern)
|
||||
correction = node.source.sub(url, "https://files.pythonhosted.org/#{match[1]}")
|
||||
corrector.insert_before(node.source_range, correction)
|
||||
corrector.remove(node.source_range)
|
||||
end
|
||||
def get_pypi_url(url)
|
||||
package_file = File.basename(url)
|
||||
package_name = package_file.match(/^(.+)-[a-z0-9.]+$/)[1]
|
||||
"https://pypi.org/project/#{package_name}/#files"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -15,7 +15,6 @@ module RuboCop
|
||||
bc
|
||||
bison
|
||||
bzip2
|
||||
cpio
|
||||
cups
|
||||
curl
|
||||
dyld-headers
|
||||
@ -62,6 +61,7 @@ module RuboCop
|
||||
# TODO: consider making some of these keg-only.
|
||||
ALLOWED_USES_FROM_MACOS_DEPS = (PROVIDED_BY_MACOS_FORMULAE + %w[
|
||||
bash
|
||||
cpio
|
||||
expect
|
||||
groff
|
||||
gzip
|
||||
|
||||
@ -47,12 +47,12 @@ class Sandbox
|
||||
end
|
||||
|
||||
def allow_cvs
|
||||
allow_write_path "#{ENV["HOME"]}/.cvspass"
|
||||
allow_write_path "#{Dir.home(ENV["USER"])}/.cvspass"
|
||||
end
|
||||
|
||||
def allow_fossil
|
||||
allow_write_path "#{ENV["HOME"]}/.fossil"
|
||||
allow_write_path "#{ENV["HOME"]}/.fossil-journal"
|
||||
allow_write_path "#{Dir.home(ENV["USER"])}/.fossil"
|
||||
allow_write_path "#{Dir.home(ENV["USER"])}/.fossil-journal"
|
||||
end
|
||||
|
||||
def allow_write_cellar(formula)
|
||||
@ -63,7 +63,7 @@ class Sandbox
|
||||
|
||||
# Xcode projects expect access to certain cache/archive dirs.
|
||||
def allow_write_xcode
|
||||
allow_write_path "#{ENV["HOME"]}/Library/Developer"
|
||||
allow_write_path "#{Dir.home(ENV["USER"])}/Library/Developer"
|
||||
end
|
||||
|
||||
def allow_write_log(formula)
|
||||
|
||||
@ -19,7 +19,7 @@ module Searchable
|
||||
def search_regex(regex)
|
||||
select do |*args|
|
||||
args = yield(*args) if block_given?
|
||||
args = [*args].compact
|
||||
args = Array(args).compact
|
||||
args.any? { |arg| arg.match?(regex) }
|
||||
end
|
||||
end
|
||||
@ -28,7 +28,7 @@ module Searchable
|
||||
simplified_string = simplify_string(string)
|
||||
select do |*args|
|
||||
args = yield(*args) if block_given?
|
||||
args = [*args].compact
|
||||
args = Array(args).compact
|
||||
args.any? { |arg| simplify_string(arg).include?(simplified_string) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -81,7 +81,6 @@ false:
|
||||
- ./cask/utils.rb
|
||||
- ./cask/verify.rb
|
||||
- ./caveats.rb
|
||||
- ./cleaner.rb
|
||||
- ./cleanup.rb
|
||||
- ./cli/args.rb
|
||||
- ./cli/parser.rb
|
||||
@ -129,15 +128,11 @@ false:
|
||||
- ./cmd/uses.rb
|
||||
- ./commands.rb
|
||||
- ./compat/language/python.rb
|
||||
- ./compilers.rb
|
||||
- ./cxxstdlib.rb
|
||||
- ./debrew.rb
|
||||
- ./debrew/irb.rb
|
||||
- ./dependencies.rb
|
||||
- ./dependency.rb
|
||||
- ./dependency_collector.rb
|
||||
- ./description_cache_store.rb
|
||||
- ./descriptions.rb
|
||||
- ./dev-cmd/audit.rb
|
||||
- ./dev-cmd/bottle.rb
|
||||
- ./dev-cmd/bump-formula-pr.rb
|
||||
@ -163,6 +158,7 @@ false:
|
||||
- ./dev-cmd/release-notes.rb
|
||||
- ./dev-cmd/ruby.rb
|
||||
- ./dev-cmd/sh.rb
|
||||
- ./dev-cmd/sponsors.rb
|
||||
- ./dev-cmd/style.rb
|
||||
- ./dev-cmd/tap-new.rb
|
||||
- ./dev-cmd/test.rb
|
||||
@ -174,7 +170,6 @@ false:
|
||||
- ./development_tools.rb
|
||||
- ./diagnostic.rb
|
||||
- ./download_strategy.rb
|
||||
- ./env_config.rb
|
||||
- ./exceptions.rb
|
||||
- ./extend/ENV.rb
|
||||
- ./extend/ENV/shared.rb
|
||||
@ -228,7 +223,6 @@ false:
|
||||
- ./lock_file.rb
|
||||
- ./migrator.rb
|
||||
- ./missing_formula.rb
|
||||
- ./os/linux.rb
|
||||
- ./os/mac.rb
|
||||
- ./os/mac/keg.rb
|
||||
- ./os/mac/mach.rb
|
||||
@ -454,9 +448,7 @@ false:
|
||||
- ./utils/formatter.rb
|
||||
- ./utils/git.rb
|
||||
- ./utils/github.rb
|
||||
- ./utils/notability.rb
|
||||
- ./utils/popen.rb
|
||||
- ./utils/user.rb
|
||||
|
||||
false:
|
||||
- ./PATH.rb
|
||||
@ -500,11 +492,8 @@ false:
|
||||
- ./messages.rb
|
||||
- ./mktemp.rb
|
||||
- ./options.rb
|
||||
- ./os.rb
|
||||
- ./os/linux/elf.rb
|
||||
- ./os/linux/glibc.rb
|
||||
- ./os/linux/global.rb
|
||||
- ./os/linux/kernel.rb
|
||||
- ./os/mac/architecture_list.rb
|
||||
- ./pkg_version.rb
|
||||
- ./requirements/arch_requirement.rb
|
||||
@ -603,6 +592,7 @@ false:
|
||||
- ./test/dev-cmd/release-notes_spec.rb
|
||||
- ./test/dev-cmd/ruby_spec.rb
|
||||
- ./test/dev-cmd/sh_spec.rb
|
||||
- ./test/dev-cmd/sponsors_spec.rb
|
||||
- ./test/dev-cmd/style_spec.rb
|
||||
- ./test/dev-cmd/tap-new_spec.rb
|
||||
- ./test/dev-cmd/test_spec.rb
|
||||
@ -848,8 +838,6 @@ false:
|
||||
- ./unpack_strategy/uncompressed.rb
|
||||
- ./utils/gems.rb
|
||||
- ./utils/inreplace.rb
|
||||
- ./utils/link.rb
|
||||
- ./utils/shebang.rb
|
||||
- ./version.rb
|
||||
|
||||
true:
|
||||
@ -860,7 +848,13 @@ true:
|
||||
- ./cask/macos.rb
|
||||
- ./cask/url.rb
|
||||
- ./checksum.rb
|
||||
- ./cleaner.rb
|
||||
- ./compilers.rb
|
||||
- ./config.rb
|
||||
- ./dependency_collector.rb
|
||||
- ./description_cache_store.rb
|
||||
- ./descriptions.rb
|
||||
- ./env_config.rb
|
||||
- ./extend/cachable.rb
|
||||
- ./extend/os/linux/development_tools.rb
|
||||
- ./extend/os/linux/formula.rb
|
||||
@ -881,6 +875,10 @@ true:
|
||||
- ./locale.rb
|
||||
- ./metafiles.rb
|
||||
- ./official_taps.rb
|
||||
- ./os.rb
|
||||
- ./os/linux.rb
|
||||
- ./os/linux/glibc.rb
|
||||
- ./os/linux/kernel.rb
|
||||
- ./rubocops/cask/ast/cask_header.rb
|
||||
- ./rubocops/cask/ast/stanza.rb
|
||||
- ./rubocops/cask/constants/stanza.rb
|
||||
@ -890,9 +888,13 @@ true:
|
||||
- ./test/support/helper/fixtures.rb
|
||||
- ./test/support/lib/config.rb
|
||||
- ./utils/bottles.rb
|
||||
- ./utils/link.rb
|
||||
- ./utils/notability.rb
|
||||
- ./utils/shebang.rb
|
||||
- ./utils/shell.rb
|
||||
- ./utils/svn.rb
|
||||
- ./utils/tty.rb
|
||||
- ./utils/user.rb
|
||||
- ./version/null.rb
|
||||
|
||||
strict:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
||||
# tapioca sync
|
||||
# tapioca sync --exclude json
|
||||
|
||||
# typed: true
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
||||
# tapioca sync
|
||||
# tapioca sync --exclude json
|
||||
|
||||
# typed: true
|
||||
|
||||
@ -12,6 +12,24 @@ end
|
||||
module RuboCop::Cop::Performance
|
||||
end
|
||||
|
||||
class RuboCop::Cop::Performance::AncestorsInclude < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
|
||||
def ancestors_include_candidate?(node = _); end
|
||||
def autocorrect(node); end
|
||||
def on_send(node); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::AncestorsInclude::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::BigDecimalWithNumericArgument < ::RuboCop::Cop::Cop
|
||||
def autocorrect(node); end
|
||||
def big_decimal_with_numeric_argument?(node = _); end
|
||||
def on_send(node); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::BigDecimalWithNumericArgument::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::BindCall < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
extend(::RuboCop::Cop::TargetRubyVersion)
|
||||
@ -256,6 +274,29 @@ class RuboCop::Cop::Performance::InefficientHashSearch < ::RuboCop::Cop::Cop
|
||||
def use_long_method; end
|
||||
end
|
||||
|
||||
class RuboCop::Cop::Performance::IoReadlines < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
|
||||
def autocorrect(node); end
|
||||
def on_send(node); end
|
||||
def readlines_on_class?(node = _); end
|
||||
def readlines_on_instance?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def build_bad_method(enumerable_call); end
|
||||
def build_call_args(call_args_node); end
|
||||
def build_good_method(enumerable_call); end
|
||||
def correction_range(enumerable_call, readlines_call); end
|
||||
def enumerable_method?(node); end
|
||||
def offense(node, enumerable_call, readlines_call); end
|
||||
def offense_range(enumerable_call, readlines_call); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::IoReadlines::ENUMERABLE_METHODS = T.let(T.unsafe(nil), Array)
|
||||
|
||||
RuboCop::Cop::Performance::IoReadlines::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::OpenStruct < ::RuboCop::Cop::Cop
|
||||
def on_send(node); end
|
||||
def open_struct(node = _); end
|
||||
@ -349,6 +390,42 @@ RuboCop::Cop::Performance::RedundantMerge::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
RuboCop::Cop::Performance::RedundantMerge::WITH_MODIFIER_CORRECTION = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::RedundantSortBlock < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
include(::RuboCop::Cop::SortBlock)
|
||||
|
||||
def autocorrect(node); end
|
||||
def on_block(node); end
|
||||
|
||||
private
|
||||
|
||||
def message(var_a, var_b); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::RedundantSortBlock::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::RedundantStringChars < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
|
||||
def autocorrect(node); end
|
||||
def on_send(node); end
|
||||
def redundant_chars_call?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def build_bad_method(method, args); end
|
||||
def build_call_args(call_args_node); end
|
||||
def build_good_method(method, args); end
|
||||
def build_message(method, args); end
|
||||
def correction_range(receiver, node); end
|
||||
def offense_range(receiver, node); end
|
||||
def replaceable_method?(method_name); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::RedundantStringChars::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
RuboCop::Cop::Performance::RedundantStringChars::REPLACEABLE_METHODS = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class RuboCop::Cop::Performance::RegexpMatch < ::RuboCop::Cop::Cop
|
||||
def autocorrect(node); end
|
||||
def last_matches(node0); end
|
||||
@ -398,21 +475,61 @@ RuboCop::Cop::Performance::ReverseEach::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
RuboCop::Cop::Performance::ReverseEach::UNDERSCORE = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::Size < ::RuboCop::Cop::Cop
|
||||
class RuboCop::Cop::Performance::ReverseFirst < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
|
||||
def autocorrect(node); end
|
||||
def on_send(node); end
|
||||
def reverse_first_candidate?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def allowed_parent?(node); end
|
||||
def array?(node); end
|
||||
def eligible_node?(node); end
|
||||
def eligible_receiver?(node); end
|
||||
def hash?(node); end
|
||||
def build_bad_method(node); end
|
||||
def build_good_method(node); end
|
||||
def build_message(node); end
|
||||
def correction_range(receiver, node); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::ReverseFirst::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::Size < ::RuboCop::Cop::Cop
|
||||
def array?(node = _); end
|
||||
def autocorrect(node); end
|
||||
def count?(node = _); end
|
||||
def hash?(node = _); end
|
||||
def on_send(node); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::Size::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::SortReverse < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
include(::RuboCop::Cop::SortBlock)
|
||||
|
||||
def autocorrect(node); end
|
||||
def on_block(node); end
|
||||
|
||||
private
|
||||
|
||||
def message(var_a, var_b); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::SortReverse::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::Squeeze < ::RuboCop::Cop::Cop
|
||||
def autocorrect(node); end
|
||||
def on_send(node); end
|
||||
def squeeze_candidate?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def repeating_literal?(regex_str); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::Squeeze::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
RuboCop::Cop::Performance::Squeeze::PREFERRED_METHODS = T.let(T.unsafe(nil), Hash)
|
||||
|
||||
class RuboCop::Cop::Performance::StartWith < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RegexpMetacharacter)
|
||||
|
||||
@ -424,6 +541,19 @@ end
|
||||
|
||||
RuboCop::Cop::Performance::StartWith::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::StringInclude < ::RuboCop::Cop::Cop
|
||||
def autocorrect(node); end
|
||||
def on_match_with_lvasgn(node); end
|
||||
def on_send(node); end
|
||||
def redundant_regex?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def literal?(regex_str); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::Performance::StringInclude::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::Performance::StringReplacement < ::RuboCop::Cop::Cop
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
|
||||
@ -504,6 +634,18 @@ module RuboCop::Cop::RegexpMetacharacter
|
||||
def safe_multiline?; end
|
||||
end
|
||||
|
||||
module RuboCop::Cop::SortBlock
|
||||
include(::RuboCop::Cop::RangeHelp)
|
||||
extend(::RuboCop::AST::NodePattern::Macros)
|
||||
|
||||
def replaceable_body?(node = _, param1, param2); end
|
||||
def sort_with_block?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def sort_range(send, node); end
|
||||
end
|
||||
|
||||
RuboCop::NodePattern = RuboCop::AST::NodePattern
|
||||
|
||||
module RuboCop::Performance
|
||||
@ -1,5 +1,5 @@
|
||||
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
||||
# tapioca sync
|
||||
# tapioca sync --exclude json
|
||||
|
||||
# typed: true
|
||||
|
||||
@ -225,7 +225,6 @@ class RuboCop::Cop::RSpec::DescribeClass < ::RuboCop::Cop::RSpec::Cop
|
||||
def describe_with_rails_metadata?(node = _); end
|
||||
def on_top_level_describe(node, _); end
|
||||
def rails_metadata?(node = _); end
|
||||
def shared_group?(node = _); end
|
||||
def valid_describe?(node = _); end
|
||||
|
||||
private
|
||||
@ -528,7 +527,7 @@ end
|
||||
class RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically < ::RuboCop::Cop::RSpec::Cop
|
||||
def association?(node = _); end
|
||||
def autocorrect(node); end
|
||||
def factory_attributes(node0); end
|
||||
def factory_attributes(node = _); end
|
||||
def on_block(node); end
|
||||
def value_matcher(node = _); end
|
||||
|
||||
@ -773,12 +772,13 @@ end
|
||||
RuboCop::Cop::RSpec::InstanceSpy::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::RSpec::InstanceVariable < ::RuboCop::Cop::RSpec::Cop
|
||||
include(::RuboCop::RSpec::TopLevelGroup)
|
||||
|
||||
def custom_matcher?(node = _); end
|
||||
def dynamic_class?(node = _); end
|
||||
def ivar_assigned?(node0, param1); end
|
||||
def ivar_usage(node0); end
|
||||
def on_block(node); end
|
||||
def spec_group?(node = _); end
|
||||
def on_top_level_group(node); end
|
||||
|
||||
private
|
||||
|
||||
@ -786,8 +786,6 @@ class RuboCop::Cop::RSpec::InstanceVariable < ::RuboCop::Cop::RSpec::Cop
|
||||
def valid_usage?(node); end
|
||||
end
|
||||
|
||||
RuboCop::Cop::RSpec::InstanceVariable::EXAMPLE_GROUP_METHODS = T.let(T.unsafe(nil), RuboCop::RSpec::Language::SelectorSet)
|
||||
|
||||
RuboCop::Cop::RSpec::InstanceVariable::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::RSpec::InvalidPredicateMatcher < ::RuboCop::Cop::RSpec::Cop
|
||||
@ -844,7 +842,6 @@ end
|
||||
RuboCop::Cop::RSpec::LeadingSubject::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::RSpec::LeakyConstantDeclaration < ::RuboCop::Cop::RSpec::Cop
|
||||
def in_example_or_shared_group?(node = _); end
|
||||
def on_casgn(node); end
|
||||
def on_class(node); end
|
||||
def on_module(node); end
|
||||
@ -875,12 +872,14 @@ end
|
||||
RuboCop::Cop::RSpec::LetBeforeExamples::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::RSpec::LetSetup < ::RuboCop::Cop::RSpec::Cop
|
||||
def let_bang(node0); end
|
||||
def example_or_shared_group_or_including?(node = _); end
|
||||
def let_bang(node = _); end
|
||||
def method_called?(node0, param1); end
|
||||
def on_block(node); end
|
||||
|
||||
private
|
||||
|
||||
def child_let_bang(node, &block); end
|
||||
def unused_let_bang(node); end
|
||||
end
|
||||
|
||||
@ -993,12 +992,11 @@ class RuboCop::Cop::RSpec::NestedGroups < ::RuboCop::Cop::RSpec::Cop
|
||||
include(::RuboCop::Cop::ConfigurableMax)
|
||||
include(::RuboCop::RSpec::TopLevelDescribe)
|
||||
|
||||
def find_contexts(node0); end
|
||||
def on_top_level_describe(node, _args); end
|
||||
|
||||
private
|
||||
|
||||
def find_nested_contexts(node, nesting: _, &block); end
|
||||
def find_nested_example_groups(node, nesting: _, &block); end
|
||||
def max_nesting; end
|
||||
def max_nesting_config; end
|
||||
def message(nesting); end
|
||||
@ -1157,6 +1155,7 @@ class RuboCop::Cop::RSpec::ReturnFromStub < ::RuboCop::Cop::RSpec::Cop
|
||||
def contains_stub?(node0); end
|
||||
def on_block(node); end
|
||||
def on_send(node); end
|
||||
def stub_with_block?(node = _); end
|
||||
|
||||
private
|
||||
|
||||
@ -1280,16 +1279,17 @@ end
|
||||
RuboCop::Cop::RSpec::SingleArgumentMessageChain::MSG = T.let(T.unsafe(nil), String)
|
||||
|
||||
class RuboCop::Cop::RSpec::SubjectStub < ::RuboCop::Cop::RSpec::Cop
|
||||
include(::RuboCop::RSpec::TopLevelGroup)
|
||||
|
||||
def message_expectation?(node = _, param1); end
|
||||
def message_expectation_matcher?(node0); end
|
||||
def on_block(node); end
|
||||
def on_top_level_group(node); end
|
||||
def subject(node = _); end
|
||||
|
||||
private
|
||||
|
||||
def find_all_explicit_subjects(node); end
|
||||
def find_subject_expectations(node, subject_names = _, &block); end
|
||||
def processed_example_groups; end
|
||||
end
|
||||
|
||||
RuboCop::Cop::RSpec::SubjectStub::MSG = T.let(T.unsafe(nil), String)
|
||||
@ -1467,17 +1467,14 @@ end
|
||||
class RuboCop::RSpec::ExampleGroup < ::RuboCop::RSpec::Concept
|
||||
def examples; end
|
||||
def hooks; end
|
||||
def lets; end
|
||||
def scope_change?(node = _); end
|
||||
def subjects; end
|
||||
|
||||
private
|
||||
|
||||
def examples_in_scope(node, &blk); end
|
||||
def find_examples(node); end
|
||||
def find_hooks(node); end
|
||||
def find_subjects(node); end
|
||||
def hooks_in_scope(node); end
|
||||
def subjects_in_scope(node); end
|
||||
def find_all(node, predicate); end
|
||||
def find_all_in_scope(node, predicate); end
|
||||
end
|
||||
|
||||
module RuboCop::RSpec::FactoryBot
|
||||
@ -1576,6 +1573,8 @@ module RuboCop::RSpec::Language::NodePattern
|
||||
def example_group_with_body?(node = _); end
|
||||
def hook?(node = _); end
|
||||
def let?(node = _); end
|
||||
def shared_group?(node = _); end
|
||||
def spec_group?(node = _); end
|
||||
def subject?(node = _); end
|
||||
end
|
||||
|
||||
@ -1636,6 +1635,21 @@ module RuboCop::RSpec::TopLevelDescribe
|
||||
def top_level_nodes; end
|
||||
end
|
||||
|
||||
module RuboCop::RSpec::TopLevelGroup
|
||||
include(::RuboCop::RSpec::Language)
|
||||
extend(::RuboCop::AST::NodePattern::Macros)
|
||||
|
||||
def example_or_shared_group?(node = _); end
|
||||
def on_block(node); end
|
||||
|
||||
private
|
||||
|
||||
def root_node; end
|
||||
def top_level_group?(node); end
|
||||
def top_level_groups; end
|
||||
def top_level_nodes; end
|
||||
end
|
||||
|
||||
module RuboCop::RSpec::Variable
|
||||
include(::RuboCop::RSpec::Language)
|
||||
extend(::RuboCop::AST::NodePattern::Macros)
|
||||
File diff suppressed because it is too large
Load Diff
@ -5819,6 +5819,10 @@ class Cask::DSL::Container
|
||||
|
||||
def nested=(nested); end
|
||||
|
||||
def pairs(); end
|
||||
|
||||
def pairs=(pairs); end
|
||||
|
||||
def type(); end
|
||||
|
||||
def type=(type); end
|
||||
@ -19436,7 +19440,7 @@ module RuboCop::RSpec::ExpectOffense
|
||||
|
||||
def expect_no_offenses(source, file=T.unsafe(nil)); end
|
||||
|
||||
def expect_offense(source, file=T.unsafe(nil), **replacements); end
|
||||
def expect_offense(source, file=T.unsafe(nil), severity: T.unsafe(nil), **replacements); end
|
||||
|
||||
def format_offense(source, **replacements); end
|
||||
end
|
||||
@ -23216,6 +23220,8 @@ class URL
|
||||
|
||||
def scheme=(scheme); end
|
||||
|
||||
def specs(); end
|
||||
|
||||
def string(); end
|
||||
|
||||
def subdomain(); end
|
||||
@ -23234,6 +23240,8 @@ class URL
|
||||
|
||||
def trust_cert(); end
|
||||
|
||||
def uri(); end
|
||||
|
||||
def user_agent(); end
|
||||
|
||||
def using(); end
|
||||
|
||||
14
Library/Homebrew/sorbet/rbi/os.rbi
Normal file
14
Library/Homebrew/sorbet/rbi/os.rbi
Normal file
@ -0,0 +1,14 @@
|
||||
# typed: true
|
||||
|
||||
module OS
|
||||
module Linux
|
||||
include Kernel
|
||||
|
||||
def which(cmd, path = ENV["PATH"])
|
||||
end
|
||||
end
|
||||
|
||||
module Mac
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
15
Library/Homebrew/sorbet/rbi/utils/notability.rbi
Normal file
15
Library/Homebrew/sorbet/rbi/utils/notability.rbi
Normal file
@ -0,0 +1,15 @@
|
||||
# typed: strict
|
||||
|
||||
module SharedAudits
|
||||
def github(user, repo)
|
||||
end
|
||||
|
||||
def gitlab(user, repo)
|
||||
end
|
||||
|
||||
def bitbucket(user, repo)
|
||||
end
|
||||
|
||||
def curl_output(*args, secrets: [], **options)
|
||||
end
|
||||
end
|
||||
9
Library/Homebrew/sorbet/rbi/utils/user.rbi
Normal file
9
Library/Homebrew/sorbet/rbi/utils/user.rbi
Normal file
@ -0,0 +1,9 @@
|
||||
# typed: strict
|
||||
|
||||
class User < String
|
||||
def gui?
|
||||
end
|
||||
|
||||
def self.current
|
||||
end
|
||||
end
|
||||
@ -5,4 +5,12 @@ module Utils
|
||||
|
||||
class Bottles
|
||||
end
|
||||
|
||||
module Link
|
||||
include Kernel
|
||||
end
|
||||
|
||||
module Shebang
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
|
||||
@ -61,7 +61,7 @@ class SystemCommand
|
||||
@executable = executable
|
||||
@args = args
|
||||
@sudo = sudo
|
||||
@input = [*input]
|
||||
@input = Array(input)
|
||||
@print_stdout = print_stdout
|
||||
@print_stderr = print_stderr
|
||||
@verbose = verbose
|
||||
|
||||
@ -21,7 +21,7 @@ RSpec/InstanceVariable:
|
||||
- 'utils/git_spec.rb'
|
||||
- 'version_spec.rb'
|
||||
|
||||
# Offense count: 74
|
||||
# Offense count: 75
|
||||
RSpec/MultipleDescribes:
|
||||
Exclude:
|
||||
- 'ENV_spec.rb'
|
||||
@ -94,6 +94,7 @@ RSpec/MultipleDescribes:
|
||||
- 'rubocops/class_spec.rb'
|
||||
- 'rubocops/formula_desc_spec.rb'
|
||||
- 'rubocops/lines_spec.rb'
|
||||
- 'rubocops/text_spec.rb'
|
||||
- 'rubocops/urls_spec.rb'
|
||||
- 'software_spec_spec.rb'
|
||||
- 'tap_spec.rb'
|
||||
|
||||
@ -20,6 +20,26 @@ describe Cask::Cmd::List, :cask do
|
||||
EOS
|
||||
end
|
||||
|
||||
it "lists oneline" do
|
||||
casks = %w[
|
||||
local-caffeine
|
||||
third-party/tap/third-party-cask
|
||||
local-transmission
|
||||
].map { |c| Cask::CaskLoader.load(c) }
|
||||
|
||||
casks.each do |c|
|
||||
InstallHelper.install_with_caskfile(c)
|
||||
end
|
||||
|
||||
expect {
|
||||
described_class.run("-1")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
local-caffeine
|
||||
local-transmission
|
||||
third-party-cask
|
||||
EOS
|
||||
end
|
||||
|
||||
it "lists full names" do
|
||||
casks = %w[
|
||||
local-caffeine
|
||||
@ -66,6 +86,31 @@ describe Cask::Cmd::List, :cask do
|
||||
end
|
||||
end
|
||||
|
||||
describe "lists json" do
|
||||
let(:casks) { ["local-caffeine", "local-transmission"] }
|
||||
let(:expected_output) {
|
||||
<<~EOS
|
||||
[{"token":"local-caffeine","name":[],"homepage":"https://brew.sh/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/caffeine.zip","appcast":null,"version":"1.2.3","sha256":"67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94","artifacts":[["Caffeine.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null},{"token":"local-transmission","name":["Transmission"],"homepage":"https://brew.sh/","url":"file:///usr/local/Homebrew/Library/Homebrew/test/support/fixtures/cask/transmission-2.61.dmg","appcast":null,"version":"2.61","sha256":"e44ffa103fbf83f55c8d0b1bea309a43b2880798dae8620b1ee8da5e1095ec68","artifacts":[["Transmission.app"]],"caveats":null,"depends_on":{},"conflicts_with":null,"container":null,"auto_updates":null}]
|
||||
EOS
|
||||
}
|
||||
|
||||
before do
|
||||
casks.map(&Cask::CaskLoader.method(:load)).each(&InstallHelper.method(:install_with_caskfile))
|
||||
end
|
||||
|
||||
it "of all installed Casks" do
|
||||
expect {
|
||||
described_class.run("--json")
|
||||
}.to output(expected_output).to_stdout
|
||||
end
|
||||
|
||||
it "of given Casks" do
|
||||
expect {
|
||||
described_class.run("--json", "local-caffeine", "local-transmission")
|
||||
}.to output(expected_output).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
describe "given a set of installed Casks" do
|
||||
let(:caffeine) { Cask::CaskLoader.load(cask_path("local-caffeine")) }
|
||||
let(:transmission) { Cask::CaskLoader.load(cask_path("local-transmission")) }
|
||||
|
||||
@ -179,60 +179,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
# Intentionally outputted non-interpolated strings
|
||||
# rubocop:disable Lint/InterpolationCheck
|
||||
describe "#line_problems" do
|
||||
specify "pkgshare" do
|
||||
fa = formula_auditor "foo", <<~RUBY, strict: true
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
end
|
||||
RUBY
|
||||
|
||||
fa.line_problems 'ohai "#{share}/foo"', 3
|
||||
expect(fa.problems.shift).to eq("Use \#{pkgshare} instead of \#{share}/foo")
|
||||
|
||||
fa.line_problems 'ohai "#{share}/foo/bar"', 3
|
||||
expect(fa.problems.shift).to eq("Use \#{pkgshare} instead of \#{share}/foo")
|
||||
|
||||
fa.line_problems 'ohai share/"foo"', 3
|
||||
expect(fa.problems.shift).to eq('Use pkgshare instead of (share/"foo")')
|
||||
|
||||
fa.line_problems 'ohai share/"foo/bar"', 3
|
||||
expect(fa.problems.shift).to eq('Use pkgshare instead of (share/"foo")')
|
||||
|
||||
fa.line_problems 'ohai "#{share}/foo-bar"', 3
|
||||
expect(fa.problems).to eq([])
|
||||
|
||||
fa.line_problems 'ohai share/"foo-bar"', 3
|
||||
expect(fa.problems).to eq([])
|
||||
|
||||
fa.line_problems 'ohai share/"bar"', 3
|
||||
expect(fa.problems).to eq([])
|
||||
end
|
||||
|
||||
# Regression test for https://github.com/Homebrew/legacy-homebrew/pull/48744
|
||||
# Formulae with "++" in their name would break various audit regexps:
|
||||
# Error: nested *?+ in regexp: /^libxml++3\s/
|
||||
specify "++ in name" do
|
||||
fa = formula_auditor "foolibc++", <<~RUBY, strict: true
|
||||
class Foolibcxx < Formula
|
||||
desc "foolibc++ is a test"
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
end
|
||||
RUBY
|
||||
|
||||
fa.line_problems 'ohai "#{share}/foolibc++"', 3
|
||||
expect(fa.problems.shift)
|
||||
.to eq("Use \#{pkgshare} instead of \#{share}/foolibc++")
|
||||
|
||||
fa.line_problems 'ohai share/"foolibc++"', 3
|
||||
expect(fa.problems.shift)
|
||||
.to eq('Use pkgshare instead of (share/"foolibc++")')
|
||||
end
|
||||
end
|
||||
# rubocop:enable Lint/InterpolationCheck
|
||||
|
||||
describe "#audit_github_repository" do
|
||||
specify "#audit_github_repository when HOMEBREW_NO_GITHUB_API is set" do
|
||||
ENV["HOMEBREW_NO_GITHUB_API"] = "1"
|
||||
@ -596,7 +542,7 @@ module Homebrew
|
||||
include_examples "formulae exist", described_class::VERSIONED_KEG_ONLY_ALLOWLIST
|
||||
include_examples "formulae exist", described_class::VERSIONED_HEAD_SPEC_ALLOWLIST
|
||||
include_examples "formulae exist", described_class::USES_FROM_MACOS_ALLOWLIST
|
||||
include_examples "formulae exist", described_class::THROTTLED_DENYLIST.keys
|
||||
include_examples "formulae exist", described_class::THROTTLED_FORMULAE.keys
|
||||
include_examples "formulae exist", described_class::UNSTABLE_ALLOWLIST.keys
|
||||
include_examples "formulae exist", described_class::GNOME_DEVEL_ALLOWLIST.keys
|
||||
end
|
||||
|
||||
@ -50,6 +50,7 @@ describe OS::Mac::Version do
|
||||
end
|
||||
|
||||
specify "#requires_nehalem_cpu?" do
|
||||
expect(Hardware::CPU).to receive(:type).at_least(:twice).and_return(:intel)
|
||||
expect(described_class.new("10.14").requires_nehalem_cpu?).to be true
|
||||
expect(described_class.new("10.12").requires_nehalem_cpu?).to be false
|
||||
end
|
||||
|
||||
@ -447,12 +447,10 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
|
||||
end
|
||||
|
||||
it "there is a on_macos block but no on_linux block" do
|
||||
expect_offense(<<~RUBY)
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
|
||||
resource do
|
||||
^^^^^^^^^^^ you need to define an `on_linux` block within your resource block.
|
||||
on_macos do
|
||||
url "https://brew.sh/resource1.tar.gz"
|
||||
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
|
||||
@ -463,12 +461,10 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
|
||||
end
|
||||
|
||||
it "there is a on_linux block but no on_macos block" do
|
||||
expect_offense(<<~RUBY)
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
|
||||
resource do
|
||||
^^^^^^^^^^^ you need to define an `on_macos` block within your resource block.
|
||||
on_linux do
|
||||
url "https://brew.sh/resource1.tar.gz"
|
||||
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
|
||||
|
||||
@ -5,14 +5,34 @@ require "rubocops/conflicts"
|
||||
describe RuboCop::Cop::FormulaAudit::Conflicts do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "When auditing formula for conflicts with" do
|
||||
it "multiple conflicts_with" do
|
||||
context "When auditing conflicts_with" do
|
||||
it "conflicts_with reason is capitalized" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", :because => "Reason"
|
||||
^^^^^^^^ 'Reason' from the `conflicts_with` reason should be 'reason'.
|
||||
conflicts_with "baz", :because => "Foo is the formula name which does not require downcasing"
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "conflicts_with reason ends with a period" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", "baz", :because => "reason."
|
||||
^^^^^^^^^ `conflicts_with` reason should not end with a period.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "conflicts_with in a versioned formula" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo@2.0.rb")
|
||||
class FooAT20 < Formula
|
||||
url 'https://brew.sh/foo-2.0.tgz'
|
||||
conflicts_with "mysql", "mariadb", "percona-server",
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Versioned formulae should not use `conflicts_with`. Use `keg_only :versioned_formula` instead.
|
||||
:because => "both install plugins"
|
||||
conflicts_with "mysql", "mariadb"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Versioned formulae should not use `conflicts_with`. Use `keg_only :versioned_formula` instead.
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
@ -21,10 +41,48 @@ describe RuboCop::Cop::FormulaAudit::Conflicts do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo@2.0.rb")
|
||||
class FooAT20 < Formula
|
||||
url 'https://brew.sh/foo-2.0.tgz'
|
||||
desc 'Bar'
|
||||
homepage "https://brew.sh"
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "auto-corrects capitalized reason" do
|
||||
source = <<~RUBY
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", :because => "Reason"
|
||||
end
|
||||
RUBY
|
||||
|
||||
corrected_source = <<~RUBY
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", :because => "reason"
|
||||
end
|
||||
RUBY
|
||||
|
||||
new_source = autocorrect_source(source)
|
||||
expect(new_source).to eq(corrected_source)
|
||||
end
|
||||
|
||||
it "auto-corrects trailing period" do
|
||||
source = <<~RUBY
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", :because => "reason."
|
||||
end
|
||||
RUBY
|
||||
|
||||
corrected_source = <<~RUBY
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
conflicts_with "bar", :because => "reason"
|
||||
end
|
||||
RUBY
|
||||
|
||||
new_source = autocorrect_source(source)
|
||||
expect(new_source).to eq(corrected_source)
|
||||
end
|
||||
end
|
||||
|
||||
include_examples "formulae exist", described_class::ALLOWLIST
|
||||
|
||||
@ -73,8 +73,8 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
|
||||
RUBY
|
||||
|
||||
inspect_source(source)
|
||||
if homepage.match?(%r{http://www\.freedesktop\.org})
|
||||
if homepage.match?(/Software/)
|
||||
if homepage.include?("http://www.freedesktop.org")
|
||||
if homepage.include?("Software")
|
||||
expected_offenses = [{ message: "#{homepage} should be styled " \
|
||||
"`https://wiki.freedesktop.org/www/Software/project_name`",
|
||||
severity: :convention,
|
||||
@ -89,7 +89,7 @@ describe RuboCop::Cop::FormulaAudit::Homepage do
|
||||
column: 2,
|
||||
source: source }]
|
||||
end
|
||||
elsif homepage.match?(%r{https://code\.google\.com})
|
||||
elsif homepage.include?("https://code.google.com")
|
||||
expected_offenses = [{ message: "#{homepage} should end with a slash",
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
|
||||
@ -201,6 +201,24 @@ describe RuboCop::Cop::FormulaAudit::OptionDeclarations do
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "build.without? in dependencies" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on "bar" if build.without?("baz")
|
||||
^^^^^^^^^^^^^^^^^^^^^ Use `:optional` or `:recommended` instead of `if build.without?("baz")`
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "build.with? in dependencies" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on "bar" if build.with?("baz")
|
||||
^^^^^^^^^^^^^^^^^^ Use `:optional` or `:recommended` instead of `if build.with?("baz")`
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "unless build.without? conditional" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
@ -279,27 +297,14 @@ describe RuboCop::Cop::FormulaAudit::OptionDeclarations do
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "build.include? conditional" do
|
||||
it "build.include? deprecated" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
desc "foo"
|
||||
url 'https://brew.sh/foo-1.0.tgz'
|
||||
def post_install
|
||||
return if build.include? "without-bar"
|
||||
^^^^^^^^^^^ Use build.without? \"bar\" instead of build.include? 'without-bar'
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "build.include? with dashed args conditional" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
desc "foo"
|
||||
url 'https://brew.sh/foo-1.0.tgz'
|
||||
def post_install
|
||||
return if build.include? "--bar"
|
||||
^^^^^ Reference 'bar' without dashes
|
||||
return if build.include? "foo"
|
||||
^^^^^^^^^^^^^^^^^^^^ `build.include?` is deprecated
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
@ -48,7 +48,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
|
||||
EOS
|
||||
|
||||
inspect_source(source)
|
||||
expected_offense = if patch_url.match?(%r{/raw\.github\.com/})
|
||||
expected_offense = if patch_url.include?("/raw.github.com/")
|
||||
[{ message:
|
||||
<<~EOS.chomp,
|
||||
GitHub/Gist patches should specify a revision:
|
||||
@ -58,7 +58,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
|
||||
line: 5,
|
||||
column: 12,
|
||||
source: source }]
|
||||
elsif patch_url.match?(%r{macports/trunk})
|
||||
elsif patch_url.include?("macports/trunk")
|
||||
[{ message:
|
||||
<<~EOS.chomp,
|
||||
MacPorts patches should specify a revision instead of trunk:
|
||||
@ -232,7 +232,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
|
||||
RUBY
|
||||
|
||||
inspect_source(source)
|
||||
expected_offense = if patch_url.match?(%r{/raw\.github\.com/})
|
||||
expected_offense = if patch_url.include?("/raw.github.com/")
|
||||
[{ message:
|
||||
<<~EOS.chomp,
|
||||
GitHub/Gist patches should specify a revision:
|
||||
@ -242,7 +242,7 @@ describe RuboCop::Cop::FormulaAudit::Patches do
|
||||
line: 5,
|
||||
column: 16,
|
||||
source: source }]
|
||||
elsif patch_url.match?(%r{macports/trunk})
|
||||
elsif patch_url.include?("macports/trunk")
|
||||
[{ message:
|
||||
<<~EOS.chomp,
|
||||
MacPorts patches should specify a revision instead of trunk:
|
||||
|
||||
@ -6,6 +6,17 @@ describe RuboCop::Cop::FormulaAudit::Text do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "When auditing formula text" do
|
||||
it "with `require \"formula\"` is present" do
|
||||
expect_offense(<<~RUBY)
|
||||
require "formula"
|
||||
^^^^^^^^^^^^^^^^^ `require "formula"` is now unnecessary
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
homepage "https://brew.sh"
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "with both openssl and libressl optional dependencies" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
@ -215,5 +226,248 @@ describe RuboCop::Cop::FormulaAudit::Text do
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When make calls are not separated" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
def install
|
||||
system "make && make install"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use separate `make` calls
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When concatenating in string interpolation" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "foo \#{bar + "baz"}"
|
||||
^^^^^^^^^^^^^^ Do not concatenate paths in string interpolation
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using JAVA_HOME without a java dependency" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "JAVA_HOME"
|
||||
^^^^^^^^^^^ Use `depends_on :java` to set JAVA_HOME
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using JAVA_HOME with an openjdk dependency" do
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on "openjdk"
|
||||
def install
|
||||
ohai "JAVA_HOME"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using JAVA_HOME with an openjdk build dependency" do
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on "openjdk" => :build
|
||||
def install
|
||||
ohai "JAVA_HOME"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using JAVA_HOME with a java dependency" do
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on :java
|
||||
def install
|
||||
ohai "JAVA_HOME"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using JAVA_HOME with a java build dependency" do
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
depends_on :java => :build
|
||||
def install
|
||||
ohai "JAVA_HOME"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using `prefix + \"bin\"` instead of `bin`" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai prefix + "bin"
|
||||
^^^^^^^^^^^^^^ Use `bin` instead of `prefix + "bin"`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "When using `prefix + \"bin/foo\"` instead of `bin`" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai prefix + "bin/foo"
|
||||
^^^^^^^^^^^^^^^^^^ Use `bin` instead of `prefix + "bin"`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe RuboCop::Cop::FormulaAuditStrict::Text do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "When auditing formula text" do
|
||||
it "when deprecated `env :userpaths` is present" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
|
||||
env :userpaths
|
||||
^^^^^^^^^^^^^^ `env :userpaths` in homebrew/core formulae is deprecated
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when deprecated `env :std` is present in homebrew-core" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/")
|
||||
class Foo < Formula
|
||||
url "https://brew.sh/foo-1.0.tgz"
|
||||
|
||||
env :std
|
||||
^^^^^^^^ `env :std` in homebrew/core formulae is deprecated
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `\#{share}/foo` is used instead of `\#{pkgshare}`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "\#{share}/foo"
|
||||
^^^^^^^^^^^^^^ Use `\#{pkgshare}` instead of `\#{share}/foo`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `\#{share}/foo/bar` is used instead of `\#{pkgshare}/bar`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "\#{share}/foo/bar"
|
||||
^^^^^^^^^^^^^^^^^^ Use `\#{pkgshare}` instead of `\#{share}/foo`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `\#{share}/foolibc++` is used instead of `\#{pkgshare}/foolibc++`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foolibc++.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "\#{share}/foolibc++"
|
||||
^^^^^^^^^^^^^^^^^^^^ Use `\#{pkgshare}` instead of `\#{share}/foolibc++`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `share/\"foo\"` is used instead of `pkgshare`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"foo"
|
||||
^^^^^^^^^^^ Use `pkgshare` instead of `share/"foo"`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `share/\"foo/bar\"` is used instead of `pkgshare`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"foo/bar"
|
||||
^^^^^^^^^^^^^^^ Use `pkgshare` instead of `share/"foo"`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `share/\"foolibc++\"` is used instead of `pkgshare`" do
|
||||
expect_offense(<<~RUBY, "/homebrew-core/Formula/foolibc++.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"foolibc++"
|
||||
^^^^^^^^^^^^^^^^^ Use `pkgshare` instead of `share/"foolibc++"`
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `\#{share}/foo-bar` doesn't match formula name" do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "\#{share}/foo-bar"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `share/foo-bar` doesn't match formula name" do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"foo-bar"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when `share/bar` doesn't match formula name" do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"bar"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when formula name appears afer `share/\"bar\"`" do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai share/"bar/foo"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "when formula name appears afer `\"\#{share}/bar\"`" do
|
||||
expect_no_offenses(<<~RUBY, "/homebrew-core/Formula/foo.rb")
|
||||
class Foo < Formula
|
||||
def install
|
||||
ohai "\#{share}/bar/foo"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -245,29 +245,32 @@ end
|
||||
describe RuboCop::Cop::FormulaAudit::PyPiUrls do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "when a pypi.python.org URL is used" do
|
||||
it "reports an offense" do
|
||||
context "when a pypi URL is used" do
|
||||
it "reports an offense for pypi.python.org urls" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
desc "foo"
|
||||
url "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz should be `https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use the `Source` url found on PyPI downloads page (`https://pypi.org/project/foo/#files`)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "support auto-correction" do
|
||||
corrected = autocorrect_source(<<~RUBY)
|
||||
it "reports an offense for short file.pythonhosted.org urls" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
desc "foo"
|
||||
url "https://pypi.python.org/packages/source/foo/foo-0.1.tar.gz"
|
||||
url "https://files.pythonhosted.org/packages/source/f/foo/foo-0.1.tar.gz"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use the `Source` url found on PyPI downloads page (`https://pypi.org/project/foo/#files`)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
expect(corrected).to eq <<~RUBY
|
||||
it "reports no offenses for long file.pythonhosted.org urls" do
|
||||
expect_no_offenses(<<~RUBY)
|
||||
class Foo < Formula
|
||||
desc "foo"
|
||||
url "https://files.pythonhosted.org/packages/source/foo/foo-0.1.tar.gz"
|
||||
url "https://files.pythonhosted.org/packages/a0/b1/a01b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f/foo-0.1.tar.gz"
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
@ -161,6 +161,12 @@ RSpec.shared_context "integration test" do
|
||||
content = <<~RUBY
|
||||
url "https://brew.sh/#{name}-1.0"
|
||||
RUBY
|
||||
|
||||
when "package_license"
|
||||
content = <<~RUBY
|
||||
url "https://brew.sh/#patchelf-1.0"
|
||||
license "0BSD"
|
||||
RUBY
|
||||
end
|
||||
|
||||
Formulary.core_path(name).tap do |formula_path|
|
||||
|
||||
@ -9,35 +9,67 @@ describe Git do
|
||||
HOMEBREW_CACHE.cd do
|
||||
system git, "init"
|
||||
|
||||
File.open(file, "w") { |f| f.write("blah") }
|
||||
system git, "add", HOMEBREW_CACHE/file
|
||||
File.open("README.md", "w") { |f| f.write("README") }
|
||||
system git, "add", HOMEBREW_CACHE/"README.md"
|
||||
system git, "commit", "-m", "'File added'"
|
||||
@h1 = `git rev-parse HEAD`
|
||||
|
||||
File.open(file, "w") { |f| f.write("brew") }
|
||||
system git, "add", HOMEBREW_CACHE/file
|
||||
File.open("README.md", "w") { |f| f.write("# README") }
|
||||
system git, "add", HOMEBREW_CACHE/"README.md"
|
||||
system git, "commit", "-m", "'written to File'"
|
||||
@h2 = `git rev-parse HEAD`
|
||||
|
||||
File.open("LICENSE.txt", "w") { |f| f.write("LICENCE") }
|
||||
system git, "add", HOMEBREW_CACHE/"LICENSE.txt"
|
||||
system git, "commit", "-m", "'File added'"
|
||||
@h3 = `git rev-parse HEAD`
|
||||
|
||||
File.open("LICENSE.txt", "w") { |f| f.write("LICENSE") }
|
||||
system git, "add", HOMEBREW_CACHE/"LICENSE.txt"
|
||||
system git, "commit", "-m", "'written to File'"
|
||||
end
|
||||
end
|
||||
|
||||
let(:file) { "blah.rb" }
|
||||
let(:hash1) { @h1[0..6] }
|
||||
let(:hash2) { @h2[0..6] }
|
||||
let(:file) { "README.md" }
|
||||
let(:file_hash1) { @h1[0..6] }
|
||||
let(:file_hash2) { @h2[0..6] }
|
||||
let(:files) { ["README.md", "LICENSE.txt"] }
|
||||
let(:files_hash1) { [@h3[0..6], ["LICENSE.txt"]] }
|
||||
let(:files_hash2) { [@h2[0..6], ["README.md"]] }
|
||||
|
||||
describe "#last_revision_commit_of_file" do
|
||||
it "gives last revision commit when before_commit is nil" do
|
||||
expect(
|
||||
described_class.last_revision_commit_of_file(HOMEBREW_CACHE, file),
|
||||
).to eq(hash1)
|
||||
).to eq(file_hash1)
|
||||
end
|
||||
|
||||
it "gives revision commit based on before_commit when it is not nil" do
|
||||
expect(
|
||||
described_class.last_revision_commit_of_file(HOMEBREW_CACHE,
|
||||
file,
|
||||
before_commit: hash2),
|
||||
).to eq(hash2)
|
||||
before_commit: file_hash2),
|
||||
).to eq(file_hash2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#last_revision_commit_of_files" do
|
||||
context "when before_commit is nil" do
|
||||
it "gives last revision commit" do
|
||||
expect(
|
||||
described_class.last_revision_commit_of_files(HOMEBREW_CACHE, files),
|
||||
).to eq(files_hash1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when before_commit is not nil" do
|
||||
it "gives last revision commit" do
|
||||
expect(
|
||||
described_class.last_revision_commit_of_files(HOMEBREW_CACHE,
|
||||
files,
|
||||
before_commit: file_hash2),
|
||||
).to eq(files_hash2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -46,14 +78,14 @@ describe Git do
|
||||
expect(
|
||||
described_class.last_revision_of_file(HOMEBREW_CACHE,
|
||||
HOMEBREW_CACHE/file),
|
||||
).to eq("blah")
|
||||
).to eq("README")
|
||||
end
|
||||
|
||||
it "returns last revision of file based on before_commit" do
|
||||
expect(
|
||||
described_class.last_revision_of_file(HOMEBREW_CACHE, HOMEBREW_CACHE/file,
|
||||
before_commit: "0..3"),
|
||||
).to eq("brew")
|
||||
).to eq("# README")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -471,6 +471,13 @@ module GitHub
|
||||
scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
|
||||
end
|
||||
|
||||
def workflow_dispatch_event(user, repo, workflow, ref, **inputs)
|
||||
url = "#{API_URL}/repos/#{user}/#{repo}/actions/workflows/#{workflow}/dispatches"
|
||||
open_api(url, data: { ref: ref, inputs: inputs },
|
||||
request_method: :POST,
|
||||
scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
|
||||
end
|
||||
|
||||
def get_artifact_url(user, repo, pr, workflow_id: "tests.yml", artifact_name: "bottles")
|
||||
scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES
|
||||
base_url = "#{API_URL}/repos/#{user}/#{repo}"
|
||||
|
||||
@ -16,6 +16,11 @@ class User < DelegateClass(String)
|
||||
end
|
||||
|
||||
def self.current
|
||||
@current ||= new(Etc.getpwuid(Process.euid).name)
|
||||
return @current if defined?(@current)
|
||||
|
||||
pwuid = Etc.getpwuid(Process.euid)
|
||||
return if pwuid.nil?
|
||||
|
||||
@current = new(pwuid.name)
|
||||
end
|
||||
end
|
||||
|
||||
19
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
19
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
@ -4,29 +4,31 @@ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
||||
ruby_version = RbConfig::CONFIG["ruby_version"]
|
||||
path = File.expand_path('..', __FILE__)
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.8.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.8.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.14.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thread_safe-0.3.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-1.2.7/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.3.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.4.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.0.3.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.7/lib"
|
||||
$:.unshift "#{path}/"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/byebug-11.1.3"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/byebug-11.1.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/colorize-0.8.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/json-2.3.1"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/json-2.3.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/docile-1.3.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-html-0.12.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.18.5/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/url-0.3.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/codecov-0.1.17/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/codecov-0.2.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/connection_pool-2.2.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/diff-lcs-1.4.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/unf_ext-0.0.7.7"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf_ext-0.0.7.7/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf-0.1.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/domain_name-0.5.20190701/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/elftools-1.1.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/hpricot-0.8.6"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/hpricot-0.8.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/http-cookie-1.0.3/lib"
|
||||
@ -44,6 +46,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mustache-1.1.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.19.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.0.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.7.1.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.1.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.5.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/rdiscount-2.2.0.1"
|
||||
@ -59,10 +62,10 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.9.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.1.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.2.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.7.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.87.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.6.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.41.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.88.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.7.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.42.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.2.0/lib"
|
||||
|
||||
@ -20,7 +20,7 @@ module I18n
|
||||
|
||||
# Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
|
||||
def fallbacks=(fallbacks)
|
||||
@@fallbacks = fallbacks
|
||||
@@fallbacks = fallbacks.is_a?(I18n::Locale::Fallbacks) ? fallbacks : I18n::Locale::Fallbacks.new(fallbacks)
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user