Merge branch 'master' into appcast-configuration-match
This commit is contained in:
commit
446ef2c85f
2
.github/ISSUE_TEMPLATE/feature.md
vendored
2
.github/ISSUE_TEMPLATE/feature.md
vendored
@ -4,6 +4,8 @@ about: Request our thoughts on your suggestion for a new feature for Homebrew.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.
|
||||||
|
|
||||||
<!-- Please fill these sections with the relevant information: -->
|
<!-- Please fill these sections with the relevant information: -->
|
||||||
|
|
||||||
# A detailed description of the proposed feature
|
# A detailed description of the proposed feature
|
||||||
|
|||||||
17
.github/workflows/docker.yml
vendored
17
.github/workflows/docker.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: ["18.04", "20.04"]
|
version: ["16.04", "18.04", "20.04"]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
@ -33,9 +33,24 @@ jobs:
|
|||||||
docker login docker.pkg.github.com -u BrewTestBot -p ${{secrets.GITHUB_TOKEN}}
|
docker login docker.pkg.github.com -u BrewTestBot -p ${{secrets.GITHUB_TOKEN}}
|
||||||
docker tag brew "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:$brew_version"
|
docker tag brew "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:$brew_version"
|
||||||
docker push "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:$brew_version"
|
docker push "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:$brew_version"
|
||||||
|
docker tag brew "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:latest"
|
||||||
|
docker push "docker.pkg.github.com/homebrew/brew/ubuntu${{matrix.version}}:latest"
|
||||||
- name: Deploy the tagged Docker image to Docker Hub
|
- name: Deploy the tagged Docker image to Docker Hub
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
docker login -u brewtestbot -p ${{secrets.DOCKER_TOKEN}}
|
docker login -u brewtestbot -p ${{secrets.DOCKER_TOKEN}}
|
||||||
docker tag brew "homebrew/ubuntu${{matrix.version}}:$brew_version"
|
docker tag brew "homebrew/ubuntu${{matrix.version}}:$brew_version"
|
||||||
docker push "homebrew/ubuntu${{matrix.version}}:$brew_version"
|
docker push "homebrew/ubuntu${{matrix.version}}:$brew_version"
|
||||||
|
docker tag brew "homebrew/ubuntu${{matrix.version}}:latest"
|
||||||
|
docker push "homebrew/ubuntu${{matrix.version}}:latest"
|
||||||
|
- name: Deploy the homebrew/brew Docker image to GitHub and Docker Hub
|
||||||
|
if: startsWith(github.ref, 'refs/tags/') && matrix.version == '20.04'
|
||||||
|
run: |
|
||||||
|
docker tag brew "docker.pkg.github.com/homebrew/brew/brew:$brew_version"
|
||||||
|
docker push "docker.pkg.github.com/homebrew/brew/brew:$brew_version"
|
||||||
|
docker tag brew "docker.pkg.github.com/homebrew/brew/brew:latest"
|
||||||
|
docker push "docker.pkg.github.com/homebrew/brew/brew:latest"
|
||||||
|
docker tag brew "homebrew/brew:$brew_version"
|
||||||
|
docker push "homebrew/brew:$brew_version"
|
||||||
|
docker tag brew "homebrew/brew:latest"
|
||||||
|
docker push "homebrew/brew:latest"
|
||||||
|
|||||||
23
.github/workflows/tests.yml
vendored
23
.github/workflows/tests.yml
vendored
@ -3,9 +3,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: master
|
branches: master
|
||||||
pull_request: []
|
pull_request: []
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
env:
|
env:
|
||||||
HOMEBREW_GITHUB_ACTIONS: 1
|
HOMEBREW_GITHUB_ACTIONS: 1
|
||||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
@ -71,6 +68,9 @@ jobs:
|
|||||||
else
|
else
|
||||||
# Link old gettext (otherwise `brew doctor` is sad)
|
# Link old gettext (otherwise `brew doctor` is sad)
|
||||||
brew link gettext
|
brew link gettext
|
||||||
|
|
||||||
|
# remove deleted formula
|
||||||
|
brew uninstall --force python@2
|
||||||
fi
|
fi
|
||||||
brew doctor
|
brew doctor
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: docker build -t brew .
|
run: docker build -t brew --build-arg=version=16.04 .
|
||||||
|
|
||||||
- name: Run brew test-bot
|
- name: Run brew test-bot
|
||||||
run: |
|
run: |
|
||||||
@ -184,16 +184,11 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Deploy the Docker image to GitHub and Docker Hub
|
- name: Deploy the Docker image to GitHub and Docker Hub
|
||||||
if: matrix.os == 'ubuntu-latest' && (github.ref == 'refs/heads/master' || github.event_name == 'release')
|
if: matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master'
|
||||||
run: |
|
run: |
|
||||||
case $GITHUB_REF in
|
|
||||||
refs/heads/master) v=latest ;;
|
|
||||||
refs/tags/*) v=${GITHUB_REF:10} ;;
|
|
||||||
*) echo Error: unexpected GITHUB_REF: $GITHUB_REF; exit 1 ;;
|
|
||||||
esac
|
|
||||||
docker login docker.pkg.github.com -u BrewTestBot -p ${{secrets.GITHUB_TOKEN}}
|
docker login docker.pkg.github.com -u BrewTestBot -p ${{secrets.GITHUB_TOKEN}}
|
||||||
docker tag brew "docker.pkg.github.com/homebrew/brew/brew:$v"
|
docker tag brew "docker.pkg.github.com/homebrew/brew/ubuntu16.04:master"
|
||||||
docker push "docker.pkg.github.com/homebrew/brew/brew:$v"
|
docker push "docker.pkg.github.com/homebrew/brew/ubuntu16.04:master"
|
||||||
docker login -u brewtestbot -p ${{secrets.DOCKER_TOKEN}}
|
docker login -u brewtestbot -p ${{secrets.DOCKER_TOKEN}}
|
||||||
docker tag brew "homebrew/brew:$v"
|
docker tag brew "homebrew/ubuntu16.04:master"
|
||||||
docker push "homebrew/brew:$v"
|
docker push "homebrew/ubuntu16.04:master"
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -110,6 +110,7 @@
|
|||||||
**/vendor/bundle/ruby/*/gems/pry-*/
|
**/vendor/bundle/ruby/*/gems/pry-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rainbow-*/
|
**/vendor/bundle/ruby/*/gems/rainbow-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rdiscount-*/
|
**/vendor/bundle/ruby/*/gems/rdiscount-*/
|
||||||
|
**/vendor/bundle/ruby/*/gems/regexp_parser-*/
|
||||||
**/vendor/bundle/ruby/*/gems/ronn-*/
|
**/vendor/bundle/ruby/*/gems/ronn-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rspec-*/
|
**/vendor/bundle/ruby/*/gems/rspec-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rspec-core-*/
|
**/vendor/bundle/ruby/*/gems/rspec-core-*/
|
||||||
@ -120,6 +121,7 @@
|
|||||||
**/vendor/bundle/ruby/*/gems/rspec-support-*/
|
**/vendor/bundle/ruby/*/gems/rspec-support-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rspec-wait-*/
|
**/vendor/bundle/ruby/*/gems/rspec-wait-*/
|
||||||
**/vendor/bundle/ruby/*/gems/rubocop-0*/
|
**/vendor/bundle/ruby/*/gems/rubocop-0*/
|
||||||
|
**/vendor/bundle/ruby/*/gems/rubocop-ast-*/
|
||||||
**/vendor/bundle/ruby/*/gems/ruby-prof-*/
|
**/vendor/bundle/ruby/*/gems/ruby-prof-*/
|
||||||
**/vendor/bundle/ruby/*/gems/ruby-progressbar-*/
|
**/vendor/bundle/ruby/*/gems/ruby-progressbar-*/
|
||||||
**/vendor/bundle/ruby/*/gems/simplecov-*/
|
**/vendor/bundle/ruby/*/gems/simplecov-*/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ARG version=16.04
|
ARG version=20.04
|
||||||
FROM ubuntu:$version
|
FROM ubuntu:$version
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
@ -42,6 +42,8 @@ RUN cd /home/linuxbrew/.linuxbrew \
|
|||||||
&& HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \
|
&& HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \
|
||||||
&& brew install-bundler-gems \
|
&& brew install-bundler-gems \
|
||||||
&& brew cleanup \
|
&& brew cleanup \
|
||||||
|
&& { git -C /home/linuxbrew/.linuxbrew/Homebrew config --unset gc.auto; true; } \
|
||||||
|
&& { git -C /home/linuxbrew/.linuxbrew/Homebrew config --unset homebrew.devcmdrun; true; } \
|
||||||
&& rm -rf ~/.cache \
|
&& rm -rf ~/.cache \
|
||||||
&& chown -R linuxbrew: /home/linuxbrew/.linuxbrew \
|
&& chown -R linuxbrew: /home/linuxbrew/.linuxbrew \
|
||||||
&& chmod -R g+w,o-w /home/linuxbrew/.linuxbrew
|
&& chmod -R g+w,o-w /home/linuxbrew/.linuxbrew
|
||||||
|
|||||||
@ -8,7 +8,7 @@ AllCops:
|
|||||||
|
|
||||||
# Use `<<~` for heredocs.
|
# Use `<<~` for heredocs.
|
||||||
Layout/HeredocIndentation:
|
Layout/HeredocIndentation:
|
||||||
EnforcedStyle: squiggly
|
Enabled: true
|
||||||
|
|
||||||
# Not useful in casks and formulae.
|
# Not useful in casks and formulae.
|
||||||
Metrics/BlockLength:
|
Metrics/BlockLength:
|
||||||
|
|||||||
@ -10,7 +10,7 @@ GEM
|
|||||||
ast (2.4.0)
|
ast (2.4.0)
|
||||||
byebug (11.1.3)
|
byebug (11.1.3)
|
||||||
concurrent-ruby (1.1.6)
|
concurrent-ruby (1.1.6)
|
||||||
connection_pool (2.2.2)
|
connection_pool (2.2.3)
|
||||||
coveralls (0.8.23)
|
coveralls (0.8.23)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov (~> 0.16.1)
|
simplecov (~> 0.16.1)
|
||||||
@ -24,7 +24,7 @@ GEM
|
|||||||
hpricot (0.8.6)
|
hpricot (0.8.6)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
i18n (1.8.2)
|
i18n (1.8.3)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
json (2.3.0)
|
json (2.3.0)
|
||||||
mechanize (2.7.6)
|
mechanize (2.7.6)
|
||||||
@ -51,11 +51,12 @@ GEM
|
|||||||
parallel (1.19.1)
|
parallel (1.19.1)
|
||||||
parallel_tests (2.32.0)
|
parallel_tests (2.32.0)
|
||||||
parallel
|
parallel
|
||||||
parser (2.7.1.2)
|
parser (2.7.1.3)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
plist (3.5.0)
|
plist (3.5.0)
|
||||||
rainbow (3.0.0)
|
rainbow (3.0.0)
|
||||||
rdiscount (2.2.0.1)
|
rdiscount (2.2.0.1)
|
||||||
|
regexp_parser (1.7.0)
|
||||||
rexml (3.2.4)
|
rexml (3.2.4)
|
||||||
ronn (0.7.3)
|
ronn (0.7.3)
|
||||||
hpricot (>= 0.8.2)
|
hpricot (>= 0.8.2)
|
||||||
@ -81,14 +82,18 @@ GEM
|
|||||||
rspec-support (3.9.3)
|
rspec-support (3.9.3)
|
||||||
rspec-wait (0.0.9)
|
rspec-wait (0.0.9)
|
||||||
rspec (>= 3, < 4)
|
rspec (>= 3, < 4)
|
||||||
rubocop (0.83.0)
|
rubocop (0.85.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 2.7.0.1)
|
parser (>= 2.7.0.1)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
|
regexp_parser (>= 1.7)
|
||||||
rexml
|
rexml
|
||||||
|
rubocop-ast (>= 0.0.3)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 1.4.0, < 2.0)
|
unicode-display_width (>= 1.4.0, < 2.0)
|
||||||
rubocop-performance (1.5.2)
|
rubocop-ast (0.0.3)
|
||||||
|
parser (>= 2.7.0.1)
|
||||||
|
rubocop-performance (1.6.1)
|
||||||
rubocop (>= 0.71.0)
|
rubocop (>= 0.71.0)
|
||||||
rubocop-rspec (1.39.0)
|
rubocop-rspec (1.39.0)
|
||||||
rubocop (>= 0.68.1)
|
rubocop (>= 0.68.1)
|
||||||
|
|||||||
@ -50,7 +50,7 @@ begin
|
|||||||
help_flag = !ENV["HOMEBREW_HELP"].nil?
|
help_flag = !ENV["HOMEBREW_HELP"].nil?
|
||||||
cmd = nil
|
cmd = nil
|
||||||
|
|
||||||
ARGV.dup.each_with_index do |arg, i|
|
ARGV.each_with_index do |arg, i|
|
||||||
break if help_flag && cmd
|
break if help_flag && cmd
|
||||||
|
|
||||||
if arg == "help" && !cmd
|
if arg == "help" && !cmd
|
||||||
@ -139,8 +139,8 @@ rescue UsageError => e
|
|||||||
require "help"
|
require "help"
|
||||||
Homebrew::Help.help cmd, usage_error: e.message
|
Homebrew::Help.help cmd, usage_error: e.message
|
||||||
rescue SystemExit => e
|
rescue SystemExit => e
|
||||||
onoe "Kernel.exit" if ARGV.debug? && !e.success?
|
onoe "Kernel.exit" if Homebrew.args.debug? && !e.success?
|
||||||
$stderr.puts e.backtrace if ARGV.debug?
|
$stderr.puts e.backtrace if Homebrew.args.debug?
|
||||||
raise
|
raise
|
||||||
rescue Interrupt
|
rescue Interrupt
|
||||||
$stderr.puts # seemingly a newline is typical
|
$stderr.puts # seemingly a newline is typical
|
||||||
@ -156,7 +156,7 @@ rescue RuntimeError, SystemCallError => e
|
|||||||
raise if e.message.empty?
|
raise if e.message.empty?
|
||||||
|
|
||||||
onoe e
|
onoe e
|
||||||
$stderr.puts e.backtrace if ARGV.debug?
|
$stderr.puts e.backtrace if Homebrew.args.debug?
|
||||||
|
|
||||||
output_unsupported_error if Homebrew.args.HEAD?
|
output_unsupported_error if Homebrew.args.HEAD?
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ rescue MethodDeprecatedError => e
|
|||||||
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):"
|
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):"
|
||||||
$stderr.puts " #{Formatter.url(e.issues_url)}"
|
$stderr.puts " #{Formatter.url(e.issues_url)}"
|
||||||
end
|
end
|
||||||
$stderr.puts e.backtrace if ARGV.debug?
|
$stderr.puts e.backtrace if Homebrew.args.debug?
|
||||||
exit 1
|
exit 1
|
||||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||||
onoe e
|
onoe e
|
||||||
|
|||||||
@ -52,6 +52,8 @@ class Build
|
|||||||
Requirement.prune
|
Requirement.prune
|
||||||
elsif req.prune_if_build_and_not_dependent?(dependent, formula)
|
elsif req.prune_if_build_and_not_dependent?(dependent, formula)
|
||||||
Requirement.prune
|
Requirement.prune
|
||||||
|
elsif req.test?
|
||||||
|
Requirement.prune
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -65,6 +67,8 @@ class Build
|
|||||||
Dependency.prune
|
Dependency.prune
|
||||||
elsif dep.build?
|
elsif dep.build?
|
||||||
Dependency.keep_but_prune_recursive_deps
|
Dependency.keep_but_prune_recursive_deps
|
||||||
|
elsif dep.test?
|
||||||
|
Dependency.prune
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -112,7 +116,7 @@ class Build
|
|||||||
}
|
}
|
||||||
|
|
||||||
with_env(new_env) do
|
with_env(new_env) do
|
||||||
formula.extend(Debrew::Formula) if ARGV.debug?
|
formula.extend(Debrew::Formula) if Homebrew.args.debug?
|
||||||
|
|
||||||
formula.update_head_version
|
formula.update_head_version
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@ module Cask
|
|||||||
args: ["list", service],
|
args: ["list", service],
|
||||||
sudo: with_sudo, print_stderr: false
|
sudo: with_sudo, print_stderr: false
|
||||||
).stdout
|
).stdout
|
||||||
if plist_status.match?(/^\{/)
|
if plist_status.start_with?("{")
|
||||||
command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo)
|
command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo)
|
||||||
sleep 1
|
sleep 1
|
||||||
end
|
end
|
||||||
@ -326,7 +326,14 @@ module Cask
|
|||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
yield path, Pathname.glob(resolved_path)
|
yield path, Pathname.glob(resolved_path)
|
||||||
|
rescue Errno::EPERM
|
||||||
|
raise if File.readable?(File.expand_path("~/Library/Application Support/com.apple.TCC"))
|
||||||
|
|
||||||
|
odie "Unable to remove some files. Please enable Full Disk Access for your terminal under " \
|
||||||
|
"System Preferences → Security & Privacy → Privacy → Full Disk Access."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ require "cask/download"
|
|||||||
require "digest"
|
require "digest"
|
||||||
require "utils/curl"
|
require "utils/curl"
|
||||||
require "utils/git"
|
require "utils/git"
|
||||||
|
require "utils/notability"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
class Audit
|
class Audit
|
||||||
@ -14,22 +15,22 @@ module Cask
|
|||||||
|
|
||||||
attr_reader :cask, :commit_range, :download
|
attr_reader :cask, :commit_range, :download
|
||||||
|
|
||||||
attr_predicate :check_appcast?
|
attr_predicate :appcast?
|
||||||
|
|
||||||
def initialize(cask, check_appcast: false, download: false, check_token_conflicts: false,
|
def initialize(cask, appcast: false, download: false,
|
||||||
commit_range: nil, command: SystemCommand)
|
token_conflicts: false, online: false, strict: false,
|
||||||
|
new_cask: false, commit_range: nil, command: SystemCommand)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
@check_appcast = check_appcast
|
@appcast = appcast
|
||||||
@download = download
|
@download = download
|
||||||
|
@online = online
|
||||||
|
@strict = strict
|
||||||
|
@new_cask = new_cask
|
||||||
@commit_range = commit_range
|
@commit_range = commit_range
|
||||||
@check_token_conflicts = check_token_conflicts
|
@token_conflicts = token_conflicts
|
||||||
@command = command
|
@command = command
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_token_conflicts?
|
|
||||||
@check_token_conflicts
|
|
||||||
end
|
|
||||||
|
|
||||||
def run!
|
def run!
|
||||||
check_blacklist
|
check_blacklist
|
||||||
check_required_stanzas
|
check_required_stanzas
|
||||||
@ -48,6 +49,9 @@ module Cask
|
|||||||
check_latest_with_auto_updates
|
check_latest_with_auto_updates
|
||||||
check_stanza_requires_uninstall
|
check_stanza_requires_uninstall
|
||||||
check_appcast_contains_version
|
check_appcast_contains_version
|
||||||
|
check_github_repository
|
||||||
|
check_gitlab_repository
|
||||||
|
check_bitbucket_repository
|
||||||
self
|
self
|
||||||
rescue => e
|
rescue => e
|
||||||
odebug "#{e.message}\n#{e.backtrace.join("\n")}"
|
odebug "#{e.message}\n#{e.backtrace.join("\n")}"
|
||||||
@ -255,7 +259,7 @@ module Cask
|
|||||||
bad_url_format?(/sourceforge/,
|
bad_url_format?(/sourceforge/,
|
||||||
[
|
[
|
||||||
%r{\Ahttps://sourceforge\.net/projects/[^/]+/files/latest/download\Z},
|
%r{\Ahttps://sourceforge\.net/projects/[^/]+/files/latest/download\Z},
|
||||||
%r{\Ahttps://downloads\.sourceforge\.net/(?!(project|sourceforge)\/)},
|
%r{\Ahttps://downloads\.sourceforge\.net/(?!(project|sourceforge)/)},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -272,7 +276,7 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_token_conflicts
|
def check_token_conflicts
|
||||||
return unless check_token_conflicts?
|
return unless @token_conflicts
|
||||||
return unless core_formula_names.include?(cask.token)
|
return unless core_formula_names.include?(cask.token)
|
||||||
|
|
||||||
add_warning "possible duplicate, cask token conflicts with Homebrew core formula: #{core_formula_url}"
|
add_warning "possible duplicate, cask token conflicts with Homebrew core formula: #{core_formula_url}"
|
||||||
@ -301,7 +305,7 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_appcast_contains_version
|
def check_appcast_contains_version
|
||||||
return unless check_appcast?
|
return unless appcast?
|
||||||
return if cask.appcast.to_s.empty?
|
return if cask.appcast.to_s.empty?
|
||||||
return if cask.appcast.must_contain == :no_check
|
return if cask.appcast.must_contain == :no_check
|
||||||
|
|
||||||
@ -309,8 +313,8 @@ module Cask
|
|||||||
appcast_contents, = curl_output("--compressed", "--user-agent", HOMEBREW_USER_AGENT_FAKE_SAFARI, "--location",
|
appcast_contents, = curl_output("--compressed", "--user-agent", HOMEBREW_USER_AGENT_FAKE_SAFARI, "--location",
|
||||||
"--globoff", "--max-time", "5", appcast_stanza)
|
"--globoff", "--max-time", "5", appcast_stanza)
|
||||||
version_stanza = cask.version.to_s
|
version_stanza = cask.version.to_s
|
||||||
adjusted_version_stanza = if cask.appcast.must_contain.blank?
|
adjusted_version_stanza = if cask.appcast.configuration.blank?
|
||||||
version_stanza.split(",")[0].split("-")[0].split("_")[0]
|
version_stanza.match(/^[[:alnum:].]+/)[0]
|
||||||
else
|
else
|
||||||
cask.appcast.must_contain
|
cask.appcast.must_contain
|
||||||
end
|
end
|
||||||
@ -322,6 +326,50 @@ module Cask
|
|||||||
add_error "appcast at URL '#{appcast_stanza}' offline or looping"
|
add_error "appcast at URL '#{appcast_stanza}' offline or looping"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_github_repository
|
||||||
|
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*})
|
||||||
|
return if user.nil?
|
||||||
|
|
||||||
|
odebug "Auditing GitHub repo"
|
||||||
|
|
||||||
|
error = SharedAudits.github(user, repo)
|
||||||
|
add_error error if error
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_gitlab_repository
|
||||||
|
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*})
|
||||||
|
return if user.nil?
|
||||||
|
|
||||||
|
odebug "Auditing GitLab repo"
|
||||||
|
|
||||||
|
error = SharedAudits.gitlab(user, repo)
|
||||||
|
add_error error if error
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_bitbucket_repository
|
||||||
|
user, repo = get_repo_data(%r{https?://bitbucket\.org/([^/]+)/([^/]+)/?.*})
|
||||||
|
return if user.nil?
|
||||||
|
|
||||||
|
odebug "Auditing Bitbucket repo"
|
||||||
|
|
||||||
|
error = SharedAudits.bitbucket(user, repo)
|
||||||
|
add_error error if error
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_repo_data(regex)
|
||||||
|
return unless @online
|
||||||
|
return unless @new_cask
|
||||||
|
|
||||||
|
_, user, repo = *regex.match(cask.url.to_s)
|
||||||
|
_, user, repo = *regex.match(cask.homepage) unless user
|
||||||
|
_, user, repo = *regex.match(cask.appcast.to_s) unless user
|
||||||
|
return if !user || !repo
|
||||||
|
|
||||||
|
repo.gsub!(/.git$/, "")
|
||||||
|
|
||||||
|
[user, repo]
|
||||||
|
end
|
||||||
|
|
||||||
def check_blacklist
|
def check_blacklist
|
||||||
return if cask.tap&.user != "Homebrew"
|
return if cask.tap&.user != "Homebrew"
|
||||||
return unless reason = Blacklist.blacklisted_reason(cask.token)
|
return unless reason = Blacklist.blacklisted_reason(cask.token)
|
||||||
|
|||||||
@ -8,37 +8,40 @@ module Cask
|
|||||||
extend Predicable
|
extend Predicable
|
||||||
|
|
||||||
def self.audit(cask, audit_download: false, audit_appcast: false,
|
def self.audit(cask, audit_download: false, audit_appcast: false,
|
||||||
check_token_conflicts: false, quarantine: true, commit_range: nil)
|
audit_online: false, audit_strict: false,
|
||||||
|
audit_token_conflicts: false, audit_new_cask: false,
|
||||||
|
quarantine: true, commit_range: nil)
|
||||||
new(cask, audit_download: audit_download,
|
new(cask, audit_download: audit_download,
|
||||||
audit_appcast: audit_appcast,
|
audit_appcast: audit_appcast,
|
||||||
check_token_conflicts: check_token_conflicts,
|
audit_online: audit_online,
|
||||||
|
audit_new_cask: audit_new_cask,
|
||||||
|
audit_strict: audit_strict,
|
||||||
|
audit_token_conflicts: audit_token_conflicts,
|
||||||
quarantine: quarantine, commit_range: commit_range).audit
|
quarantine: quarantine, commit_range: commit_range).audit
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :cask, :commit_range
|
attr_reader :cask, :commit_range
|
||||||
|
|
||||||
def initialize(cask, audit_download: false, audit_appcast: false,
|
def initialize(cask, audit_download: false, audit_appcast: false,
|
||||||
check_token_conflicts: false, quarantine: true, commit_range: nil)
|
audit_online: false, audit_strict: false,
|
||||||
|
audit_token_conflicts: false, audit_new_cask: false,
|
||||||
|
quarantine: true, commit_range: nil)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
@audit_download = audit_download
|
@audit_download = audit_download
|
||||||
@audit_appcast = audit_appcast
|
@audit_appcast = audit_appcast
|
||||||
|
@audit_online = audit_online
|
||||||
|
@audit_strict = audit_strict
|
||||||
|
@audit_new_cask = audit_new_cask
|
||||||
@quarantine = quarantine
|
@quarantine = quarantine
|
||||||
@commit_range = commit_range
|
@commit_range = commit_range
|
||||||
@check_token_conflicts = check_token_conflicts
|
@audit_token_conflicts = audit_token_conflicts
|
||||||
end
|
end
|
||||||
|
|
||||||
def audit_download?
|
attr_predicate :audit_appcast?, :audit_download?, :audit_online?,
|
||||||
@audit_download
|
:audit_strict?, :audit_new_cask?, :audit_token_conflicts?, :quarantine?
|
||||||
end
|
|
||||||
|
|
||||||
attr_predicate :audit_appcast?, :quarantine?
|
|
||||||
|
|
||||||
def check_token_conflicts?
|
|
||||||
@check_token_conflicts
|
|
||||||
end
|
|
||||||
|
|
||||||
def audit
|
def audit
|
||||||
if !ARGV.value("language") && language_blocks
|
if !Homebrew.args.value("language") && language_blocks
|
||||||
audit_all_languages
|
audit_all_languages
|
||||||
else
|
else
|
||||||
audit_cask_instance(cask)
|
audit_cask_instance(cask)
|
||||||
@ -64,9 +67,12 @@ module Cask
|
|||||||
|
|
||||||
def audit_cask_instance(cask)
|
def audit_cask_instance(cask)
|
||||||
download = audit_download? && Download.new(cask, quarantine: quarantine?)
|
download = audit_download? && Download.new(cask, quarantine: quarantine?)
|
||||||
audit = Audit.new(cask, check_appcast: audit_appcast?,
|
audit = Audit.new(cask, appcast: audit_appcast?,
|
||||||
|
online: audit_online?,
|
||||||
|
strict: audit_strict?,
|
||||||
|
new_cask: audit_new_cask?,
|
||||||
|
token_conflicts: audit_token_conflicts?,
|
||||||
download: download,
|
download: download,
|
||||||
check_token_conflicts: check_token_conflicts?,
|
|
||||||
commit_range: commit_range)
|
commit_range: commit_range)
|
||||||
audit.run!
|
audit.run!
|
||||||
puts audit.summary
|
puts audit.summary
|
||||||
|
|||||||
@ -4,7 +4,7 @@ module Cask
|
|||||||
module Blacklist
|
module Blacklist
|
||||||
def self.blacklisted_reason(name)
|
def self.blacklisted_reason(name)
|
||||||
case name
|
case name
|
||||||
when /^adobe\-(after|illustrator|indesign|photoshop|premiere)/
|
when /^adobe-(after|illustrator|indesign|photoshop|premiere)/
|
||||||
"Adobe casks were removed because they are too difficult to maintain."
|
"Adobe casks were removed because they are too difficult to maintain."
|
||||||
when /^audacity$/
|
when /^audacity$/
|
||||||
"Audacity was removed because it is too difficult to download programmatically."
|
"Audacity was removed because it is too difficult to download programmatically."
|
||||||
|
|||||||
@ -145,13 +145,13 @@ module Cask
|
|||||||
command, args = detect_internal_command(*args) || detect_external_command(*args) || [NullCommand.new, args]
|
command, args = detect_internal_command(*args) || detect_external_command(*args) || [NullCommand.new, args]
|
||||||
|
|
||||||
if help?
|
if help?
|
||||||
puts command.help
|
Help.new(command.command_name).run
|
||||||
else
|
else
|
||||||
command.run(*args)
|
command.run(*args)
|
||||||
end
|
end
|
||||||
rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e
|
rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e
|
||||||
onoe e.message
|
onoe e.message
|
||||||
$stderr.puts e.backtrace if ARGV.debug?
|
$stderr.puts e.backtrace if Homebrew.args.debug?
|
||||||
exit 1
|
exit 1
|
||||||
rescue StandardError, ScriptError, NoMemoryError => e
|
rescue StandardError, ScriptError, NoMemoryError => e
|
||||||
onoe e.message
|
onoe e.message
|
||||||
@ -180,7 +180,7 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
def process_options(*args)
|
def process_options(*args)
|
||||||
exclude_regex = /^\-\-#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
|
exclude_regex = /^--#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
|
||||||
|
|
||||||
non_options = []
|
non_options = []
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +1,66 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "cli/parser"
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
class Cmd
|
class Cmd
|
||||||
class Audit < AbstractCommand
|
class Audit < AbstractCommand
|
||||||
option "--download", :download, false
|
option "--download", :download_arg, false
|
||||||
option "--appcast", :appcast, false
|
option "--appcast", :appcast_arg, false
|
||||||
option "--token-conflicts", :token_conflicts, false
|
option "--token-conflicts", :token_conflicts_arg, false
|
||||||
|
option "--strict", :strict_arg, false
|
||||||
|
option "--online", :online_arg, false
|
||||||
|
option "--new-cask", :new_cask_arg, false
|
||||||
|
|
||||||
|
def self.usage
|
||||||
|
<<~EOS
|
||||||
|
`cask audit` [<options>] [<cask>]
|
||||||
|
|
||||||
|
--strict - Run additional, stricter style checks.
|
||||||
|
--online - Run additional, slower style checks that require a network connection.
|
||||||
|
--new-cask - Run various additional style checks to determine if a new cask is eligible
|
||||||
|
for Homebrew. This should be used when creating new casks and implies
|
||||||
|
`--strict` and `--online`.
|
||||||
|
--download - Audit the downloaded file
|
||||||
|
--appcast - Audit the appcast
|
||||||
|
--token-conflicts - Audit for token conflicts
|
||||||
|
|
||||||
|
Check <cask> for Homebrew coding style violations. This should be run before
|
||||||
|
submitting a new cask. If no <casks> are provided, check all locally
|
||||||
|
available casks. Will exit with a non-zero status if any errors are
|
||||||
|
found, which can be useful for implementing pre-commit hooks.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
def self.help
|
def self.help
|
||||||
"verifies installability of Casks"
|
"verifies installability of Casks"
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
Homebrew.auditing = true
|
||||||
|
strict = new_cask_arg? || strict_arg?
|
||||||
|
token_conflicts = strict || token_conflicts_arg?
|
||||||
|
|
||||||
|
online = new_cask_arg? || online_arg?
|
||||||
|
download = online || download_arg?
|
||||||
|
appcast = online || appcast_arg?
|
||||||
|
|
||||||
failed_casks = casks(alternative: -> { Cask.to_a })
|
failed_casks = casks(alternative: -> { Cask.to_a })
|
||||||
.reject { |cask| audit(cask) }
|
.reject do |cask|
|
||||||
|
odebug "Auditing Cask #{cask}"
|
||||||
|
Auditor.audit(cask, audit_download: download,
|
||||||
|
audit_appcast: appcast,
|
||||||
|
audit_online: online,
|
||||||
|
audit_strict: strict,
|
||||||
|
audit_new_cask: new_cask_arg?,
|
||||||
|
audit_token_conflicts: token_conflicts,
|
||||||
|
quarantine: quarantine?)
|
||||||
|
end
|
||||||
|
|
||||||
return if failed_casks.empty?
|
return if failed_casks.empty?
|
||||||
|
|
||||||
raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
|
raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def audit(cask)
|
|
||||||
odebug "Auditing Cask #{cask}"
|
|
||||||
Auditor.audit(cask, audit_download: download?,
|
|
||||||
audit_appcast: appcast?,
|
|
||||||
check_token_conflicts: token_conflicts?,
|
|
||||||
quarantine: quarantine?)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,17 +3,26 @@
|
|||||||
module Cask
|
module Cask
|
||||||
class Cmd
|
class Cmd
|
||||||
class Help < AbstractCommand
|
class Help < AbstractCommand
|
||||||
def initialize(*)
|
|
||||||
super
|
|
||||||
return if args.empty?
|
|
||||||
|
|
||||||
raise ArgumentError, "#{self.class.command_name} does not take arguments."
|
|
||||||
end
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
if args.empty?
|
||||||
puts self.class.purpose
|
puts self.class.purpose
|
||||||
puts
|
puts
|
||||||
puts self.class.usage
|
puts self.class.usage
|
||||||
|
elsif args.count == 1
|
||||||
|
command_name = args.first
|
||||||
|
|
||||||
|
unless command = self.class.commands[command_name]
|
||||||
|
raise "No help information found for command '#{command_name}'."
|
||||||
|
end
|
||||||
|
|
||||||
|
if command.respond_to?(:usage)
|
||||||
|
puts command.usage
|
||||||
|
else
|
||||||
|
puts command.help
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise ArgumentError, "#{self.class.command_name} only takes up to one argument."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.purpose
|
def self.purpose
|
||||||
@ -23,6 +32,10 @@ module Cask
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.commands
|
||||||
|
Cmd.command_classes.select(&:visible?).map { |klass| [klass.command_name, klass] }.to_h
|
||||||
|
end
|
||||||
|
|
||||||
def self.usage
|
def self.usage
|
||||||
max_command_len = Cmd.commands.map(&:length).max
|
max_command_len = Cmd.commands.map(&:length).max
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,7 @@ module Cask
|
|||||||
|
|
||||||
def self.info(cask)
|
def self.info(cask)
|
||||||
puts get_info(cask)
|
puts get_info(cask)
|
||||||
|
::Utils::Analytics.cask_output(cask)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.title_info(cask)
|
def self.title_info(cask)
|
||||||
|
|||||||
@ -46,7 +46,7 @@ module Cask
|
|||||||
next if self.class.options.nil?
|
next if self.class.options.nil?
|
||||||
|
|
||||||
self.class.options.each do |option_name, option_method|
|
self.class.options.each do |option_name, option_method|
|
||||||
option_type = case option_name.split(/(\ |\=)/).last
|
option_type = case option_name.split(/(\ |=)/).last
|
||||||
when "PATH"
|
when "PATH"
|
||||||
Pathname
|
Pathname
|
||||||
when /\w+(,\w+)+/
|
when /\w+(,\w+)+/
|
||||||
|
|||||||
@ -86,7 +86,7 @@ module Cask
|
|||||||
Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
|
Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
|
||||||
.select { |arg| arg.include?("=") }
|
.select { |arg| arg.include?("=") }
|
||||||
.map { |arg| arg.split("=", 2) }
|
.map { |arg| arg.split("=", 2) }
|
||||||
.map { |(flag, value)| [flag.sub(/^\-\-/, ""), value] },
|
.map { |(flag, value)| [flag.sub(/^--/, ""), value] },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,19 @@ module Cask
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
caveat :unsigned_accessibility do |access = "Accessibility"|
|
||||||
|
# access: the category in System Preferences -> Security & Privacy -> Privacy the app requires.
|
||||||
|
|
||||||
|
<<~EOS
|
||||||
|
#{@cask} is not signed and requires Accessibility access,
|
||||||
|
so you will need to re-grant Accessibility access every time the app is updated.
|
||||||
|
|
||||||
|
Enable or re-enable it in:
|
||||||
|
System Preferences → Security & Privacy → Privacy -> #{access}
|
||||||
|
To re-enable untick and retick #{@cask}.app.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
caveat :path_environment_variable do |path|
|
caveat :path_environment_variable do |path|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
To use #{@cask}, you may need to add the #{path} directory
|
To use #{@cask}, you may need to add the #{path} directory
|
||||||
|
|||||||
@ -11,9 +11,9 @@ module Cask
|
|||||||
|
|
||||||
DIVIDER_REGEX = /(#{DIVIDERS.keys.map { |v| Regexp.quote(v) }.join('|')})/.freeze
|
DIVIDER_REGEX = /(#{DIVIDERS.keys.map { |v| Regexp.quote(v) }.join('|')})/.freeze
|
||||||
|
|
||||||
MAJOR_MINOR_PATCH_REGEX = /^([^.,:]+)(?:\.([^.,:]+)(?:\.([^.,:]+))?)?/.freeze
|
MAJOR_MINOR_PATCH_REGEX = /^([^.,:]+)(?:.([^.,:]+)(?:.([^.,:]+))?)?/.freeze
|
||||||
|
|
||||||
INVALID_CHARACTERS = /[^0-9a-zA-Z\.\,\:\-\_]/.freeze
|
INVALID_CHARACTERS = /[^0-9a-zA-Z.,:\-_]/.freeze
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
private
|
private
|
||||||
@ -75,7 +75,7 @@ module Cask
|
|||||||
s = downcase.delete(".").gsub(/[^a-z\d]+/, "-")
|
s = downcase.delete(".").gsub(/[^a-z\d]+/, "-")
|
||||||
|
|
||||||
return true if s.match?(/(\d+|\b)(alpha|beta|preview|rc|dev|canary|snapshot)(\d+|\b)/i)
|
return true if s.match?(/(\d+|\b)(alpha|beta|preview|rc|dev|canary|snapshot)(\d+|\b)/i)
|
||||||
return true if s.match?(/\A[a-z\d]+(\-\d+)*\-?(a|b|pre)(\d+|\b)/i)
|
return true if s.match?(/\A[a-z\d]+(-\d+)*-?(a|b|pre)(\d+|\b)/i)
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -368,8 +368,8 @@ module Cask
|
|||||||
fi.installed_on_request = false
|
fi.installed_on_request = false
|
||||||
fi.show_header = true
|
fi.show_header = true
|
||||||
fi.verbose = verbose?
|
fi.verbose = verbose?
|
||||||
fi.fetch
|
|
||||||
fi.prelude
|
fi.prelude
|
||||||
|
fi.fetch
|
||||||
fi.install
|
fi.install
|
||||||
fi.finish
|
fi.finish
|
||||||
end
|
end
|
||||||
|
|||||||
@ -109,7 +109,7 @@ class Cleaner
|
|||||||
else
|
else
|
||||||
0444
|
0444
|
||||||
end
|
end
|
||||||
if ARGV.debug?
|
if Homebrew.args.debug?
|
||||||
old_perms = path.stat.mode & 0777
|
old_perms = path.stat.mode & 0777
|
||||||
odebug "Fixing #{path} permissions from #{old_perms.to_s(8)} to #{perms.to_s(8)}" if perms != old_perms
|
odebug "Fixing #{path} permissions from #{old_perms.to_s(8)} to #{perms.to_s(8)}" if perms != old_perms
|
||||||
end
|
end
|
||||||
|
|||||||
@ -56,14 +56,14 @@ module CleanupRefinement
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
version ||= basename.to_s[/\A.*(?:\-\-.*?)*\-\-(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
version ||= basename.to_s[/\A.*(?:--.*?)*--(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
||||||
version ||= basename.to_s[/\A.*\-\-?(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
version ||= basename.to_s[/\A.*--?(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
||||||
|
|
||||||
return false unless version
|
return false unless version
|
||||||
|
|
||||||
version = Version.new(version)
|
version = Version.new(version)
|
||||||
|
|
||||||
return false unless formula_name = basename.to_s[/\A(.*?)(?:\-\-.*?)*\-\-?(?:#{Regexp.escape(version)})/, 1]
|
return false unless formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1]
|
||||||
|
|
||||||
formula = begin
|
formula = begin
|
||||||
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
|
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
|
||||||
@ -71,7 +71,7 @@ module CleanupRefinement
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
resource_name = basename.to_s[/\A.*?\-\-(.*?)\-\-?(?:#{Regexp.escape(version)})/, 1]
|
resource_name = basename.to_s[/\A.*?--(.*?)--?(?:#{Regexp.escape(version)})/, 1]
|
||||||
|
|
||||||
if resource_name == "patch"
|
if resource_name == "patch"
|
||||||
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
|
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
|
||||||
@ -84,7 +84,7 @@ module CleanupRefinement
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return true if scrub && !formula.installed?
|
return true if scrub && !formula.latest_version_installed?
|
||||||
|
|
||||||
return true if Utils::Bottles.file_outdated?(formula, self)
|
return true if Utils::Bottles.file_outdated?(formula, self)
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ module CleanupRefinement
|
|||||||
end
|
end
|
||||||
|
|
||||||
def stale_cask?(scrub)
|
def stale_cask?(scrub)
|
||||||
return false unless name = basename.to_s[/\A(.*?)\-\-/, 1]
|
return false unless name = basename.to_s[/\A(.*?)--/, 1]
|
||||||
|
|
||||||
cask = begin
|
cask = begin
|
||||||
Cask::CaskLoader.load(name)
|
Cask::CaskLoader.load(name)
|
||||||
@ -100,7 +100,7 @@ module CleanupRefinement
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}\-\-#{Regexp.escape(cask.version)}\b/)
|
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
|
||||||
|
|
||||||
return true if scrub && !cask.versions.include?(cask.version)
|
return true if scrub && !cask.versions.include?(cask.version)
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ module Homebrew
|
|||||||
# undefine tap to allow --tap argument
|
# undefine tap to allow --tap argument
|
||||||
undef tap
|
undef tap
|
||||||
|
|
||||||
def initialize(argv = ARGV.dup.freeze, set_default_args: false)
|
def initialize(argv = ARGV.freeze, set_default_args: false)
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@processed_options = []
|
@processed_options = []
|
||||||
@ -84,11 +84,7 @@ module Homebrew
|
|||||||
require "formula"
|
require "formula"
|
||||||
|
|
||||||
@formulae ||= (downcased_unique_named - casks).map do |name|
|
@formulae ||= (downcased_unique_named - casks).map do |name|
|
||||||
if name.include?("/") || File.exist?(name)
|
|
||||||
Formulary.factory(name, spec)
|
Formulary.factory(name, spec)
|
||||||
else
|
|
||||||
Formulary.find_with_priority(name, spec)
|
|
||||||
end
|
|
||||||
end.uniq(&:name).freeze
|
end.uniq(&:name).freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -175,6 +171,20 @@ module Homebrew
|
|||||||
formulae.any? { |args_f| args_f.full_name == f.full_name }
|
formulae.any? { |args_f| args_f.full_name == f.full_name }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def include_formula_test_deps?(f)
|
||||||
|
return false unless include_test?
|
||||||
|
|
||||||
|
formulae.any? { |args_f| args_f.full_name == f.full_name }
|
||||||
|
end
|
||||||
|
|
||||||
|
def value(name)
|
||||||
|
arg_prefix = "--#{name}="
|
||||||
|
flag_with_value = flags_only.find { |arg| arg.start_with?(arg_prefix) }
|
||||||
|
return unless flag_with_value
|
||||||
|
|
||||||
|
flag_with_value.delete_prefix(arg_prefix)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def option_to_name(option)
|
def option_to_name(option)
|
||||||
|
|||||||
@ -13,7 +13,7 @@ module Homebrew
|
|||||||
class Parser
|
class Parser
|
||||||
attr_reader :processed_options, :hide_from_man_page
|
attr_reader :processed_options, :hide_from_man_page
|
||||||
|
|
||||||
def self.parse(argv = ARGV.dup.freeze, allow_no_named_args: false, &block)
|
def self.parse(argv = ARGV.freeze, allow_no_named_args: false, &block)
|
||||||
new(argv, &block).parse(allow_no_named_args: allow_no_named_args)
|
new(argv, &block).parse(allow_no_named_args: allow_no_named_args)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ module Homebrew
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(argv = ARGV.dup.freeze, &block)
|
def initialize(argv = ARGV.freeze, &block)
|
||||||
@parser = OptionParser.new
|
@parser = OptionParser.new
|
||||||
@argv = argv
|
@argv = argv
|
||||||
@args = Homebrew::CLI::Args.new(@argv)
|
@args = Homebrew::CLI::Args.new(@argv)
|
||||||
@ -359,11 +359,7 @@ module Homebrew
|
|||||||
named_args.map do |arg|
|
named_args.map do |arg|
|
||||||
next if arg.match?(HOMEBREW_CASK_TAP_CASK_REGEX)
|
next if arg.match?(HOMEBREW_CASK_TAP_CASK_REGEX)
|
||||||
|
|
||||||
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
|
|
||||||
Formulary.factory(arg, spec)
|
Formulary.factory(arg, spec)
|
||||||
else
|
|
||||||
Formulary.find_with_priority(arg.downcase, spec)
|
|
||||||
end
|
|
||||||
end.compact.uniq(&:name)
|
end.compact.uniq(&:name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -36,7 +36,6 @@ module Homebrew
|
|||||||
shell = if args.plain?
|
shell = if args.plain?
|
||||||
nil
|
nil
|
||||||
elsif args.shell.nil?
|
elsif args.shell.nil?
|
||||||
# legacy behavior
|
|
||||||
:bash unless $stdout.tty?
|
:bash unless $stdout.tty?
|
||||||
elsif args.shell == "auto"
|
elsif args.shell == "auto"
|
||||||
Utils::Shell.parent || Utils::Shell.preferred
|
Utils::Shell.parent || Utils::Shell.preferred
|
||||||
|
|||||||
@ -105,11 +105,7 @@ module Homebrew
|
|||||||
args.named.each_with_index do |f, i|
|
args.named.each_with_index do |f, i|
|
||||||
puts unless i.zero?
|
puts unless i.zero?
|
||||||
begin
|
begin
|
||||||
formula = if f.include?("/") || File.exist?(f)
|
formula = Formulary.factory(f)
|
||||||
Formulary.factory(f)
|
|
||||||
else
|
|
||||||
Formulary.find_with_priority(f)
|
|
||||||
end
|
|
||||||
if args.analytics?
|
if args.analytics?
|
||||||
Utils::Analytics.formula_output(formula)
|
Utils::Analytics.formula_output(formula)
|
||||||
else
|
else
|
||||||
|
|||||||
@ -325,8 +325,8 @@ module Homebrew
|
|||||||
fi.build_bottle = args.build_bottle?
|
fi.build_bottle = args.build_bottle?
|
||||||
fi.interactive = args.interactive?
|
fi.interactive = args.interactive?
|
||||||
fi.git = args.git?
|
fi.git = args.git?
|
||||||
fi.fetch
|
|
||||||
fi.prelude
|
fi.prelude
|
||||||
|
fi.fetch
|
||||||
fi.install
|
fi.install
|
||||||
fi.finish
|
fi.finish
|
||||||
rescue FormulaInstallationAlreadyAttemptedError
|
rescue FormulaInstallationAlreadyAttemptedError
|
||||||
|
|||||||
@ -20,8 +20,8 @@ homebrew-shellenv() {
|
|||||||
echo "setenv HOMEBREW_CELLAR $HOMEBREW_CELLAR;"
|
echo "setenv HOMEBREW_CELLAR $HOMEBREW_CELLAR;"
|
||||||
echo "setenv HOMEBREW_REPOSITORY $HOMEBREW_REPOSITORY;"
|
echo "setenv HOMEBREW_REPOSITORY $HOMEBREW_REPOSITORY;"
|
||||||
echo "setenv PATH $HOMEBREW_PREFIX/bin:$HOMEBREW_PREFIX/sbin:\$PATH;"
|
echo "setenv PATH $HOMEBREW_PREFIX/bin:$HOMEBREW_PREFIX/sbin:\$PATH;"
|
||||||
echo "setenv MANPATH $HOMEBREW_PREFIX/share/man:\$MANPATH;"
|
echo "setenv MANPATH $HOMEBREW_PREFIX/share/man\`[ \${?MANPATH} == 1 ] && echo \":\${MANPATH}\"\`:;"
|
||||||
echo "setenv INFOPATH $HOMEBREW_PREFIX/share/info:\$INFOPATH;"
|
echo "setenv INFOPATH $HOMEBREW_PREFIX/share/info\`[ \${?INFOPATH} == 1 ] && echo \":\${INFOPATH}\"\`;"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "export HOMEBREW_PREFIX=\"$HOMEBREW_PREFIX\";"
|
echo "export HOMEBREW_PREFIX=\"$HOMEBREW_PREFIX\";"
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "cli/parser"
|
|
||||||
|
|
||||||
module Homebrew
|
|
||||||
module_function
|
|
||||||
|
|
||||||
def tap_pin_args
|
|
||||||
Homebrew::CLI::Parser.new do
|
|
||||||
hide_from_man_page!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def tap_pin
|
|
||||||
odisabled "the brew tap-pin command",
|
|
||||||
"fully-scoped user/tap/formula naming when installing and in dependency references"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "cli/parser"
|
|
||||||
|
|
||||||
module Homebrew
|
|
||||||
module_function
|
|
||||||
|
|
||||||
def tap_unpin_args
|
|
||||||
Homebrew::CLI::Parser.new do
|
|
||||||
hide_from_man_page!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def tap_unpin
|
|
||||||
odisabled "the brew tap-unpin command",
|
|
||||||
"fully-scoped user/tap/formula naming when installing and in dependency references"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -599,7 +599,6 @@ EOS
|
|||||||
-d "$HOMEBREW_LIBRARY/LinkedKegs" ||
|
-d "$HOMEBREW_LIBRARY/LinkedKegs" ||
|
||||||
(-n "$HOMEBREW_DEVELOPER" && -z "$HOMEBREW_UPDATE_PREINSTALL") ]]
|
(-n "$HOMEBREW_DEVELOPER" && -z "$HOMEBREW_UPDATE_PREINSTALL") ]]
|
||||||
then
|
then
|
||||||
unset HOMEBREW_RUBY_PATH
|
|
||||||
brew update-report "$@"
|
brew update-report "$@"
|
||||||
return $?
|
return $?
|
||||||
elif [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]]
|
elif [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]]
|
||||||
|
|||||||
@ -191,8 +191,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
oh1 "Upgrading #{Formatter.identifier(f.full_specified_name)} #{upgrade_version} #{fi.options.to_a.join(" ")}"
|
oh1 "Upgrading #{Formatter.identifier(f.full_specified_name)} #{upgrade_version} #{fi.options.to_a.join(" ")}"
|
||||||
|
|
||||||
fi.fetch
|
|
||||||
fi.prelude
|
fi.prelude
|
||||||
|
fi.fetch
|
||||||
|
|
||||||
# first we unlink the currently active keg for this formula otherwise it is
|
# first we unlink the currently active keg for this formula otherwise it is
|
||||||
# possible for the existing build to interfere with the build we are about to
|
# possible for the existing build to interfere with the build we are about to
|
||||||
@ -216,7 +216,7 @@ module Homebrew
|
|||||||
ensure
|
ensure
|
||||||
# restore previous installation state if build failed
|
# restore previous installation state if build failed
|
||||||
begin
|
begin
|
||||||
linked_kegs.each(&:link) unless f.installed?
|
linked_kegs.each(&:link) unless f.latest_version_installed?
|
||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|||||||
@ -101,7 +101,7 @@ module Commands
|
|||||||
end
|
end
|
||||||
|
|
||||||
def official_external_commands_paths
|
def official_external_commands_paths
|
||||||
%w[bundle services].map do |cmd|
|
%w[bundle services test-bot].map do |cmd|
|
||||||
tap = Tap.fetch("Homebrew/#{cmd}")
|
tap = Tap.fetch("Homebrew/#{cmd}")
|
||||||
tap.install unless tap.installed?
|
tap.install unless tap.installed?
|
||||||
external_ruby_v2_cmd_path(cmd)
|
external_ruby_v2_cmd_path(cmd)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "compat/cask/dsl/version"
|
require "compat/extend/nil"
|
||||||
require "compat/language/python"
|
require "compat/extend/string"
|
||||||
require "compat/requirements/macos_requirement"
|
|
||||||
require "compat/formula"
|
require "compat/formula"
|
||||||
|
require "compat/language/python"
|
||||||
require "compat/os/mac" if OS.mac?
|
require "compat/os/mac" if OS.mac?
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Cask
|
|
||||||
class DSL
|
|
||||||
class Version < ::String
|
|
||||||
module Compat
|
|
||||||
def dots_to_slashes
|
|
||||||
odisabled "#dots_to_slashes"
|
|
||||||
end
|
|
||||||
|
|
||||||
def hyphens_to_slashes
|
|
||||||
odisabled "#hyphens_to_slashes"
|
|
||||||
end
|
|
||||||
|
|
||||||
def underscores_to_slashes
|
|
||||||
odisabled "#underscores_to_slashes"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
prepend Compat
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
11
Library/Homebrew/compat/extend/nil.rb
Normal file
11
Library/Homebrew/compat/extend/nil.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class NilClass
|
||||||
|
module Compat
|
||||||
|
def chuzzle
|
||||||
|
odeprecated "chuzzle", "chomp.presence"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
prepend Compat
|
||||||
|
end
|
||||||
15
Library/Homebrew/compat/extend/string.rb
Normal file
15
Library/Homebrew/compat/extend/string.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class String
|
||||||
|
module Compat
|
||||||
|
# String.chomp, but if result is empty: returns nil instead.
|
||||||
|
# Allows `chuzzle || foo` short-circuits.
|
||||||
|
def chuzzle
|
||||||
|
odeprecated "chuzzle", "chomp.presence"
|
||||||
|
s = chomp
|
||||||
|
s unless s.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
prepend Compat
|
||||||
|
end
|
||||||
@ -3,10 +3,19 @@
|
|||||||
class Formula
|
class Formula
|
||||||
module Compat
|
module Compat
|
||||||
def installed?
|
def installed?
|
||||||
# odeprecated "Formula#installed?",
|
odeprecated "Formula#installed?",
|
||||||
# "Formula#latest_version_installed? (or Formula#any_version_installed? )"
|
"Formula#latest_version_installed? (or Formula#any_version_installed? )"
|
||||||
latest_version_installed?
|
latest_version_installed?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def prepare_patches
|
||||||
|
if respond_to?(:patches)
|
||||||
|
active_spec.add_legacy_patches(patches)
|
||||||
|
odeprecated "patches", "patch do"
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
prepend Compat
|
prepend Compat
|
||||||
|
|||||||
@ -5,7 +5,7 @@ module Language
|
|||||||
module Cabal
|
module Cabal
|
||||||
module Compat
|
module Compat
|
||||||
def cabal_sandbox(options = {})
|
def cabal_sandbox(options = {})
|
||||||
# odeprecated "Language::Haskell::Cabal.cabal_sandbox"
|
odeprecated "Language::Haskell::Cabal.cabal_sandbox"
|
||||||
|
|
||||||
pwd = Pathname.pwd
|
pwd = Pathname.pwd
|
||||||
home = options[:home] || pwd
|
home = options[:home] || pwd
|
||||||
@ -41,14 +41,14 @@ module Language
|
|||||||
end
|
end
|
||||||
|
|
||||||
def cabal_sandbox_add_source(*args)
|
def cabal_sandbox_add_source(*args)
|
||||||
# odeprecated "Language::Haskell::Cabal.cabal_sandbox_add_source"
|
odeprecated "Language::Haskell::Cabal.cabal_sandbox_add_source"
|
||||||
|
|
||||||
system "cabal", "v1-sandbox", "add-source", *args
|
system "cabal", "v1-sandbox", "add-source", *args
|
||||||
end
|
end
|
||||||
|
|
||||||
def cabal_install(*args)
|
def cabal_install(*args)
|
||||||
# odeprecated "Language::Haskell::Cabal.cabal_install",
|
odeprecated "Language::Haskell::Cabal.cabal_install",
|
||||||
# "cabal v2-install directly with std_cabal_v2_args"
|
"cabal v2-install directly with std_cabal_v2_args"
|
||||||
|
|
||||||
# cabal hardcodes 64 as the maximum number of parallel jobs
|
# cabal hardcodes 64 as the maximum number of parallel jobs
|
||||||
# https://github.com/Homebrew/legacy-homebrew/issues/49509
|
# https://github.com/Homebrew/legacy-homebrew/issues/49509
|
||||||
@ -64,13 +64,13 @@ module Language
|
|||||||
end
|
end
|
||||||
|
|
||||||
def cabal_configure(flags)
|
def cabal_configure(flags)
|
||||||
# odeprecated "Language::Haskell::Cabal.cabal_configure"
|
odeprecated "Language::Haskell::Cabal.cabal_configure"
|
||||||
|
|
||||||
system "cabal", "v1-configure", flags
|
system "cabal", "v1-configure", flags
|
||||||
end
|
end
|
||||||
|
|
||||||
def cabal_install_tools(*tools)
|
def cabal_install_tools(*tools)
|
||||||
# odeprecated "Language::Haskell::Cabal.cabal_install_tools"
|
odeprecated "Language::Haskell::Cabal.cabal_install_tools"
|
||||||
|
|
||||||
# install tools sequentially, as some tools can depend on other tools
|
# install tools sequentially, as some tools can depend on other tools
|
||||||
tools.each { |tool| cabal_install tool }
|
tools.each { |tool| cabal_install tool }
|
||||||
@ -81,8 +81,8 @@ module Language
|
|||||||
end
|
end
|
||||||
|
|
||||||
def install_cabal_package(*args, **options)
|
def install_cabal_package(*args, **options)
|
||||||
# odeprecated "Language::Haskell::Cabal.install_cabal_package",
|
odeprecated "Language::Haskell::Cabal.install_cabal_package",
|
||||||
# "cabal v2-update directly followed by v2-install with std_cabal_v2_args"
|
"cabal v2-update directly followed by v2-install with std_cabal_v2_args"
|
||||||
|
|
||||||
cabal_sandbox do
|
cabal_sandbox do
|
||||||
cabal_install_tools(*options[:using]) if options[:using]
|
cabal_install_tools(*options[:using]) if options[:using]
|
||||||
|
|||||||
@ -5,6 +5,8 @@ module Language
|
|||||||
class << self
|
class << self
|
||||||
module Compat
|
module Compat
|
||||||
def rewrite_python_shebang(python_path)
|
def rewrite_python_shebang(python_path)
|
||||||
|
odeprecated "Language::Python.rewrite_python_shebang",
|
||||||
|
"Utils::Shebang.rewrite_shebang and Shebang.python_shebang_rewrite_info(python_path)"
|
||||||
Pathname.pwd.find do |f|
|
Pathname.pwd.find do |f|
|
||||||
Utils::Shebang.rewrite_shebang(Shebang.python_shebang_rewrite_info(python_path), f)
|
Utils::Shebang.rewrite_shebang(Shebang.python_shebang_rewrite_info(python_path), f)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -5,7 +5,7 @@ module OS
|
|||||||
class << self
|
class << self
|
||||||
module Compat
|
module Compat
|
||||||
def preferred_arch
|
def preferred_arch
|
||||||
# odeprecated "MacOS.preferred_arch", "Hardware::CPU.arch (or ideally let the compiler handle it)"
|
odeprecated "MacOS.preferred_arch", "Hardware::CPU.arch (or ideally let the compiler handle it)"
|
||||||
if Hardware::CPU.is_64_bit?
|
if Hardware::CPU.is_64_bit?
|
||||||
Hardware::CPU.arch_64_bit
|
Hardware::CPU.arch_64_bit
|
||||||
else
|
else
|
||||||
@ -14,12 +14,12 @@ module OS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tcc_db
|
def tcc_db
|
||||||
# odeprecated "MacOS.tcc_db"
|
odeprecated "MacOS.tcc_db"
|
||||||
@tcc_db ||= Pathname.new("/Library/Application Support/com.apple.TCC/TCC.db")
|
@tcc_db ||= Pathname.new("/Library/Application Support/com.apple.TCC/TCC.db")
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre_mavericks_accessibility_dotfile
|
def pre_mavericks_accessibility_dotfile
|
||||||
# odeprecated "MacOS.pre_mavericks_accessibility_dotfile"
|
odeprecated "MacOS.pre_mavericks_accessibility_dotfile"
|
||||||
@pre_mavericks_accessibility_dotfile ||= Pathname.new("/private/var/db/.AccessibilityAPIEnabled")
|
@pre_mavericks_accessibility_dotfile ||= Pathname.new("/private/var/db/.AccessibilityAPIEnabled")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class MacOSRequirement < Requirement
|
|
||||||
module Compat
|
|
||||||
def initialize(tags = [], comparator: ">=")
|
|
||||||
if tags.first.respond_to?(:map)
|
|
||||||
versions, *rest = tags
|
|
||||||
|
|
||||||
versions = versions.map do |v|
|
|
||||||
next v if v.is_a?(Symbol)
|
|
||||||
|
|
||||||
sym = MacOS::Version.new(v).to_sym
|
|
||||||
|
|
||||||
odisabled "depends_on macos: #{v.inspect}",
|
|
||||||
"depends_on macos: #{sym.inspect}"
|
|
||||||
sym
|
|
||||||
end
|
|
||||||
|
|
||||||
tags = [versions, *rest]
|
|
||||||
elsif !tags.empty? && !tags.first.is_a?(Symbol)
|
|
||||||
v, *rest = tags
|
|
||||||
sym = MacOS::Version.new(v).to_sym
|
|
||||||
|
|
||||||
odisabled "depends_on macos: #{v.inspect}",
|
|
||||||
"depends_on macos: #{sym.inspect}"
|
|
||||||
|
|
||||||
tags = [sym, *rest]
|
|
||||||
end
|
|
||||||
|
|
||||||
super(tags, comparator: comparator)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
prepend Compat
|
|
||||||
end
|
|
||||||
@ -100,16 +100,11 @@ module Homebrew
|
|||||||
klass.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
|
klass.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
|
||||||
elsif dep.optional?
|
elsif dep.optional?
|
||||||
klass.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
|
klass.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
|
||||||
elsif dep.test?
|
elsif dep.build? || dep.test?
|
||||||
if includes.include?("test?")
|
keep = false
|
||||||
Dependency.keep_but_prune_recursive_deps if type == :dependencies
|
keep ||= dep.test? && includes.include?("test?") && dependent == formula
|
||||||
elsif dep.build?
|
keep ||= dep.build? && includes.include?("build?")
|
||||||
klass.prune unless includes.include?("build?")
|
klass.prune unless keep
|
||||||
else
|
|
||||||
klass.prune
|
|
||||||
end
|
|
||||||
elsif dep.build?
|
|
||||||
klass.prune unless includes.include?("build?")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# If a tap isn't installed, we can't find the dependencies of one of
|
# If a tap isn't installed, we can't find the dependencies of one of
|
||||||
|
|||||||
@ -89,9 +89,6 @@ class Dependency
|
|||||||
deps.each do |dep|
|
deps.each do |dep|
|
||||||
next if dependent.name == dep.name
|
next if dependent.name == dep.name
|
||||||
|
|
||||||
# we only care about one level of test dependencies.
|
|
||||||
next if dep.test? && @expand_stack.length > 1
|
|
||||||
|
|
||||||
case action(dependent, dep, &block)
|
case action(dependent, dep, &block)
|
||||||
when :prune
|
when :prune
|
||||||
next
|
next
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
require "formula"
|
require "formula"
|
||||||
require "formula_versions"
|
require "formula_versions"
|
||||||
require "utils/curl"
|
require "utils/curl"
|
||||||
|
require "utils/notability"
|
||||||
require "extend/ENV"
|
require "extend/ENV"
|
||||||
require "formula_cellar_checks"
|
require "formula_cellar_checks"
|
||||||
require "cmd/search"
|
require "cmd/search"
|
||||||
@ -134,19 +135,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
created_pr_comment = false
|
|
||||||
if new_formula && !new_formula_problem_lines.empty?
|
|
||||||
begin
|
|
||||||
created_pr_comment = true if GitHub.create_issue_comment(new_formula_problem_lines.join("\n"))
|
|
||||||
rescue *GitHub.api_errors => e
|
|
||||||
opoo "Unable to create issue comment: #{e.message}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
unless created_pr_comment
|
|
||||||
new_formula_problem_count += new_formula_problem_lines.size
|
new_formula_problem_count += new_formula_problem_lines.size
|
||||||
puts new_formula_problem_lines.map { |s| " #{s}" }
|
puts new_formula_problem_lines.map { |s| " #{s}" }
|
||||||
end
|
|
||||||
|
|
||||||
total_problems_count = problem_count + new_formula_problem_count
|
total_problems_count = problem_count + new_formula_problem_count
|
||||||
problem_plural = "#{total_problems_count} #{"problem".pluralize(total_problems_count)}"
|
problem_plural = "#{total_problems_count} #{"problem".pluralize(total_problems_count)}"
|
||||||
@ -155,10 +145,7 @@ module Homebrew
|
|||||||
errors_summary = "#{problem_plural} in #{formula_plural} detected"
|
errors_summary = "#{problem_plural} in #{formula_plural} detected"
|
||||||
errors_summary += ", #{corrected_problem_plural} corrected" if corrected_problem_count.positive?
|
errors_summary += ", #{corrected_problem_plural} corrected" if corrected_problem_count.positive?
|
||||||
|
|
||||||
if problem_count.positive? ||
|
ofail errors_summary if problem_count.positive? || new_formula_problem_count.positive?
|
||||||
(new_formula_problem_count.positive? && !created_pr_comment)
|
|
||||||
ofail errors_summary
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_problem_lines(problems)
|
def format_problem_lines(problems)
|
||||||
@ -458,9 +445,10 @@ module Homebrew
|
|||||||
autoconf@2.13
|
autoconf@2.13
|
||||||
bash-completion@2
|
bash-completion@2
|
||||||
gnupg@1.4
|
gnupg@1.4
|
||||||
|
libsigc++@2
|
||||||
lua@5.1
|
lua@5.1
|
||||||
numpy@1.16
|
numpy@1.16
|
||||||
libsigc++@2
|
python@3.8
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
def audit_versioned_keg_only
|
def audit_versioned_keg_only
|
||||||
@ -524,79 +512,30 @@ module Homebrew
|
|||||||
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*})
|
user, repo = get_repo_data(%r{https?://github\.com/([^/]+)/([^/]+)/?.*})
|
||||||
return if user.nil?
|
return if user.nil?
|
||||||
|
|
||||||
begin
|
warning = SharedAudits.github(user, repo)
|
||||||
metadata = GitHub.repository(user, repo)
|
return if warning.nil?
|
||||||
rescue GitHub::HTTPNotFoundError
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
return if metadata.nil?
|
new_formula_problem warning
|
||||||
|
|
||||||
new_formula_problem "GitHub fork (not canonical repository)" if metadata["fork"]
|
|
||||||
if (metadata["forks_count"] < 30) && (metadata["subscribers_count"] < 30) &&
|
|
||||||
(metadata["stargazers_count"] < 75)
|
|
||||||
new_formula_problem "GitHub repository not notable enough (<30 forks, <30 watchers and <75 stars)"
|
|
||||||
end
|
|
||||||
|
|
||||||
return if Date.parse(metadata["created_at"]) <= (Date.today - 30)
|
|
||||||
|
|
||||||
new_formula_problem "GitHub repository too new (<30 days old)"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def audit_gitlab_repository
|
def audit_gitlab_repository
|
||||||
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*})
|
user, repo = get_repo_data(%r{https?://gitlab\.com/([^/]+)/([^/]+)/?.*})
|
||||||
return if user.nil?
|
return if user.nil?
|
||||||
|
|
||||||
out, _, status= curl_output("--request", "GET", "https://gitlab.com/api/v4/projects/#{user}%2F#{repo}")
|
warning = SharedAudits.gitlab(user, repo)
|
||||||
return unless status.success?
|
return if warning.nil?
|
||||||
|
|
||||||
metadata = JSON.parse(out)
|
new_formula_problem warning
|
||||||
return if metadata.nil?
|
|
||||||
|
|
||||||
new_formula_problem "GitLab fork (not canonical repository)" if metadata["fork"]
|
|
||||||
if (metadata["forks_count"] < 30) && (metadata["star_count"] < 75)
|
|
||||||
new_formula_problem "GitLab repository not notable enough (<30 forks and <75 stars)"
|
|
||||||
end
|
|
||||||
|
|
||||||
return if Date.parse(metadata["created_at"]) <= (Date.today - 30)
|
|
||||||
|
|
||||||
new_formula_problem "GitLab repository too new (<30 days old)"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def audit_bitbucket_repository
|
def audit_bitbucket_repository
|
||||||
user, repo = get_repo_data(%r{https?://bitbucket\.org/([^/]+)/([^/]+)/?.*})
|
user, repo = get_repo_data(%r{https?://bitbucket\.org/([^/]+)/([^/]+)/?.*})
|
||||||
return if user.nil?
|
return if user.nil?
|
||||||
|
|
||||||
api_url = "https://api.bitbucket.org/2.0/repositories/#{user}/#{repo}"
|
warning = SharedAudits.bitbucket(user, repo)
|
||||||
out, _, status= curl_output("--request", "GET", api_url)
|
return if warning.nil?
|
||||||
return unless status.success?
|
|
||||||
|
|
||||||
metadata = JSON.parse(out)
|
new_formula_problem warning
|
||||||
return if metadata.nil?
|
|
||||||
|
|
||||||
new_formula_problem "Uses deprecated mercurial support in Bitbucket" if metadata["scm"] == "hg"
|
|
||||||
|
|
||||||
new_formula_problem "Bitbucket fork (not canonical repository)" unless metadata["parent"].nil?
|
|
||||||
|
|
||||||
if Date.parse(metadata["created_on"]) >= (Date.today - 30)
|
|
||||||
new_formula_problem "Bitbucket repository too new (<30 days old)"
|
|
||||||
end
|
|
||||||
|
|
||||||
forks_out, _, forks_status= curl_output("--request", "GET", "#{api_url}/forks")
|
|
||||||
return unless forks_status.success?
|
|
||||||
|
|
||||||
watcher_out, _, watcher_status= curl_output("--request", "GET", "#{api_url}/watchers")
|
|
||||||
return unless watcher_status.success?
|
|
||||||
|
|
||||||
forks_metadata = JSON.parse(forks_out)
|
|
||||||
return if forks_metadata.nil?
|
|
||||||
|
|
||||||
watcher_metadata = JSON.parse(watcher_out)
|
|
||||||
return if watcher_metadata.nil?
|
|
||||||
|
|
||||||
return if (forks_metadata["size"] < 30) && (watcher_metadata["size"] < 75)
|
|
||||||
|
|
||||||
new_formula_problem "Bitbucket repository not notable enough (<30 forks and <75 watchers)"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_repo_data(regex)
|
def get_repo_data(regex)
|
||||||
@ -608,7 +547,7 @@ module Homebrew
|
|||||||
_, user, repo = *regex.match(formula.homepage) unless user
|
_, user, repo = *regex.match(formula.homepage) unless user
|
||||||
return if !user || !repo
|
return if !user || !repo
|
||||||
|
|
||||||
repo.gsub!(/.git$/, "")
|
repo.delete_suffix!(".git")
|
||||||
|
|
||||||
[user, repo]
|
[user, repo]
|
||||||
end
|
end
|
||||||
@ -730,7 +669,7 @@ module Homebrew
|
|||||||
.map(&:to_i)
|
.map(&:to_i)
|
||||||
|
|
||||||
case (url = stable.url)
|
case (url = stable.url)
|
||||||
when /[\d\._-](alpha|beta|rc\d)/
|
when /[\d._-](alpha|beta|rc\d)/
|
||||||
matched = Regexp.last_match(1)
|
matched = Regexp.last_match(1)
|
||||||
version_prefix = stable_version_string.sub(/\d+$/, "")
|
version_prefix = stable_version_string.sub(/\d+$/, "")
|
||||||
return if UNSTABLE_WHITELIST[formula.name] == version_prefix
|
return if UNSTABLE_WHITELIST[formula.name] == version_prefix
|
||||||
@ -758,7 +697,7 @@ module Homebrew
|
|||||||
.second
|
.second
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (release = GitHub.open_api("#{GitHub::API_URL}/repos/#{owner}/#{repo}/releases/tags/#{tag}"))
|
if @online && (release = GitHub.open_api("#{GitHub::API_URL}/repos/#{owner}/#{repo}/releases/tags/#{tag}"))
|
||||||
problem "#{tag} is a GitHub prerelease" if release["prerelease"]
|
problem "#{tag} is a GitHub prerelease" if release["prerelease"]
|
||||||
problem "#{tag} is a GitHub draft" if release["draft"]
|
problem "#{tag} is a GitHub draft" if release["draft"]
|
||||||
end
|
end
|
||||||
@ -864,7 +803,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
bin_names.each do |name|
|
bin_names.each do |name|
|
||||||
["system", "shell_output", "pipe_output"].each do |cmd|
|
["system", "shell_output", "pipe_output"].each do |cmd|
|
||||||
if text.to_s.match?(/test do.*#{cmd}[\(\s]+['"]#{Regexp.escape(name)}[\s'"]/m)
|
if text.to_s.match?(/test do.*#{cmd}[(\s]+['"]#{Regexp.escape(name)}[\s'"]/m)
|
||||||
problem %Q(fully scope test #{cmd} calls, e.g. #{cmd} "\#{bin}/#{name}")
|
problem %Q(fully scope test #{cmd} calls, e.g. #{cmd} "\#{bin}/#{name}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -984,7 +923,7 @@ module Homebrew
|
|||||||
except_audits = @except
|
except_audits = @except
|
||||||
|
|
||||||
methods.map(&:to_s).grep(/^audit_/).each do |audit_method_name|
|
methods.map(&:to_s).grep(/^audit_/).each do |audit_method_name|
|
||||||
name = audit_method_name.gsub(/^audit_/, "")
|
name = audit_method_name.delete_prefix("audit_")
|
||||||
if only_audits
|
if only_audits
|
||||||
next unless only_audits.include?(name)
|
next unless only_audits.include?(name)
|
||||||
elsif except_audits
|
elsif except_audits
|
||||||
@ -1052,15 +991,9 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def audit_download_strategy
|
def audit_download_strategy
|
||||||
if url =~ %r{^(cvs|bzr|hg|fossil)://} || url =~ %r{^(svn)\+http://}
|
|
||||||
# TODO: check could be in RuboCop
|
|
||||||
problem "Use of the #{$&} scheme is deprecated, pass `:using => :#{Regexp.last_match(1)}` instead"
|
|
||||||
end
|
|
||||||
|
|
||||||
url_strategy = DownloadStrategyDetector.detect(url)
|
url_strategy = DownloadStrategyDetector.detect(url)
|
||||||
|
|
||||||
if using == :git || url_strategy == GitDownloadStrategy
|
if using == :git || url_strategy == GitDownloadStrategy
|
||||||
# TODO: check could be in RuboCop
|
|
||||||
problem "Git should specify :revision when a :tag is specified." if specs[:tag] && !specs[:revision]
|
problem "Git should specify :revision when a :tag is specified." if specs[:tag] && !specs[:revision]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -321,7 +321,7 @@ module Homebrew
|
|||||||
if any_go_deps
|
if any_go_deps
|
||||||
go_regex =
|
go_regex =
|
||||||
Version.formula_optionally_versioned_regex(:go, full: false)
|
Version.formula_optionally_versioned_regex(:go, full: false)
|
||||||
ignores << %r{#{Regexp.escape(HOMEBREW_CELLAR)}/#{go_regex}/[\d\.]+/libexec}
|
ignores << %r{#{Regexp.escape(HOMEBREW_CELLAR)}/#{go_regex}/[\d.]+/libexec}
|
||||||
end
|
end
|
||||||
|
|
||||||
relocatable = true
|
relocatable = true
|
||||||
|
|||||||
@ -79,7 +79,7 @@ module Homebrew
|
|||||||
origin_branch = "#{homebrew_core_remote}/#{homebrew_core_branch}"
|
origin_branch = "#{homebrew_core_remote}/#{homebrew_core_branch}"
|
||||||
previous_branch = Utils.popen_read("git -C \"#{formula.tap.path}\" symbolic-ref -q --short HEAD").chomp
|
previous_branch = Utils.popen_read("git -C \"#{formula.tap.path}\" symbolic-ref -q --short HEAD").chomp
|
||||||
previous_branch = "master" if previous_branch.empty?
|
previous_branch = "master" if previous_branch.empty?
|
||||||
formula_path = formula.path.to_s[%r{(Formula\/.*)}, 1]
|
formula_path = formula.path.to_s[%r{(Formula/.*)}, 1]
|
||||||
|
|
||||||
if args.dry_run?
|
if args.dry_run?
|
||||||
ohai "git remote add #{homebrew_core_remote} #{homebrew_core_url}"
|
ohai "git remote add #{homebrew_core_remote} #{homebrew_core_url}"
|
||||||
@ -89,7 +89,7 @@ module Homebrew
|
|||||||
return tap_full_name, origin_branch, previous_branch
|
return tap_full_name, origin_branch, previous_branch
|
||||||
else
|
else
|
||||||
formula.path.parent.cd do
|
formula.path.parent.cd do
|
||||||
unless Utils.popen_read("git remote -v").match?(%r{^homebrew.*Homebrew\/homebrew-core.*$})
|
unless Utils.popen_read("git remote -v").match?(%r{^homebrew.*Homebrew/homebrew-core.*$})
|
||||||
ohai "Adding #{homebrew_core_remote} remote"
|
ohai "Adding #{homebrew_core_remote} remote"
|
||||||
safe_system "git", "remote", "add", homebrew_core_remote, homebrew_core_url
|
safe_system "git", "remote", "add", homebrew_core_remote, homebrew_core_url
|
||||||
end
|
end
|
||||||
@ -118,12 +118,6 @@ module Homebrew
|
|||||||
|
|
||||||
formula = args.formulae.first
|
formula = args.formulae.first
|
||||||
|
|
||||||
if formula
|
|
||||||
tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
|
|
||||||
check_for_duplicate_pull_requests(formula, tap_full_name)
|
|
||||||
checked_for_duplicates = true
|
|
||||||
end
|
|
||||||
|
|
||||||
new_url = args.url
|
new_url = args.url
|
||||||
if new_url && !formula
|
if new_url && !formula
|
||||||
# Split the new URL on / and find any formulae that have the same URL
|
# Split the new URL on / and find any formulae that have the same URL
|
||||||
@ -152,7 +146,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
raise FormulaUnspecifiedError unless formula
|
raise FormulaUnspecifiedError unless formula
|
||||||
|
|
||||||
check_for_duplicate_pull_requests(formula, tap_full_name) unless checked_for_duplicates
|
tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
|
||||||
|
check_for_duplicate_pull_requests(formula, tap_full_name)
|
||||||
|
|
||||||
requested_spec, formula_spec = if args.devel?
|
requested_spec, formula_spec = if args.devel?
|
||||||
devel_message = " (devel)"
|
devel_message = " (devel)"
|
||||||
@ -230,7 +225,7 @@ module Homebrew
|
|||||||
|
|
||||||
replacement_pairs += formula_spec.mirrors.map do |mirror|
|
replacement_pairs += formula_spec.mirrors.map do |mirror|
|
||||||
[
|
[
|
||||||
/ +mirror \"#{Regexp.escape(mirror)}\"\n/m,
|
/ +mirror "#{Regexp.escape(mirror)}"\n/m,
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@ -263,7 +258,7 @@ module Homebrew
|
|||||||
|
|
||||||
if new_mirrors
|
if new_mirrors
|
||||||
replacement_pairs << [
|
replacement_pairs << [
|
||||||
/^( +)(url \"#{Regexp.escape(new_url)}\"\n)/m,
|
/^( +)(url "#{Regexp.escape(new_url)}"\n)/m,
|
||||||
"\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n",
|
"\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@ -288,30 +283,30 @@ module Homebrew
|
|||||||
]
|
]
|
||||||
elsif new_mirrors
|
elsif new_mirrors
|
||||||
[
|
[
|
||||||
/^( +)(mirror \"#{Regexp.escape(new_mirrors.last)}\"\n)/m,
|
/^( +)(mirror "#{Regexp.escape(new_mirrors.last)}"\n)/m,
|
||||||
"\\1\\2\\1version \"#{forced_version}\"\n",
|
"\\1\\2\\1version \"#{forced_version}\"\n",
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
[
|
[
|
||||||
/^( +)(url \"#{Regexp.escape(new_url)}\"\n)/m,
|
/^( +)(url "#{Regexp.escape(new_url)}"\n)/m,
|
||||||
"\\1\\2\\1version \"#{forced_version}\"\n",
|
"\\1\\2\\1version \"#{forced_version}\"\n",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
elsif requested_spec == :devel
|
elsif requested_spec == :devel
|
||||||
replacement_pairs << [
|
replacement_pairs << [
|
||||||
/( devel do.+?version \")#{old_formula_version}(\"\n.+?end\n)/m,
|
/( devel do.+?version ")#{old_formula_version}("\n.+?end\n)/m,
|
||||||
"\\1#{forced_version}\\2",
|
"\\1#{forced_version}\\2",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
elsif forced_version && forced_version == "0"
|
elsif forced_version && forced_version == "0"
|
||||||
if requested_spec == :stable
|
if requested_spec == :stable
|
||||||
replacement_pairs << [
|
replacement_pairs << [
|
||||||
/^ version \"[\w\.\-\+]+\"\n/m,
|
/^ version "[\w.\-+]+"\n/m,
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
elsif requested_spec == :devel
|
elsif requested_spec == :devel
|
||||||
replacement_pairs << [
|
replacement_pairs << [
|
||||||
/( devel do.+?)^ +version \"[^\n]+\"\n(.+?end\n)/m,
|
/( devel do.+?)^ +version "[^\n]+"\n(.+?end\n)/m,
|
||||||
"\\1\\2",
|
"\\1\\2",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|||||||
@ -19,7 +19,7 @@ module Homebrew
|
|||||||
|
|
||||||
def irb_args
|
def irb_args
|
||||||
# work around IRB modifying ARGV.
|
# work around IRB modifying ARGV.
|
||||||
Homebrew::CLI::Parser.new(ARGV.dup) do
|
Homebrew::CLI::Parser.new(ARGV.dup.freeze) do
|
||||||
usage_banner <<~EOS
|
usage_banner <<~EOS
|
||||||
`irb` [<options>]
|
`irb` [<options>]
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ module Homebrew
|
|||||||
|
|
||||||
if args.examples?
|
if args.examples?
|
||||||
puts "'v8'.f # => instance of the v8 formula"
|
puts "'v8'.f # => instance of the v8 formula"
|
||||||
puts ":hub.f.installed?"
|
puts ":hub.f.latest_version_installed?"
|
||||||
puts ":lua.f.methods - 1.methods"
|
puts ":lua.f.methods - 1.methods"
|
||||||
puts ":mpd.f.recursive_dependencies.reject(&:installed?)"
|
puts ":mpd.f.recursive_dependencies.reject(&:installed?)"
|
||||||
return
|
return
|
||||||
|
|||||||
@ -60,7 +60,7 @@ module Homebrew
|
|||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
if gnupg.installed?
|
if gnupg.any_version_installed?
|
||||||
path = PATH.new(ENV.fetch("PATH"))
|
path = PATH.new(ENV.fetch("PATH"))
|
||||||
path.prepend(gnupg.installed_prefix/"bin")
|
path.prepend(gnupg.installed_prefix/"bin")
|
||||||
ENV["PATH"] = path
|
ENV["PATH"] = path
|
||||||
|
|||||||
@ -15,6 +15,7 @@ module Homebrew
|
|||||||
|
|
||||||
def pull_args
|
def pull_args
|
||||||
Homebrew::CLI::Parser.new do
|
Homebrew::CLI::Parser.new do
|
||||||
|
hide_from_man_page!
|
||||||
usage_banner <<~EOS
|
usage_banner <<~EOS
|
||||||
`pull` [<options>] <patch>
|
`pull` [<options>] <patch>
|
||||||
|
|
||||||
@ -43,6 +44,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pull
|
def pull
|
||||||
|
odeprecated "brew pull", "hub checkout"
|
||||||
|
|
||||||
odie "You meant `git pull --rebase`." if ARGV[0] == "--rebase"
|
odie "You meant `git pull --rebase`." if ARGV[0] == "--rebase"
|
||||||
|
|
||||||
pull_args.parse
|
pull_args.parse
|
||||||
@ -56,7 +59,7 @@ module Homebrew
|
|||||||
gnupg = Formula["gnupg"]
|
gnupg = Formula["gnupg"]
|
||||||
rescue FormulaUnavailableError # rubocop:disable Lint/SuppressedException
|
rescue FormulaUnavailableError # rubocop:disable Lint/SuppressedException
|
||||||
else
|
else
|
||||||
if gnupg.installed?
|
if gnupg.any_version_installed?
|
||||||
path = PATH.new(ENV.fetch("PATH"))
|
path = PATH.new(ENV.fetch("PATH"))
|
||||||
path.prepend(gnupg.installed_prefix/"bin")
|
path.prepend(gnupg.installed_prefix/"bin")
|
||||||
ENV["PATH"] = path
|
ENV["PATH"] = path
|
||||||
@ -333,7 +336,7 @@ module Homebrew
|
|||||||
|
|
||||||
def check_bintray_mirror(name, url)
|
def check_bintray_mirror(name, url)
|
||||||
headers, = curl_output("--connect-timeout", "15", "--location", "--head", url)
|
headers, = curl_output("--connect-timeout", "15", "--location", "--head", url)
|
||||||
status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first
|
status_code = headers.scan(%r{^HTTP/.* (\d+)}).last.first
|
||||||
return if status_code.start_with?("2")
|
return if status_code.start_with?("2")
|
||||||
|
|
||||||
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."
|
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."
|
||||||
|
|||||||
@ -38,12 +38,6 @@ module Homebrew
|
|||||||
|
|
||||||
Or `brew tap #{tap}` and then `brew install <formula>`.
|
Or `brew tap #{tap}` and then `brew install <formula>`.
|
||||||
|
|
||||||
Or install via URL (which will not receive updates):
|
|
||||||
|
|
||||||
```
|
|
||||||
brew install https://raw.githubusercontent.com/#{tap.user}/homebrew-#{tap.repo}/master/Formula/<formula>.rb
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
||||||
MARKDOWN
|
MARKDOWN
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
require "keg"
|
require "keg"
|
||||||
require "language/python"
|
require "language/python"
|
||||||
require "formula"
|
require "formula"
|
||||||
|
require "formulary"
|
||||||
require "version"
|
require "version"
|
||||||
require "development_tools"
|
require "development_tools"
|
||||||
require "utils/shell"
|
require "utils/shell"
|
||||||
@ -832,6 +833,23 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_deleted_formula
|
||||||
|
kegs = Keg.all
|
||||||
|
deleted_formulae = []
|
||||||
|
kegs.each do |keg|
|
||||||
|
keg_name = keg.name
|
||||||
|
deleted_formulae << keg_name if Formulary.tap_paths(keg_name).blank?
|
||||||
|
end
|
||||||
|
return if deleted_formulae.blank?
|
||||||
|
|
||||||
|
message = <<~EOS
|
||||||
|
Some installed formulae were deleted!
|
||||||
|
You should find replacements for the following formulae:
|
||||||
|
#{deleted_formulae.join("\n ")}
|
||||||
|
EOS
|
||||||
|
message
|
||||||
|
end
|
||||||
|
|
||||||
def all
|
def all
|
||||||
methods.map(&:to_s).grep(/^check_/)
|
methods.map(&:to_s).grep(/^check_/)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -221,7 +221,7 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def basename
|
def basename
|
||||||
cached_location.basename.sub(/^[\da-f]{64}\-\-/, "")
|
cached_location.basename.sub(/^[\da-f]{64}--/, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -390,7 +390,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
|
|||||||
filenames = lines.map(&parse_content_disposition).compact
|
filenames = lines.map(&parse_content_disposition).compact
|
||||||
|
|
||||||
time =
|
time =
|
||||||
lines.map { |line| line[/^Last\-Modified:\s*(.+)/i, 1] }
|
lines.map { |line| line[/^Last-Modified:\s*(.+)/i, 1] }
|
||||||
.compact
|
.compact
|
||||||
.map { |t| t.match?(/^\d+$/) ? Time.at(t.to_i) : Time.parse(t) }
|
.map { |t| t.match?(/^\d+$/) ? Time.at(t.to_i) : Time.parse(t) }
|
||||||
.last
|
.last
|
||||||
@ -820,7 +820,7 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
|
|||||||
|
|
||||||
return unless status.success?
|
return unless status.success?
|
||||||
|
|
||||||
commit = output[/^ETag: \"(\h+)\"/, 1]
|
commit = output[/^ETag: "(\h+)"/, 1]
|
||||||
version.update_commit(commit) if commit
|
version.update_commit(commit) if commit
|
||||||
commit
|
commit
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,63 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module HomebrewArgvExtension
|
|
||||||
def value(name)
|
|
||||||
arg_prefix = "--#{name}="
|
|
||||||
flag_with_value = find { |arg| arg.start_with?(arg_prefix) }
|
|
||||||
flag_with_value&.delete_prefix(arg_prefix)
|
|
||||||
end
|
|
||||||
|
|
||||||
def debug?
|
|
||||||
flag?("--debug") || !ENV["HOMEBREW_DEBUG"].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def cc
|
|
||||||
value "cc"
|
|
||||||
end
|
|
||||||
|
|
||||||
def env
|
|
||||||
value "env"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def options_only
|
|
||||||
select { |arg| arg.start_with?("-") }
|
|
||||||
end
|
|
||||||
|
|
||||||
def flag?(flag)
|
|
||||||
options_only.include?(flag) || switch?(flag[2, 1])
|
|
||||||
end
|
|
||||||
|
|
||||||
# e.g. `foo -ns -i --bar` has three switches: `n`, `s` and `i`
|
|
||||||
def switch?(char)
|
|
||||||
return false if char.length > 1
|
|
||||||
|
|
||||||
options_only.any? { |arg| arg.scan("-").size == 1 && arg.include?(char) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec(default = :stable)
|
|
||||||
if include?("--HEAD")
|
|
||||||
:head
|
|
||||||
elsif include?("--devel")
|
|
||||||
:devel
|
|
||||||
else
|
|
||||||
default
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def named
|
|
||||||
self - options_only
|
|
||||||
end
|
|
||||||
|
|
||||||
def downcased_unique_named
|
|
||||||
# Only lowercase names, not paths, bottle filenames or URLs
|
|
||||||
named.map do |arg|
|
|
||||||
if arg.include?("/") || arg.end_with?(".tar.gz") || File.exist?(arg)
|
|
||||||
arg
|
|
||||||
else
|
|
||||||
arg.downcase
|
|
||||||
end
|
|
||||||
end.uniq
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -6,7 +6,7 @@ require "extend/ENV/std"
|
|||||||
require "extend/ENV/super"
|
require "extend/ENV/super"
|
||||||
|
|
||||||
def superenv?
|
def superenv?
|
||||||
ARGV.env != "std" && Superenv.bin
|
Homebrew.args.env != "std" && Superenv.bin
|
||||||
end
|
end
|
||||||
|
|
||||||
module EnvActivation
|
module EnvActivation
|
||||||
|
|||||||
@ -162,7 +162,7 @@ module SharedEnvExtension
|
|||||||
# ENV.append_to_cflags "-I ./missing/includes"
|
# ENV.append_to_cflags "-I ./missing/includes"
|
||||||
# end</pre>
|
# end</pre>
|
||||||
def compiler
|
def compiler
|
||||||
@compiler ||= if (cc = ARGV.cc)
|
@compiler ||= if (cc = Homebrew.args.cc)
|
||||||
warn_about_non_apple_gcc($&) if cc =~ GNU_GCC_REGEXP
|
warn_about_non_apple_gcc($&) if cc =~ GNU_GCC_REGEXP
|
||||||
fetch_compiler(cc, "--cc")
|
fetch_compiler(cc, "--cc")
|
||||||
elsif (cc = homebrew_cc)
|
elsif (cc = homebrew_cc)
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class Keg
|
|||||||
return if !file.elf? || !file.dynamic_elf?
|
return if !file.elf? || !file.dynamic_elf?
|
||||||
|
|
||||||
patchelf = DevelopmentTools.locate "patchelf"
|
patchelf = DevelopmentTools.locate "patchelf"
|
||||||
|
odie "Could not locate patchelf, please: brew install patchelf." if patchelf.nil?
|
||||||
|
|
||||||
cmd_rpath = [patchelf, "--print-rpath", file]
|
cmd_rpath = [patchelf, "--print-rpath", file]
|
||||||
old_rpath = Utils.popen_read(*cmd_rpath, err: :out).strip
|
old_rpath = Utils.popen_read(*cmd_rpath, err: :out).strip
|
||||||
|
|
||||||
|
|||||||
@ -347,12 +347,13 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_deprecated_caskroom_taps
|
def check_deprecated_caskroom_taps
|
||||||
tapped_caskroom_taps = Tap.select { |t| t.user == "caskroom" }.map(&:repo)
|
tapped_caskroom_taps = Tap.select { |t| t.user == "caskroom" || t.name == "phinze/cask" }
|
||||||
|
.map(&:name)
|
||||||
return if tapped_caskroom_taps.empty?
|
return if tapped_caskroom_taps.empty?
|
||||||
|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
You have the following deprecated, cask taps tapped:
|
You have the following deprecated, cask taps tapped:
|
||||||
Caskroom/homebrew-#{tapped_caskroom_taps.join("\n Caskroom/homebrew-")}
|
#{tapped_caskroom_taps.join("\n ")}
|
||||||
Untap them with `brew untap`.
|
Untap them with `brew untap`.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|||||||
@ -81,7 +81,7 @@ module Stdenv
|
|||||||
prepend "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
prepend "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
||||||
|
|
||||||
sdk = formula ? MacOS.sdk_for_formula(formula, version) : MacOS.sdk(version)
|
sdk = formula ? MacOS.sdk_for_formula(formula, version) : MacOS.sdk(version)
|
||||||
return if !MacOS.sdk_root_needed? && sdk.source != :xcode
|
return if !MacOS.sdk_root_needed? && sdk&.source != :xcode
|
||||||
|
|
||||||
sdk = sdk.path
|
sdk = sdk.path
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ module Superenv
|
|||||||
# @private
|
# @private
|
||||||
def setup_build_environment(formula = nil)
|
def setup_build_environment(formula = nil)
|
||||||
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
|
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
|
||||||
if MacOS.sdk_root_needed? || sdk.source == :xcode
|
if MacOS.sdk_root_needed? || sdk&.source == :xcode
|
||||||
self["HOMEBREW_SDKROOT"] = sdk.path
|
self["HOMEBREW_SDKROOT"] = sdk.path
|
||||||
self["HOMEBREW_DEVELOPER_DIR"] = if sdk.source == :xcode
|
self["HOMEBREW_DEVELOPER_DIR"] = if sdk.source == :xcode
|
||||||
MacOS::Xcode.prefix
|
MacOS::Xcode.prefix
|
||||||
|
|||||||
@ -106,10 +106,12 @@ class Keg
|
|||||||
bad_name.sub(PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
bad_name.sub(PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
||||||
elsif bad_name.start_with? CELLAR_PLACEHOLDER
|
elsif bad_name.start_with? CELLAR_PLACEHOLDER
|
||||||
bad_name.sub(CELLAR_PLACEHOLDER, HOMEBREW_CELLAR)
|
bad_name.sub(CELLAR_PLACEHOLDER, HOMEBREW_CELLAR)
|
||||||
elsif (file.dylib? || file.mach_o_bundle?) && (file.parent + bad_name).exist?
|
elsif (file.dylib? || file.mach_o_bundle?) && (file.dirname/bad_name).exist?
|
||||||
"@loader_path/#{bad_name}"
|
"@loader_path/#{bad_name}"
|
||||||
elsif file.mach_o_executable? && (lib + bad_name).exist?
|
elsif file.mach_o_executable? && (lib/bad_name).exist?
|
||||||
"#{lib}/#{bad_name}"
|
"#{lib}/#{bad_name}"
|
||||||
|
elsif file.mach_o_executable? && (libexec/"lib"/bad_name).exist?
|
||||||
|
"#{libexec}/lib/#{bad_name}"
|
||||||
elsif bad_name.start_with?("@rpath") && ENV["HOMEBREW_RELOCATE_METAVARS"]
|
elsif bad_name.start_with?("@rpath") && ENV["HOMEBREW_RELOCATE_METAVARS"]
|
||||||
expand_rpath file, bad_name
|
expand_rpath file, bad_name
|
||||||
elsif (abs_name = find_dylib(bad_name)) && abs_name.exist?
|
elsif (abs_name = find_dylib(bad_name)) && abs_name.exist?
|
||||||
|
|||||||
@ -224,7 +224,7 @@ class Pathname
|
|||||||
return archive_ext if archive_ext
|
return archive_ext if archive_ext
|
||||||
|
|
||||||
# Don't treat version numbers as extname.
|
# Don't treat version numbers as extname.
|
||||||
return "" if basename.match?(/\b\d+\.\d+[^\.]*\Z/) && !basename.end_with?(".7z")
|
return "" if basename.match?(/\b\d+\.\d+[^.]*\Z/) && !basename.end_with?(".7z")
|
||||||
|
|
||||||
File.extname(basename)
|
File.extname(basename)
|
||||||
end
|
end
|
||||||
@ -398,15 +398,6 @@ class Pathname
|
|||||||
basename.to_s == ".DS_Store"
|
basename.to_s == ".DS_Store"
|
||||||
end
|
end
|
||||||
|
|
||||||
# https://bugs.ruby-lang.org/issues/9915
|
|
||||||
if RUBY_VERSION == "2.0.0"
|
|
||||||
prepend Module.new {
|
|
||||||
def inspect
|
|
||||||
super.force_encoding(@path.encoding)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def binary_executable?
|
def binary_executable?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,21 +2,6 @@
|
|||||||
|
|
||||||
require "active_support/core_ext/object/blank"
|
require "active_support/core_ext/object/blank"
|
||||||
|
|
||||||
class String
|
|
||||||
# String.chomp, but if result is empty: returns nil instead.
|
|
||||||
# Allows `chuzzle || foo` short-circuits.
|
|
||||||
# TODO: Deprecate.
|
|
||||||
def chuzzle
|
|
||||||
s = chomp
|
|
||||||
s unless s.empty?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class NilClass
|
|
||||||
# TODO: Deprecate.
|
|
||||||
def chuzzle; end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Used by the inreplace function (in `utils.rb`).
|
# Used by the inreplace function (in `utils.rb`).
|
||||||
module StringInreplaceExtension
|
module StringInreplaceExtension
|
||||||
attr_accessor :errors
|
attr_accessor :errors
|
||||||
@ -41,7 +26,7 @@ module StringInreplaceExtension
|
|||||||
# Looks for Makefile style variable definitions and replaces the
|
# Looks for Makefile style variable definitions and replaces the
|
||||||
# value with "new_value", or removes the definition entirely.
|
# value with "new_value", or removes the definition entirely.
|
||||||
def change_make_var!(flag, new_value)
|
def change_make_var!(flag, new_value)
|
||||||
return if gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?\+\:\!]?=[ \t]*((?:.*\\\n)*.*)$/, "#{flag}=#{new_value}", false)
|
return if gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, "#{flag}=#{new_value}", false)
|
||||||
|
|
||||||
errors << "expected to change #{flag.inspect} to #{new_value.inspect}"
|
errors << "expected to change #{flag.inspect} to #{new_value.inspect}"
|
||||||
end
|
end
|
||||||
@ -50,7 +35,7 @@ module StringInreplaceExtension
|
|||||||
def remove_make_var!(flags)
|
def remove_make_var!(flags)
|
||||||
Array(flags).each do |flag|
|
Array(flags).each do |flag|
|
||||||
# Also remove trailing \n, if present.
|
# Also remove trailing \n, if present.
|
||||||
unless gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?\+\:\!]?=(?:.*\\\n)*.*$\n?/, "", false)
|
unless gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=(?:.*\\\n)*.*$\n?/, "", false)
|
||||||
errors << "expected to remove #{flag.inspect}"
|
errors << "expected to remove #{flag.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -58,6 +43,6 @@ module StringInreplaceExtension
|
|||||||
|
|
||||||
# Finds the specified variable
|
# Finds the specified variable
|
||||||
def get_make_var(flag)
|
def get_make_var(flag)
|
||||||
self[/^#{Regexp.escape(flag)}[ \t]*[\\?\+\:\!]?=[ \t]*((?:.*\\\n)*.*)$/, 1]
|
self[/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, 1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1172,7 +1172,7 @@ class Formula
|
|||||||
begin
|
begin
|
||||||
yield self, staging
|
yield self, staging
|
||||||
rescue
|
rescue
|
||||||
staging.retain! if Homebrew.args.interactive? || ARGV.debug?
|
staging.retain! if Homebrew.args.interactive? || Homebrew.args.debug?
|
||||||
raise
|
raise
|
||||||
ensure
|
ensure
|
||||||
cp Dir["config.log", "CMakeCache.txt"], logs
|
cp Dir["config.log", "CMakeCache.txt"], logs
|
||||||
@ -1822,7 +1822,7 @@ class Formula
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue Exception # rubocop:disable Lint/RescueException
|
rescue Exception # rubocop:disable Lint/RescueException
|
||||||
staging.retain! if ARGV.debug?
|
staging.retain! if Homebrew.args.debug?
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2090,7 +2090,6 @@ class Formula
|
|||||||
private
|
private
|
||||||
|
|
||||||
def prepare_patches
|
def prepare_patches
|
||||||
active_spec.add_legacy_patches(patches) if respond_to?(:patches)
|
|
||||||
patchlist.grep(DATAPatch) { |p| p.path = path }
|
patchlist.grep(DATAPatch) { |p| p.path = path }
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2171,7 +2170,10 @@ class Formula
|
|||||||
raise "You cannot override Formula#brew in class #{name}"
|
raise "You cannot override Formula#brew in class #{name}"
|
||||||
when :test
|
when :test
|
||||||
define_method(:test_defined?) { true }
|
define_method(:test_defined?) { true }
|
||||||
|
when :patches
|
||||||
|
odeprecated "a Formula#patches definition", "'patch do' block calls"
|
||||||
when :options
|
when :options
|
||||||
|
odeprecated "a Formula#options definition", "'option do' block calls"
|
||||||
instance = allocate
|
instance = allocate
|
||||||
|
|
||||||
specs.each do |spec|
|
specs.each do |spec|
|
||||||
@ -2385,6 +2387,7 @@ class Formula
|
|||||||
@devel ||= SoftwareSpec.new
|
@devel ||= SoftwareSpec.new
|
||||||
return @devel unless block_given?
|
return @devel unless block_given?
|
||||||
|
|
||||||
|
odeprecated "'devel' blocks in formulae", "'head' blocks or @-versioned formulae"
|
||||||
@devel.instance_eval(&block)
|
@devel.instance_eval(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2668,7 +2671,7 @@ class Formula
|
|||||||
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
||||||
# end</pre>
|
# end</pre>
|
||||||
def livecheck(&block)
|
def livecheck(&block)
|
||||||
@livecheck ||= Livecheck.new
|
@livecheck ||= Livecheck.new(self)
|
||||||
return @livecheck unless block_given?
|
return @livecheck unless block_given?
|
||||||
|
|
||||||
@livecheckable = true
|
@livecheckable = true
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class FormulaInstaller
|
|||||||
@git = false
|
@git = false
|
||||||
@verbose = Homebrew.args.verbose?
|
@verbose = Homebrew.args.verbose?
|
||||||
@quiet = Homebrew.args.quiet?
|
@quiet = Homebrew.args.quiet?
|
||||||
@debug = ARGV.debug?
|
@debug = Homebrew.args.debug?
|
||||||
@installed_as_dependency = false
|
@installed_as_dependency = false
|
||||||
@installed_on_request = true
|
@installed_on_request = true
|
||||||
@options = Options.new
|
@options = Options.new
|
||||||
@ -100,7 +100,7 @@ class FormulaInstaller
|
|||||||
return false if !formula.bottled? && !formula.local_bottle_path
|
return false if !formula.bottled? && !formula.local_bottle_path
|
||||||
return true if force_bottle?
|
return true if force_bottle?
|
||||||
return false if build_from_source? || build_bottle? || interactive?
|
return false if build_from_source? || build_bottle? || interactive?
|
||||||
return false if ARGV.cc
|
return false if Homebrew.args.cc
|
||||||
return false unless options.empty?
|
return false unless options.empty?
|
||||||
return false if formula.bottle_disabled?
|
return false if formula.bottle_disabled?
|
||||||
|
|
||||||
@ -141,7 +141,6 @@ class FormulaInstaller
|
|||||||
def prelude
|
def prelude
|
||||||
Tab.clear_cache
|
Tab.clear_cache
|
||||||
verify_deps_exist unless ignore_deps?
|
verify_deps_exist unless ignore_deps?
|
||||||
lock
|
|
||||||
check_install_sanity
|
check_install_sanity
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -221,6 +220,8 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
def install
|
def install
|
||||||
|
lock
|
||||||
|
|
||||||
start_time = Time.now
|
start_time = Time.now
|
||||||
if !formula.bottle_unneeded? && !pour_bottle? && DevelopmentTools.installed?
|
if !formula.bottle_unneeded? && !pour_bottle? && DevelopmentTools.installed?
|
||||||
Homebrew::Install.perform_build_from_source_checks
|
Homebrew::Install.perform_build_from_source_checks
|
||||||
@ -417,7 +418,7 @@ class FormulaInstaller
|
|||||||
|
|
||||||
req_map.each_pair do |dependent, reqs|
|
req_map.each_pair do |dependent, reqs|
|
||||||
reqs.each do |req|
|
reqs.each do |req|
|
||||||
next if dependent.installed? && req.name == "maximummacos"
|
next if dependent.latest_version_installed? && req.name == "maximummacos"
|
||||||
|
|
||||||
@requirement_messages << "#{dependent}: #{req.message}"
|
@requirement_messages << "#{dependent}: #{req.message}"
|
||||||
fatals << req if req.fatal?
|
fatals << req if req.fatal?
|
||||||
@ -453,13 +454,16 @@ class FormulaInstaller
|
|||||||
build = effective_build_options_for(dependent)
|
build = effective_build_options_for(dependent)
|
||||||
install_bottle_for_dependent = install_bottle_for?(dependent, build)
|
install_bottle_for_dependent = install_bottle_for?(dependent, build)
|
||||||
|
|
||||||
|
keep_build_test = false
|
||||||
|
keep_build_test ||= runtime_requirements.include?(req)
|
||||||
|
keep_build_test ||= req.test? && include_test? && dependent == f
|
||||||
|
keep_build_test ||= req.build? && !install_bottle_for_dependent && !dependent.latest_version_installed?
|
||||||
|
|
||||||
if req.prune_from_option?(build)
|
if req.prune_from_option?(build)
|
||||||
Requirement.prune
|
Requirement.prune
|
||||||
elsif req.satisfied?
|
elsif req.satisfied?
|
||||||
Requirement.prune
|
Requirement.prune
|
||||||
elsif include_test? && req.test?
|
elsif (req.build? || req.test?) && !keep_build_test
|
||||||
next
|
|
||||||
elsif !runtime_requirements.include?(req) && install_bottle_for_dependent
|
|
||||||
Requirement.prune
|
Requirement.prune
|
||||||
elsif (dep = formula_deps_map[dependent.name]) && dep.build?
|
elsif (dep = formula_deps_map[dependent.name]) && dep.build?
|
||||||
Requirement.prune
|
Requirement.prune
|
||||||
@ -486,13 +490,13 @@ class FormulaInstaller
|
|||||||
inherited_options.fetch(dependent.name, []),
|
inherited_options.fetch(dependent.name, []),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
keep_build_test = false
|
||||||
|
keep_build_test ||= dep.test? && include_test? && Homebrew.args.include_formula_test_deps?(dependent)
|
||||||
|
keep_build_test ||= dep.build? && !install_bottle_for?(dependent, build) && !dependent.latest_version_installed?
|
||||||
|
|
||||||
if dep.prune_from_option?(build)
|
if dep.prune_from_option?(build)
|
||||||
Dependency.prune
|
Dependency.prune
|
||||||
elsif dep.test? && !dep.build? && !include_test?
|
elsif (dep.build? || dep.test?) && !keep_build_test
|
||||||
Dependency.prune
|
|
||||||
elsif dep.build? && !dep.test? && install_bottle_for?(dependent, build)
|
|
||||||
Dependency.prune
|
|
||||||
elsif dep.prune_if_build_and_not_dependent?(dependent)
|
|
||||||
Dependency.prune
|
Dependency.prune
|
||||||
elsif dep.satisfied?(inherited_options[dep.name])
|
elsif dep.satisfied?(inherited_options[dep.name])
|
||||||
Dependency.skip
|
Dependency.skip
|
||||||
@ -568,6 +572,7 @@ class FormulaInstaller
|
|||||||
|
|
||||||
fi.build_from_source = Homebrew.args.build_formula_from_source?(df)
|
fi.build_from_source = Homebrew.args.build_formula_from_source?(df)
|
||||||
fi.force_bottle = false
|
fi.force_bottle = false
|
||||||
|
fi.include_test = Homebrew.args.include_formula_test_deps?(df)
|
||||||
fi.verbose = verbose?
|
fi.verbose = verbose?
|
||||||
fi.quiet = quiet?
|
fi.quiet = quiet?
|
||||||
fi.debug = debug?
|
fi.debug = debug?
|
||||||
@ -589,7 +594,7 @@ class FormulaInstaller
|
|||||||
linked_keg.unlink
|
linked_keg.unlink
|
||||||
end
|
end
|
||||||
|
|
||||||
if df.installed?
|
if df.latest_version_installed?
|
||||||
installed_keg = Keg.new(df.prefix)
|
installed_keg = Keg.new(df.prefix)
|
||||||
tmp_keg = Pathname.new("#{installed_keg}.tmp")
|
tmp_keg = Pathname.new("#{installed_keg}.tmp")
|
||||||
installed_keg.rename(tmp_keg)
|
installed_keg.rename(tmp_keg)
|
||||||
@ -610,6 +615,7 @@ class FormulaInstaller
|
|||||||
fi.options &= df.options
|
fi.options &= df.options
|
||||||
fi.build_from_source = Homebrew.args.build_formula_from_source?(df)
|
fi.build_from_source = Homebrew.args.build_formula_from_source?(df)
|
||||||
fi.force_bottle = false
|
fi.force_bottle = false
|
||||||
|
fi.include_test = Homebrew.args.include_formula_test_deps?(df)
|
||||||
fi.verbose = verbose?
|
fi.verbose = verbose?
|
||||||
fi.quiet = quiet?
|
fi.quiet = quiet?
|
||||||
fi.debug = debug?
|
fi.debug = debug?
|
||||||
@ -723,11 +729,11 @@ class FormulaInstaller
|
|||||||
args << "--interactive" if interactive?
|
args << "--interactive" if interactive?
|
||||||
args << "--verbose" if verbose?
|
args << "--verbose" if verbose?
|
||||||
args << "--debug" if debug?
|
args << "--debug" if debug?
|
||||||
args << "--cc=#{ARGV.cc}" if ARGV.cc
|
args << "--cc=#{Homebrew.args.cc}" if Homebrew.args.cc
|
||||||
args << "--keep-tmp" if Homebrew.args.keep_tmp?
|
args << "--keep-tmp" if Homebrew.args.keep_tmp?
|
||||||
|
|
||||||
if ARGV.env
|
if Homebrew.args.env.present?
|
||||||
args << "--env=#{ARGV.env}"
|
args << "--env=#{Homebrew.args.env}"
|
||||||
elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" }
|
elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" }
|
||||||
args << "--env=std"
|
args << "--env=std"
|
||||||
end
|
end
|
||||||
@ -740,7 +746,7 @@ class FormulaInstaller
|
|||||||
|
|
||||||
formula.options.each do |opt|
|
formula.options.each do |opt|
|
||||||
name = opt.name[/^([^=]+)=$/, 1]
|
name = opt.name[/^([^=]+)=$/, 1]
|
||||||
value = ARGV.value(name) if name
|
value = Homebrew.args.value(name) if name
|
||||||
args << "--#{name}=#{value}" if value
|
args << "--#{name}=#{value}" if value
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -964,9 +970,10 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
|
|
||||||
def fetch_dependencies
|
def fetch_dependencies
|
||||||
deps = compute_dependencies
|
return if ignore_deps?
|
||||||
|
|
||||||
return if deps.empty? || ignore_deps?
|
deps = compute_dependencies
|
||||||
|
return if deps.empty?
|
||||||
|
|
||||||
deps.each { |dep, _options| fetch_dependency(dep) }
|
deps.each { |dep, _options| fetch_dependency(dep) }
|
||||||
end
|
end
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class FormulaVersions
|
|||||||
rescue *IGNORED_EXCEPTIONS => e
|
rescue *IGNORED_EXCEPTIONS => e
|
||||||
# We rescue these so that we can skip bad versions and
|
# We rescue these so that we can skip bad versions and
|
||||||
# continue walking the history
|
# continue walking the history
|
||||||
odebug "#{e} in #{name} at revision #{rev}", e.backtrace if ARGV.debug?
|
odebug "#{e} in #{name} at revision #{rev}", e.backtrace if Homebrew.args.debug?
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
nil
|
nil
|
||||||
ensure
|
ensure
|
||||||
|
|||||||
@ -9,6 +9,8 @@ require "extend/cachable"
|
|||||||
module Formulary
|
module Formulary
|
||||||
extend Cachable
|
extend Cachable
|
||||||
|
|
||||||
|
URL_START_REGEX = %r{(https?|ftp|file)://}.freeze
|
||||||
|
|
||||||
def self.enable_factory_cache!
|
def self.enable_factory_cache!
|
||||||
@factory_cache = true
|
@factory_cache = true
|
||||||
end
|
end
|
||||||
@ -130,7 +132,7 @@ module Formulary
|
|||||||
private
|
private
|
||||||
|
|
||||||
def load_file
|
def load_file
|
||||||
$stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if ARGV.debug?
|
$stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if Homebrew.args.debug?
|
||||||
raise FormulaUnavailableError, name unless path.file?
|
raise FormulaUnavailableError, name unless path.file?
|
||||||
|
|
||||||
Formulary.load_formula_from_path(name, path)
|
Formulary.load_formula_from_path(name, path)
|
||||||
@ -141,7 +143,7 @@ module Formulary
|
|||||||
class BottleLoader < FormulaLoader
|
class BottleLoader < FormulaLoader
|
||||||
def initialize(bottle_name)
|
def initialize(bottle_name)
|
||||||
case bottle_name
|
case bottle_name
|
||||||
when %r{(https?|ftp|file)://}
|
when URL_START_REGEX
|
||||||
# The name of the formula is found between the last slash and the last hyphen.
|
# The name of the formula is found between the last slash and the last hyphen.
|
||||||
formula_name = File.basename(bottle_name)[/(.+)-/, 1]
|
formula_name = File.basename(bottle_name)[/(.+)-/, 1]
|
||||||
resource = Resource.new(formula_name) { url bottle_name }
|
resource = Resource.new(formula_name) { url bottle_name }
|
||||||
@ -205,21 +207,20 @@ module Formulary
|
|||||||
def load_file
|
def load_file
|
||||||
if url =~ %r{githubusercontent.com/[\w-]+/[\w-]+/[a-f0-9]{40}(/Formula)?/([\w+-.@]+).rb}
|
if url =~ %r{githubusercontent.com/[\w-]+/[\w-]+/[a-f0-9]{40}(/Formula)?/([\w+-.@]+).rb}
|
||||||
formula_name = Regexp.last_match(2)
|
formula_name = Regexp.last_match(2)
|
||||||
opoo <<~EOS
|
odeprecated "Installation of #{formula_name} from a GitHub commit URL",
|
||||||
Unsupported installation from a commit URL!
|
"'brew extract #{formula_name}' to stable tap on GitHub"
|
||||||
Consider using `brew extract #{formula_name} ...` instead!"
|
elsif url.match?(%r{^(https?|ftp)://})
|
||||||
This will extract your desired #{formula_name} version to a stable tap instead of
|
odeprecated "Non-checksummed download of #{name} formula file from an arbitrary URL",
|
||||||
installing from a commit URL that cannnot receive updates or fixes!
|
"'brew extract' or 'brew create' and 'brew tap-new' to create a "\
|
||||||
|
"formula file in a tap on GitHub"
|
||||||
EOS
|
|
||||||
end
|
end
|
||||||
HOMEBREW_CACHE_FORMULA.mkpath
|
HOMEBREW_CACHE_FORMULA.mkpath
|
||||||
FileUtils.rm_f(path)
|
FileUtils.rm_f(path)
|
||||||
curl_download url, to: path
|
curl_download url, to: path
|
||||||
super
|
super
|
||||||
rescue MethodDeprecatedError => e
|
rescue MethodDeprecatedError => e
|
||||||
if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/}
|
if url =~ %r{github.com/([\w-]+)/([\w-]+)/}
|
||||||
e.issues_url = "https://github.com/#{Regexp.last_match(1)}/homebrew-#{Regexp.last_match(2)}/issues/new"
|
e.issues_url = "https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/issues/new"
|
||||||
end
|
end
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
@ -307,7 +308,7 @@ module Formulary
|
|||||||
end
|
end
|
||||||
|
|
||||||
def klass
|
def klass
|
||||||
$stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if ARGV.debug?
|
$stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if Homebrew.args.debug?
|
||||||
namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents)}"
|
namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents)}"
|
||||||
Formulary.load_formula(name, path, contents, namespace)
|
Formulary.load_formula(name, path, contents, namespace)
|
||||||
end
|
end
|
||||||
@ -418,7 +419,7 @@ module Formulary
|
|||||||
case ref
|
case ref
|
||||||
when Pathname::BOTTLE_EXTNAME_RX
|
when Pathname::BOTTLE_EXTNAME_RX
|
||||||
return BottleLoader.new(ref)
|
return BottleLoader.new(ref)
|
||||||
when %r{(https?|ftp|file)://}
|
when URL_START_REGEX
|
||||||
return FromUrlLoader.new(ref)
|
return FromUrlLoader.new(ref)
|
||||||
when HOMEBREW_TAP_FORMULA_REGEX
|
when HOMEBREW_TAP_FORMULA_REGEX
|
||||||
return TapLoader.new(ref, from: from)
|
return TapLoader.new(ref, from: from)
|
||||||
@ -483,20 +484,4 @@ module Formulary
|
|||||||
]).find(&:file?)
|
]).find(&:file?)
|
||||||
end.compact
|
end.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_with_priority(ref, spec = :stable)
|
|
||||||
possible_pinned_tap_formulae = tap_paths(ref, Dir["#{HOMEBREW_LIBRARY}/PinnedTaps/*/*/"]).map(&:realpath)
|
|
||||||
raise TapFormulaAmbiguityError.new(ref, possible_pinned_tap_formulae) if possible_pinned_tap_formulae.size > 1
|
|
||||||
|
|
||||||
if possible_pinned_tap_formulae.size == 1
|
|
||||||
selected_formula = factory(possible_pinned_tap_formulae.first, spec)
|
|
||||||
if core_path(ref).file?
|
|
||||||
odisabled "the brew tap-pin command",
|
|
||||||
"fully-scoped user/tap/formula naming when installing and in dependency references"
|
|
||||||
end
|
|
||||||
selected_formula
|
|
||||||
else
|
|
||||||
factory(ref, spec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -35,13 +35,10 @@ require "env_config"
|
|||||||
|
|
||||||
require "config"
|
require "config"
|
||||||
require "os"
|
require "os"
|
||||||
require "extend/ARGV"
|
|
||||||
require "cli/args"
|
require "cli/args"
|
||||||
require "messages"
|
require "messages"
|
||||||
require "system_command"
|
require "system_command"
|
||||||
|
|
||||||
ARGV.extend(HomebrewArgvExtension)
|
|
||||||
|
|
||||||
HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"]
|
HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"]
|
||||||
HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"]
|
HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"]
|
||||||
HOMEBREW_WWW = "https://brew.sh"
|
HOMEBREW_WWW = "https://brew.sh"
|
||||||
|
|||||||
@ -103,7 +103,7 @@ module Homebrew
|
|||||||
help_lines = command_help_lines(path)
|
help_lines = command_help_lines(path)
|
||||||
return if help_lines.blank?
|
return if help_lines.blank?
|
||||||
|
|
||||||
Formatter.wrap(help_lines.join.gsub(/^ /, ""), COMMAND_DESC_WIDTH)
|
Formatter.wrap(help_lines.join.delete_prefix(" "), COMMAND_DESC_WIDTH)
|
||||||
.sub("@hide_from_man_page ", "")
|
.sub("@hide_from_man_page ", "")
|
||||||
.sub(/^\* /, "#{Tty.bold}Usage: brew#{Tty.reset} ")
|
.sub(/^\* /, "#{Tty.bold}Usage: brew#{Tty.reset} ")
|
||||||
.gsub(/`(.*?)`/m, "#{Tty.bold}\\1#{Tty.reset}")
|
.gsub(/`(.*?)`/m, "#{Tty.bold}\\1#{Tty.reset}")
|
||||||
|
|||||||
@ -37,11 +37,11 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_cc_argv
|
def check_cc_argv
|
||||||
return unless ARGV.cc
|
return unless Homebrew.args.cc
|
||||||
|
|
||||||
@checks ||= Diagnostic::Checks.new
|
@checks ||= Diagnostic::Checks.new
|
||||||
opoo <<~EOS
|
opoo <<~EOS
|
||||||
You passed `--cc=#{ARGV.cc}`.
|
You passed `--cc=#{Homebrew.args.cc}`.
|
||||||
#{@checks.please_create_pull_requests}
|
#{@checks.please_create_pull_requests}
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|||||||
@ -117,6 +117,10 @@ class Keg
|
|||||||
path/"lib"
|
path/"lib"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def libexec
|
||||||
|
path/"libexec"
|
||||||
|
end
|
||||||
|
|
||||||
def text_files
|
def text_files
|
||||||
text_files = []
|
text_files = []
|
||||||
return text_files unless which("file") && which("xargs")
|
return text_files unless which("file") && which("xargs")
|
||||||
|
|||||||
@ -33,7 +33,7 @@ module Language
|
|||||||
next if build.without? python_formula.to_s
|
next if build.without? python_formula.to_s
|
||||||
|
|
||||||
version = major_minor_version python
|
version = major_minor_version python
|
||||||
ENV["PYTHONPATH"] = if python_formula.installed?
|
ENV["PYTHONPATH"] = if python_formula.latest_version_installed?
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
homebrew_site_packages(python)
|
homebrew_site_packages(python)
|
||||||
|
|||||||
@ -10,7 +10,8 @@ class Livecheck
|
|||||||
# e.g. `Not maintained`
|
# e.g. `Not maintained`
|
||||||
attr_reader :skip_msg
|
attr_reader :skip_msg
|
||||||
|
|
||||||
def initialize
|
def initialize(formula)
|
||||||
|
@formula = formula
|
||||||
@regex = nil
|
@regex = nil
|
||||||
@skip = false
|
@skip = false
|
||||||
@skip_msg = nil
|
@skip_msg = nil
|
||||||
@ -44,7 +45,14 @@ class Livecheck
|
|||||||
def url(val = nil)
|
def url(val = nil)
|
||||||
return @url if val.nil?
|
return @url if val.nil?
|
||||||
|
|
||||||
@url = val
|
@url = case val
|
||||||
|
when :head, :stable, :devel
|
||||||
|
@formula.send(val).url
|
||||||
|
when :homepage
|
||||||
|
@formula.homepage
|
||||||
|
else
|
||||||
|
val
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a Hash of all instance variable values.
|
# Returns a Hash of all instance variable values.
|
||||||
|
|||||||
@ -8,7 +8,7 @@ class Locale
|
|||||||
REGION_REGEX = /(?:[A-Z]{2}|\d{3})/.freeze # ISO 3166-1 or UN M.49
|
REGION_REGEX = /(?:[A-Z]{2}|\d{3})/.freeze # ISO 3166-1 or UN M.49
|
||||||
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/.freeze # ISO 15924
|
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/.freeze # ISO 15924
|
||||||
|
|
||||||
LOCALE_REGEX = /\A((?:#{LANGUAGE_REGEX}|#{REGION_REGEX}|#{SCRIPT_REGEX})(?:\-|$)){1,3}\Z/.freeze
|
LOCALE_REGEX = /\A((?:#{LANGUAGE_REGEX}|#{REGION_REGEX}|#{SCRIPT_REGEX})(?:-|$)){1,3}\Z/.freeze
|
||||||
|
|
||||||
def self.parse(string)
|
def self.parse(string)
|
||||||
string = string.to_s
|
string = string.to_s
|
||||||
@ -16,7 +16,7 @@ class Locale
|
|||||||
raise ParserError, "'#{string}' cannot be parsed to a #{self}" unless string.match?(LOCALE_REGEX)
|
raise ParserError, "'#{string}' cannot be parsed to a #{self}" unless string.match?(LOCALE_REGEX)
|
||||||
|
|
||||||
scan = proc do |regex|
|
scan = proc do |regex|
|
||||||
string.scan(/(?:\-|^)(#{regex})(?:\-|$)/).flatten.first
|
string.scan(/(?:-|^)(#{regex})(?:-|$)/).flatten.first
|
||||||
end
|
end
|
||||||
|
|
||||||
language = scan.call(LANGUAGE_REGEX)
|
language = scan.call(LANGUAGE_REGEX)
|
||||||
|
|||||||
@ -97,11 +97,9 @@ can take several different forms:
|
|||||||
You can still access these formulae by using a special syntax, e.g.
|
You can still access these formulae by using a special syntax, e.g.
|
||||||
`homebrew/dupes/vim` or `homebrew/versions/node4`.
|
`homebrew/dupes/vim` or `homebrew/versions/node4`.
|
||||||
|
|
||||||
* An arbitrary file or URL:
|
* An arbitrary file:
|
||||||
Homebrew can install formulae via URL, e.g.
|
Homebrew can install formulae from a local path. It can point to either a
|
||||||
`https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Formula/git.rb`,
|
formula file or a bottle.
|
||||||
or from a local path. It can point to either a formula file or a bottle.
|
|
||||||
In the case of a URL, the downloaded file will be cached for later use.
|
|
||||||
|
|
||||||
## ENVIRONMENT
|
## ENVIRONMENT
|
||||||
|
|
||||||
|
|||||||
@ -209,7 +209,7 @@ class Migrator
|
|||||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||||
onoe "Error occurred while migrating."
|
onoe "Error occurred while migrating."
|
||||||
puts e
|
puts e
|
||||||
puts e.backtrace if ARGV.debug?
|
puts e.backtrace if Homebrew.args.debug?
|
||||||
puts "Backing up..."
|
puts "Backing up..."
|
||||||
ignore_interrupts { backup_oldname }
|
ignore_interrupts { backup_oldname }
|
||||||
ensure
|
ensure
|
||||||
@ -318,7 +318,7 @@ class Migrator
|
|||||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||||
onoe "An unexpected error occurred during linking"
|
onoe "An unexpected error occurred during linking"
|
||||||
puts e
|
puts e
|
||||||
puts e.backtrace if ARGV.debug?
|
puts e.backtrace if Homebrew.args.debug?
|
||||||
ignore_interrupts { new_keg.unlink }
|
ignore_interrupts { new_keg.unlink }
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|||||||
@ -42,11 +42,7 @@ module OS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def languages
|
def languages
|
||||||
@languages ||= [
|
@languages ||= [*ENV["LANG"]&.slice(/[a-z]+/)].uniq
|
||||||
*ARGV.value("language")&.split(","),
|
|
||||||
*ENV["HOMEBREW_LANGUAGES"]&.split(","),
|
|
||||||
*ENV["LANG"]&.slice(/[a-z]+/),
|
|
||||||
].uniq
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def language
|
def language
|
||||||
|
|||||||
@ -60,9 +60,11 @@ module OS
|
|||||||
|
|
||||||
def languages
|
def languages
|
||||||
@languages ||= [
|
@languages ||= [
|
||||||
*ARGV.value("language")&.split(","),
|
*Homebrew.args.value("language")&.split(","),
|
||||||
*ENV["HOMEBREW_LANGUAGES"]&.split(","),
|
*ENV["HOMEBREW_LANGUAGES"]&.split(","),
|
||||||
*Open3.capture2("defaults", "read", "-g", "AppleLanguages")[0].scan(/[^ \n"(),]+/),
|
*Open3.capture2("defaults", "read", "-g", "AppleLanguages")
|
||||||
|
.first
|
||||||
|
.scan(/[^ \n"(),]+/),
|
||||||
].uniq
|
].uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ class Keg
|
|||||||
return if file.dylib_id == id
|
return if file.dylib_id == id
|
||||||
|
|
||||||
@require_relocation = true
|
@require_relocation = true
|
||||||
odebug "Changing dylib ID of #{file}\n from #{file.dylib_id}\n to #{id}" if ARGV.debug?
|
odebug "Changing dylib ID of #{file}\n from #{file.dylib_id}\n to #{id}" if Homebrew.args.debug?
|
||||||
MachO::Tools.change_dylib_id(file, id, strict: false)
|
MachO::Tools.change_dylib_id(file, id, strict: false)
|
||||||
rescue MachO::MachOError
|
rescue MachO::MachOError
|
||||||
onoe <<~EOS
|
onoe <<~EOS
|
||||||
@ -20,7 +20,7 @@ class Keg
|
|||||||
return if old == new
|
return if old == new
|
||||||
|
|
||||||
@require_relocation = true
|
@require_relocation = true
|
||||||
odebug "Changing install name in #{file}\n from #{old}\n to #{new}" if ARGV.debug?
|
odebug "Changing install name in #{file}\n from #{old}\n to #{new}" if Homebrew.args.debug?
|
||||||
MachO::Tools.change_install_name(file, old, new, strict: false)
|
MachO::Tools.change_install_name(file, old, new, strict: false)
|
||||||
rescue MachO::MachOError
|
rescue MachO::MachOError
|
||||||
onoe <<~EOS
|
onoe <<~EOS
|
||||||
|
|||||||
@ -169,6 +169,7 @@ end
|
|||||||
# Legacy patches have no checksum and are not cached.
|
# Legacy patches have no checksum and are not cached.
|
||||||
class LegacyPatch < ExternalPatch
|
class LegacyPatch < ExternalPatch
|
||||||
def initialize(strip, url)
|
def initialize(strip, url)
|
||||||
|
odeprecated "legacy patches", "'patch do' blocks"
|
||||||
super(strip)
|
super(strip)
|
||||||
resource.url(url)
|
resource.url(url)
|
||||||
resource.download_strategy = CurlDownloadStrategy
|
resource.download_strategy = CurlDownloadStrategy
|
||||||
|
|||||||
@ -35,8 +35,8 @@ module Homebrew
|
|||||||
fi.installed_as_dependency = tab.installed_as_dependency
|
fi.installed_as_dependency = tab.installed_as_dependency
|
||||||
fi.installed_on_request = tab.installed_on_request
|
fi.installed_on_request = tab.installed_on_request
|
||||||
end
|
end
|
||||||
fi.fetch
|
|
||||||
fi.prelude
|
fi.prelude
|
||||||
|
fi.fetch
|
||||||
|
|
||||||
oh1 "Reinstalling #{Formatter.identifier(f.full_name)} #{options.to_a.join " "}"
|
oh1 "Reinstalling #{Formatter.identifier(f.full_name)} #{options.to_a.join " "}"
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ class JavaRequirement < Requirement
|
|||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
javas << jdk.bin/"java" if jdk&.installed?
|
javas << jdk.bin/"java" if jdk&.latest_version_installed?
|
||||||
javas << which("java")
|
javas << which("java")
|
||||||
javas
|
javas
|
||||||
end
|
end
|
||||||
|
|||||||
@ -72,7 +72,7 @@ class Resource
|
|||||||
# directory. Subclasses that override stage should implement the tmp
|
# directory. Subclasses that override stage should implement the tmp
|
||||||
# dir using {Mktemp} so that works with all subtypes.
|
# dir using {Mktemp} so that works with all subtypes.
|
||||||
def stage(target = nil, &block)
|
def stage(target = nil, &block)
|
||||||
raise ArgumentError, "target directory or block is required" if target.blank? && block.blank?
|
raise ArgumentError, "target directory or block is required" if !target && block.blank?
|
||||||
|
|
||||||
prepare_patches
|
prepare_patches
|
||||||
fetch_patches(skip_downloaded: true)
|
fetch_patches(skip_downloaded: true)
|
||||||
|
|||||||
@ -129,7 +129,7 @@ module RuboCop
|
|||||||
string = stanza.stanza_node.children[2]
|
string = stanza.stanza_node.children[2]
|
||||||
return string.str_content if string.str_type?
|
return string.str_content if string.str_type?
|
||||||
|
|
||||||
string.to_s.gsub(%r{.*"([a-z0-9]+\:\/\/[^"]+)".*}m, '\1')
|
string.to_s.gsub(%r{.*"([a-z0-9]+://[^"]+)".*}m, '\1')
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_match_homepage?(stanza)
|
def url_match_homepage?(stanza)
|
||||||
|
|||||||
@ -10,6 +10,11 @@ module RuboCop
|
|||||||
# - `component_precedence_list` has component hierarchy in a nested list
|
# - `component_precedence_list` has component hierarchy in a nested list
|
||||||
# where each sub array contains components' details which are at same precedence level
|
# where each sub array contains components' details which are at same precedence level
|
||||||
class ComponentsOrder < FormulaCop
|
class ComponentsOrder < FormulaCop
|
||||||
|
# `aspell`: options and resources should be grouped by language
|
||||||
|
COMPONENT_WHITELIST = %w[
|
||||||
|
aspell
|
||||||
|
].freeze
|
||||||
|
|
||||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||||
component_precedence_list = [
|
component_precedence_list = [
|
||||||
[{ name: :include, type: :method_call }],
|
[{ name: :include, type: :method_call }],
|
||||||
@ -34,6 +39,8 @@ module RuboCop
|
|||||||
[{ name: :deprecated_option, type: :method_call }],
|
[{ name: :deprecated_option, type: :method_call }],
|
||||||
[{ name: :depends_on, type: :method_call }],
|
[{ name: :depends_on, type: :method_call }],
|
||||||
[{ name: :uses_from_macos, type: :method_call }],
|
[{ name: :uses_from_macos, type: :method_call }],
|
||||||
|
[{ name: :on_macos, type: :block_call }],
|
||||||
|
[{ name: :on_linux, type: :block_call }],
|
||||||
[{ name: :conflicts_with, type: :method_call }],
|
[{ name: :conflicts_with, type: :method_call }],
|
||||||
[{ name: :skip_clean, type: :method_call }],
|
[{ name: :skip_clean, type: :method_call }],
|
||||||
[{ name: :cxxstdlib_check, type: :method_call }],
|
[{ name: :cxxstdlib_check, type: :method_call }],
|
||||||
@ -49,50 +56,115 @@ module RuboCop
|
|||||||
[{ name: :test, type: :block_call }],
|
[{ name: :test, type: :block_call }],
|
||||||
]
|
]
|
||||||
|
|
||||||
@present_components = component_precedence_list.map do |components|
|
@present_components, @offensive_nodes = check_order(component_precedence_list, body_node)
|
||||||
relevant_components = []
|
|
||||||
components.each do |component|
|
|
||||||
case component[:type]
|
|
||||||
when :method_call
|
|
||||||
relevant_components += find_method_calls_by_name(body_node, component[:name]).to_a
|
|
||||||
when :block_call
|
|
||||||
relevant_components += find_blocks(body_node, component[:name]).to_a
|
|
||||||
when :method_definition
|
|
||||||
relevant_components << find_method_def(body_node, component[:name])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
relevant_components.delete_if(&:nil?)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check if each present_components is above rest of the present_components
|
|
||||||
@present_components.take(@present_components.size - 1).each_with_index do |preceding_component, p_idx|
|
|
||||||
next if preceding_component.empty?
|
|
||||||
|
|
||||||
@present_components.drop(p_idx + 1).each do |succeeding_component|
|
|
||||||
next if succeeding_component.empty?
|
|
||||||
|
|
||||||
@offensive_nodes = check_precedence(preceding_component, succeeding_component)
|
|
||||||
component_problem @offensive_nodes[0], @offensive_nodes[1] if @offensive_nodes
|
component_problem @offensive_nodes[0], @offensive_nodes[1] if @offensive_nodes
|
||||||
|
|
||||||
|
component_precedence_list = [
|
||||||
|
[{ name: :depends_on, type: :method_call }],
|
||||||
|
[{ name: :resource, type: :block_call }],
|
||||||
|
[{ name: :patch, type: :method_call }, { name: :patch, type: :block_call }],
|
||||||
|
]
|
||||||
|
|
||||||
|
on_macos_blocks = find_blocks(body_node, :on_macos)
|
||||||
|
|
||||||
|
if on_macos_blocks.length > 1
|
||||||
|
@offensive_node = on_macos_blocks.second
|
||||||
|
@offense_source_range = on_macos_blocks.second.source_range
|
||||||
|
problem "there can only be one `on_macos` block in a formula."
|
||||||
|
end
|
||||||
|
|
||||||
|
check_on_os_block_content(component_precedence_list, on_macos_blocks.first) if on_macos_blocks.any?
|
||||||
|
|
||||||
|
on_linux_blocks = find_blocks(body_node, :on_linux)
|
||||||
|
|
||||||
|
if on_linux_blocks.length > 1
|
||||||
|
@offensive_node = on_linux_blocks.second
|
||||||
|
@offense_source_range = on_linux_blocks.second.source_range
|
||||||
|
problem "there can only be one `on_linux` block in a formula."
|
||||||
|
end
|
||||||
|
|
||||||
|
check_on_os_block_content(component_precedence_list, on_linux_blocks.first) if on_linux_blocks.any?
|
||||||
|
|
||||||
|
resource_blocks = find_blocks(body_node, :resource)
|
||||||
|
resource_blocks.each do |resource_block|
|
||||||
|
on_macos_blocks = find_blocks(resource_block.body, :on_macos)
|
||||||
|
on_linux_blocks = find_blocks(resource_block.body, :on_linux)
|
||||||
|
|
||||||
|
if on_macos_blocks.length.zero? && on_linux_blocks.length.zero?
|
||||||
|
# Found nothing. Try without .body as depending on the code,
|
||||||
|
# on_macos or on_linux might be in .body or not ...
|
||||||
|
on_macos_blocks = find_blocks(resource_block, :on_macos)
|
||||||
|
on_linux_blocks = find_blocks(resource_block, :on_linux)
|
||||||
|
|
||||||
|
next if on_macos_blocks.length.zero? && on_linux_blocks.length.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
@offensive_node = resource_block
|
||||||
|
@offense_source_range = resource_block.source_range
|
||||||
|
|
||||||
|
if on_macos_blocks.length > 1
|
||||||
|
problem "there can only be one `on_macos` block in a resource block."
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
if on_linux_blocks.length > 1
|
||||||
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# `aspell`: options and resources should be grouped by language
|
def check_on_os_block_content(component_precedence_list, on_os_block)
|
||||||
WHITELIST = %w[
|
_, offensive_node = check_order(component_precedence_list, on_os_block.body)
|
||||||
aspell
|
component_problem(*offensive_node) if offensive_node
|
||||||
].freeze
|
on_os_block.body.child_nodes.each do |child|
|
||||||
|
valid_node = depends_on_node?(child)
|
||||||
|
# Check for RuboCop::AST::SendNode instances only, as we are checking the
|
||||||
|
# method_name for patches and resources.
|
||||||
|
next unless child.instance_of? RuboCop::AST::SendNode
|
||||||
|
|
||||||
# Method to format message for reporting component precedence violations
|
valid_node ||= child.method_name.to_s == "patch"
|
||||||
def component_problem(c1, c2)
|
valid_node ||= child.method_name.to_s == "resource"
|
||||||
return if WHITELIST.include?(@formula_name)
|
|
||||||
|
|
||||||
problem "`#{format_component(c1)}` (line #{line_number(c1)}) " \
|
@offensive_node = on_os_block
|
||||||
"should be put before `#{format_component(c2)}` " \
|
@offense_source_range = on_os_block.source_range
|
||||||
"(line #{line_number(c2)})"
|
unless valid_node
|
||||||
|
problem "`#{on_os_block.method_name}` can only include `depends_on`, `patch` and `resource` nodes."
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# autocorrect method gets called just after component_problem method call
|
# autocorrect method gets called just after component_problem method call
|
||||||
def autocorrect(_node)
|
def autocorrect(_node)
|
||||||
|
return if @offensive_nodes.nil?
|
||||||
|
|
||||||
succeeding_node = @offensive_nodes[0]
|
succeeding_node = @offensive_nodes[0]
|
||||||
preceding_node = @offensive_nodes[1]
|
preceding_node = @offensive_nodes[1]
|
||||||
lambda do |corrector|
|
lambda do |corrector|
|
||||||
@ -130,6 +202,52 @@ module RuboCop
|
|||||||
return [idx, comp.index(node1), comp] if comp.member?(node1)
|
return [idx, comp.index(node1), comp] if comp.member?(node1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_order(component_precedence_list, body_node)
|
||||||
|
present_components = component_precedence_list.map do |components|
|
||||||
|
components.flat_map do |component|
|
||||||
|
case component[:type]
|
||||||
|
when :method_call
|
||||||
|
find_method_calls_by_name(body_node, component[:name]).to_a
|
||||||
|
when :block_call
|
||||||
|
find_blocks(body_node, component[:name]).to_a
|
||||||
|
when :method_definition
|
||||||
|
find_method_def(body_node, component[:name])
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if each present_components is above rest of the present_components
|
||||||
|
offensive_nodes = nil
|
||||||
|
present_components.take(present_components.size - 1).each_with_index do |preceding_component, p_idx|
|
||||||
|
next if preceding_component.empty?
|
||||||
|
|
||||||
|
present_components.drop(p_idx + 1).each do |succeeding_component|
|
||||||
|
next if succeeding_component.empty?
|
||||||
|
|
||||||
|
offensive_nodes = check_precedence(preceding_component, succeeding_component)
|
||||||
|
break if offensive_nodes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[present_components, offensive_nodes]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Method to format message for reporting component precedence violations
|
||||||
|
def component_problem(c1, c2)
|
||||||
|
return if COMPONENT_WHITELIST.include?(@formula_name)
|
||||||
|
|
||||||
|
problem "`#{format_component(c1)}` (line #{line_number(c1)}) " \
|
||||||
|
"should be put before `#{format_component(c2)}` " \
|
||||||
|
"(line #{line_number(c2)})"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Node pattern method to match
|
||||||
|
# `depends_on` variants
|
||||||
|
def_node_matcher :depends_on_node?, <<~EOS
|
||||||
|
{(if _ (send nil? :depends_on ...) nil?)
|
||||||
|
(send nil? :depends_on ...)}
|
||||||
|
EOS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -153,7 +153,7 @@ module RuboCop
|
|||||||
|
|
||||||
find_instance_method_call(body_node, :build, :include?) do |method|
|
find_instance_method_call(body_node, :build, :include?) do |method|
|
||||||
arg = parameters(method).first
|
arg = parameters(method).first
|
||||||
next unless match = regex_match_group(arg, /^\-\-(.*)$/)
|
next unless match = regex_match_group(arg, /^--(.*)$/)
|
||||||
|
|
||||||
problem "Reference '#{match[1]}' without dashes"
|
problem "Reference '#{match[1]}' without dashes"
|
||||||
end
|
end
|
||||||
@ -403,7 +403,7 @@ module RuboCop
|
|||||||
|
|
||||||
path = parameters(method).first
|
path = parameters(method).first
|
||||||
next unless path.str_type?
|
next unless path.str_type?
|
||||||
next unless match = regex_match_group(path, /^[^\*{},]+$/)
|
next unless match = regex_match_group(path, /^[^*{},]+$/)
|
||||||
|
|
||||||
problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\""
|
problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\""
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,11 +13,12 @@ module RuboCop
|
|||||||
https://downloads.sourceforge.net/project/bittwist/
|
https://downloads.sourceforge.net/project/bittwist/
|
||||||
https://downloads.sourceforge.net/project/launch4j/
|
https://downloads.sourceforge.net/project/launch4j/
|
||||||
https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard/archive/
|
https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard/archive/
|
||||||
https://github.com/obihann/archey-osx/archive/
|
https://github.com/obihann/archey-osx
|
||||||
https://github.com/sindresorhus/macos-wallpaper/archive/
|
https://github.com/sindresorhus/macos-wallpaper/archive/
|
||||||
https://raw.githubusercontent.com/liyanage/macosx-shell-scripts/
|
https://raw.githubusercontent.com/liyanage/macosx-shell-scripts/
|
||||||
https://osxbook.com/book/bonus/chapter8/core/download/gcore
|
https://osxbook.com/book/bonus/chapter8/core/download/gcore
|
||||||
https://naif.jpl.nasa.gov/pub/naif/toolkit/C/MacIntel_OSX_AppleC_64bit/packages/
|
https://naif.jpl.nasa.gov/pub/naif/toolkit/C/MacIntel_OSX_AppleC_64bit/packages/
|
||||||
|
https://artifacts.videolan.org/x264/release-macos/
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
# These are formulae that, sadly, require an upstream binary to bootstrap.
|
# These are formulae that, sadly, require an upstream binary to bootstrap.
|
||||||
@ -48,6 +49,12 @@ module RuboCop
|
|||||||
urls = find_every_func_call_by_name(body_node, :url)
|
urls = find_every_func_call_by_name(body_node, :url)
|
||||||
mirrors = find_every_func_call_by_name(body_node, :mirror)
|
mirrors = find_every_func_call_by_name(body_node, :mirror)
|
||||||
|
|
||||||
|
# Identify livecheck urls, to skip some checks for them
|
||||||
|
livecheck_url = if (livecheck = find_every_func_call_by_name(body_node, :livecheck).first) &&
|
||||||
|
(livecheck_url = find_every_func_call_by_name(livecheck.parent, :url).first)
|
||||||
|
string_content(parameters(livecheck_url).first)
|
||||||
|
end
|
||||||
|
|
||||||
# GNU urls; doesn't apply to mirrors
|
# GNU urls; doesn't apply to mirrors
|
||||||
gnu_pattern = %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)}
|
gnu_pattern = %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)}
|
||||||
audit_urls(urls, gnu_pattern) do |match, url|
|
audit_urls(urls, gnu_pattern) do |match, url|
|
||||||
@ -63,9 +70,21 @@ module RuboCop
|
|||||||
|
|
||||||
apache_pattern = %r{^https?://(?:[^/]*\.)?apache\.org/(?:dyn/closer\.cgi\?path=/?|dist/)(.*)}i
|
apache_pattern = %r{^https?://(?:[^/]*\.)?apache\.org/(?:dyn/closer\.cgi\?path=/?|dist/)(.*)}i
|
||||||
audit_urls(urls, apache_pattern) do |match, url|
|
audit_urls(urls, apache_pattern) do |match, url|
|
||||||
|
next if url == livecheck_url
|
||||||
|
|
||||||
problem "#{url} should be `https://www.apache.org/dyn/closer.lua?path=#{match[1]}`"
|
problem "#{url} should be `https://www.apache.org/dyn/closer.lua?path=#{match[1]}`"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
version_control_pattern = %r{^(cvs|bzr|hg|fossil)://}
|
||||||
|
audit_urls(urls, version_control_pattern) do |match, _|
|
||||||
|
problem "Use of the #{match[1]}:// scheme is deprecated, pass `:using => :#{match[1]}` instead"
|
||||||
|
end
|
||||||
|
|
||||||
|
svn_pattern = %r{^svn\+http://}
|
||||||
|
audit_urls(urls, svn_pattern) do |_, _|
|
||||||
|
problem "Use of the svn+http:// scheme is deprecated, pass `:using => :svn` instead"
|
||||||
|
end
|
||||||
|
|
||||||
audit_urls(mirrors, /.*/) do |_, mirror|
|
audit_urls(mirrors, /.*/) do |_, mirror|
|
||||||
urls.each do |url|
|
urls.each do |url|
|
||||||
url_string = string_content(parameters(url).first)
|
url_string = string_content(parameters(url).first)
|
||||||
@ -148,7 +167,7 @@ module RuboCop
|
|||||||
|
|
||||||
problem "Don't use /download in SourceForge urls (url is #{url})." if url.end_with?("/download")
|
problem "Don't use /download in SourceForge urls (url is #{url})." if url.end_with?("/download")
|
||||||
|
|
||||||
if url.match?(%r{^https?://sourceforge\.})
|
if url.match?(%r{^https?://sourceforge\.}) && url != livecheck_url
|
||||||
problem "Use https://downloads.sourceforge.net to get geolocation (url is #{url})."
|
problem "Use https://downloads.sourceforge.net to get geolocation (url is #{url})."
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -220,7 +239,7 @@ module RuboCop
|
|||||||
# Use new-style archive downloads
|
# Use new-style archive downloads
|
||||||
archive_gh_pattern = %r{https://.*github.*/(?:tar|zip)ball/}
|
archive_gh_pattern = %r{https://.*github.*/(?:tar|zip)ball/}
|
||||||
audit_urls(urls, archive_gh_pattern) do |_, url|
|
audit_urls(urls, archive_gh_pattern) do |_, url|
|
||||||
next if url.match?(/\.git$/)
|
next if url.end_with?(".git")
|
||||||
|
|
||||||
problem "Use /archive/ URLs for GitHub tarballs (url is #{url})."
|
problem "Use /archive/ URLs for GitHub tarballs (url is #{url})."
|
||||||
end
|
end
|
||||||
|
|||||||
@ -221,6 +221,7 @@ class SoftwareSpec
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO
|
||||||
def add_legacy_patches(list)
|
def add_legacy_patches(list)
|
||||||
list = Patch.normalize_legacy_patches(list)
|
list = Patch.normalize_legacy_patches(list)
|
||||||
list.each { |p| p.owner = self }
|
list.each { |p| p.owner = self }
|
||||||
|
|||||||
@ -77,7 +77,7 @@ module Homebrew
|
|||||||
|
|
||||||
case output_type
|
case output_type
|
||||||
when :print
|
when :print
|
||||||
args << "--debug" if ARGV.debug?
|
args << "--debug" if Homebrew.args.debug?
|
||||||
args << "--display-cop-names" if Homebrew.args.display_cop_names?
|
args << "--display-cop-names" if Homebrew.args.display_cop_names?
|
||||||
args << "--format" << "simple" if files
|
args << "--format" << "simple" if files
|
||||||
system(cache_env, "rubocop", *args)
|
system(cache_env, "rubocop", *args)
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class SystemCommand
|
|||||||
end
|
end
|
||||||
|
|
||||||
def run!
|
def run!
|
||||||
puts redact_secrets(command.shelljoin.gsub('\=', "="), @secrets) if verbose? || ARGV.debug?
|
puts redact_secrets(command.shelljoin.gsub('\=', "="), @secrets) if verbose? || Homebrew.args.debug?
|
||||||
|
|
||||||
@output = []
|
@output = []
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@ class SystemConfig
|
|||||||
_, err, status = system_command("java", args: ["-version"], print_stderr: false)
|
_, err, status = system_command("java", args: ["-version"], print_stderr: false)
|
||||||
return "N/A" unless status.success?
|
return "N/A" unless status.success?
|
||||||
|
|
||||||
err[/java version "([\d\._]+)"/, 1] || "N/A"
|
err[/java version "([\d._]+)"/, 1] || "N/A"
|
||||||
end
|
end
|
||||||
|
|
||||||
def describe_git
|
def describe_git
|
||||||
@ -100,7 +100,7 @@ class SystemConfig
|
|||||||
def describe_curl
|
def describe_curl
|
||||||
out, = system_command(curl_executable, args: ["--version"])
|
out, = system_command(curl_executable, args: ["--version"])
|
||||||
|
|
||||||
if /^curl (?<curl_version>[\d\.]+)/ =~ out
|
if /^curl (?<curl_version>[\d.]+)/ =~ out
|
||||||
"#{curl_version} => #{curl_executable}"
|
"#{curl_version} => #{curl_executable}"
|
||||||
else
|
else
|
||||||
"N/A"
|
"N/A"
|
||||||
|
|||||||
@ -1,89 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "extend/ARGV"
|
|
||||||
|
|
||||||
describe HomebrewArgvExtension do
|
|
||||||
subject { argv.extend(described_class) }
|
|
||||||
|
|
||||||
let(:argv) { ["mxcl"] }
|
|
||||||
|
|
||||||
describe "#named" do
|
|
||||||
let(:argv) { ["foo", "--debug", "-v"] }
|
|
||||||
|
|
||||||
it "returns an array of non-option arguments" do
|
|
||||||
expect(subject.send(:named)).to eq ["foo"]
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when there are no named arguments" do
|
|
||||||
let(:argv) { [] }
|
|
||||||
|
|
||||||
it "returns an empty array" do
|
|
||||||
expect(subject.send(:named)).to be_empty
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#options_only" do
|
|
||||||
let(:argv) { ["--foo", "-vds", "a", "b", "cdefg"] }
|
|
||||||
|
|
||||||
it "returns an array of option arguments" do
|
|
||||||
expect(subject.send("options_only")).to eq ["--foo", "-vds"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#empty?" do
|
|
||||||
let(:argv) { [] }
|
|
||||||
|
|
||||||
it "returns true if it is empty" do
|
|
||||||
expect(subject).to be_empty
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#switch?" do
|
|
||||||
let(:argv) { ["-ns", "-i", "--bar", "-a-bad-arg"] }
|
|
||||||
|
|
||||||
it "returns true if the given string is a switch" do
|
|
||||||
%w[n s i].each do |s|
|
|
||||||
expect(subject.send("switch?", s)).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns false if the given string is not a switch" do
|
|
||||||
%w[b ns bar --bar -n a bad arg].each do |s|
|
|
||||||
expect(subject.send("switch?", s)).to be false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#flag?" do
|
|
||||||
let(:argv) { ["--foo", "-bq", "--bar"] }
|
|
||||||
|
|
||||||
it "returns true if the given string is a flag" do
|
|
||||||
expect(subject.send("flag?", "--foo")).to eq true
|
|
||||||
expect(subject.send("flag?", "--bar")).to eq true
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns true if there is a switch with the same initial character" do
|
|
||||||
expect(subject.send("flag?", "--baz")).to eq true
|
|
||||||
expect(subject.send("flag?", "--qux")).to eq true
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns false if there is no matching flag" do
|
|
||||||
expect(subject.send("flag?", "--frotz")).to eq false
|
|
||||||
expect(subject.send("flag?", "--debug")).to eq false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#value" do
|
|
||||||
let(:argv) { ["--foo=", "--bar=ab"] }
|
|
||||||
|
|
||||||
it "returns the value for a given string" do
|
|
||||||
expect(subject.value("foo")).to eq ""
|
|
||||||
expect(subject.value("bar")).to eq "ab"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns nil if there is no matching argument" do
|
|
||||||
expect(subject.value("baz")).to be nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -39,11 +39,11 @@ describe Cask::Audit, :cask do
|
|||||||
|
|
||||||
let(:cask) { instance_double(Cask::Cask) }
|
let(:cask) { instance_double(Cask::Cask) }
|
||||||
let(:download) { false }
|
let(:download) { false }
|
||||||
let(:check_token_conflicts) { false }
|
let(:token_conflicts) { false }
|
||||||
let(:fake_system_command) { class_double(SystemCommand) }
|
let(:fake_system_command) { class_double(SystemCommand) }
|
||||||
let(:audit) {
|
let(:audit) {
|
||||||
described_class.new(cask, download: download,
|
described_class.new(cask, download: download,
|
||||||
check_token_conflicts: check_token_conflicts,
|
token_conflicts: token_conflicts,
|
||||||
command: fake_system_command)
|
command: fake_system_command)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +517,7 @@ describe Cask::Audit, :cask do
|
|||||||
|
|
||||||
describe "token conflicts" do
|
describe "token conflicts" do
|
||||||
let(:cask_token) { "with-binary" }
|
let(:cask_token) { "with-binary" }
|
||||||
let(:check_token_conflicts) { true }
|
let(:token_conflicts) { true }
|
||||||
|
|
||||||
context "when cask token conflicts with a core formula" do
|
context "when cask token conflicts with a core formula" do
|
||||||
let(:formula_names) { %w[with-binary other-formula] }
|
let(:formula_names) { %w[with-binary other-formula] }
|
||||||
|
|||||||
@ -21,7 +21,13 @@ describe Cask::Cmd::Audit, :cask do
|
|||||||
expect(Cask::CaskLoader).to receive(:load).with(cask_token).and_return(cask)
|
expect(Cask::CaskLoader).to receive(:load).with(cask_token).and_return(cask)
|
||||||
|
|
||||||
expect(Cask::Auditor).to receive(:audit)
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
.with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
.and_return(true)
|
.and_return(true)
|
||||||
|
|
||||||
described_class.run(cask_token)
|
described_class.run(cask_token)
|
||||||
@ -32,7 +38,13 @@ describe Cask::Cmd::Audit, :cask do
|
|||||||
it "does not download the Cask per default" do
|
it "does not download the Cask per default" do
|
||||||
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
expect(Cask::Auditor).to receive(:audit)
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
.with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
.and_return(true)
|
.and_return(true)
|
||||||
|
|
||||||
described_class.run("casktoken")
|
described_class.run("casktoken")
|
||||||
@ -41,7 +53,13 @@ describe Cask::Cmd::Audit, :cask do
|
|||||||
it "download a Cask if --download flag is set" do
|
it "download a Cask if --download flag is set" do
|
||||||
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
expect(Cask::Auditor).to receive(:audit)
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
.with(cask, audit_download: true, audit_appcast: false, check_token_conflicts: false, quarantine: true)
|
.with(cask, audit_download: true,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
.and_return(true)
|
.and_return(true)
|
||||||
|
|
||||||
described_class.run("casktoken", "--download")
|
described_class.run("casktoken", "--download")
|
||||||
@ -52,7 +70,13 @@ describe Cask::Cmd::Audit, :cask do
|
|||||||
it "does not check for token conflicts per default" do
|
it "does not check for token conflicts per default" do
|
||||||
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
expect(Cask::Auditor).to receive(:audit)
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
.with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: false, quarantine: true)
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
.and_return(true)
|
.and_return(true)
|
||||||
|
|
||||||
described_class.run("casktoken")
|
described_class.run("casktoken")
|
||||||
@ -61,10 +85,112 @@ describe Cask::Cmd::Audit, :cask do
|
|||||||
it "checks for token conflicts if --token-conflicts flag is set" do
|
it "checks for token conflicts if --token-conflicts flag is set" do
|
||||||
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
expect(Cask::Auditor).to receive(:audit)
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
.with(cask, audit_download: false, audit_appcast: false, check_token_conflicts: true, quarantine: true)
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: true,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
.and_return(true)
|
.and_return(true)
|
||||||
|
|
||||||
described_class.run("casktoken", "--token-conflicts")
|
described_class.run("casktoken", "--token-conflicts")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "rules for checking strictly" do
|
||||||
|
it "does not check strictly per default" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "checks strictly if --strict flag is set" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: true,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: true,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken", "--strict")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rules for checking online" do
|
||||||
|
it "does not check online per default" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "checks online if --online flag is set" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: true,
|
||||||
|
audit_appcast: true,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: true,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken", "--online")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rules for checking new casks" do
|
||||||
|
it "does not check new casks per default" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: false,
|
||||||
|
audit_appcast: false,
|
||||||
|
audit_token_conflicts: false,
|
||||||
|
audit_new_cask: false,
|
||||||
|
audit_online: false,
|
||||||
|
audit_strict: false,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "checks new casks if --new-cask flag is set" do
|
||||||
|
allow(Cask::CaskLoader).to receive(:load).and_return(cask)
|
||||||
|
expect(Cask::Auditor).to receive(:audit)
|
||||||
|
.with(cask, audit_download: true,
|
||||||
|
audit_appcast: true,
|
||||||
|
audit_token_conflicts: true,
|
||||||
|
audit_new_cask: true,
|
||||||
|
audit_online: true,
|
||||||
|
audit_strict: true,
|
||||||
|
quarantine: true)
|
||||||
|
.and_return(true)
|
||||||
|
|
||||||
|
described_class.run("casktoken", "--new-cask")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
require_relative "shared_examples/requires_cask_token"
|
require_relative "shared_examples/requires_cask_token"
|
||||||
require_relative "shared_examples/invalid_option"
|
require_relative "shared_examples/invalid_option"
|
||||||
|
require "utils"
|
||||||
|
|
||||||
describe Cask::Cmd::Info, :cask do
|
describe Cask::Cmd::Info, :cask do
|
||||||
it_behaves_like "a command that requires a Cask token"
|
it_behaves_like "a command that requires a Cask token"
|
||||||
@ -139,7 +140,16 @@ describe Cask::Cmd::Info, :cask do
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can run be run with a url twice", :needs_network do
|
it "can run be run with a url twice and returns analytics", :needs_network do
|
||||||
|
analytics = {
|
||||||
|
"analytics" => {
|
||||||
|
"install" => {
|
||||||
|
"30d" => { "docker" => 1000 }, "90d" => { "docker" => 2000 }, "365d" => { "docker" => 3000 }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expect(Utils::Analytics).to receive(:formulae_brew_sh_json).twice.with("cask/docker.json")
|
||||||
|
.and_return(analytics)
|
||||||
expect {
|
expect {
|
||||||
described_class.run("https://raw.githubusercontent.com/Homebrew/homebrew-cask" \
|
described_class.run("https://raw.githubusercontent.com/Homebrew/homebrew-cask" \
|
||||||
"/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb")
|
"/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb")
|
||||||
@ -155,6 +165,8 @@ describe Cask::Cmd::Info, :cask do
|
|||||||
Docker CE
|
Docker CE
|
||||||
==> Artifacts
|
==> Artifacts
|
||||||
Docker.app (App)
|
Docker.app (App)
|
||||||
|
==> Analytics
|
||||||
|
install: 1,000 (30 days), 2,000 (90 days), 3,000 (365 days)
|
||||||
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb.
|
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb.
|
||||||
docker: 2.0.0.2-ce-mac81,30215 (auto_updates)
|
docker: 2.0.0.2-ce-mac81,30215 (auto_updates)
|
||||||
https://www.docker.com/community-edition
|
https://www.docker.com/community-edition
|
||||||
@ -164,6 +176,8 @@ describe Cask::Cmd::Info, :cask do
|
|||||||
Docker CE
|
Docker CE
|
||||||
==> Artifacts
|
==> Artifacts
|
||||||
Docker.app (App)
|
Docker.app (App)
|
||||||
|
==> Analytics
|
||||||
|
install: 1,000 (30 days), 2,000 (90 days), 3,000 (365 days)
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -9,7 +9,7 @@ end
|
|||||||
describe "brew --cache", :integration_test do
|
describe "brew --cache", :integration_test do
|
||||||
it "prints all cache files for a given Formula" do
|
it "prints all cache files for a given Formula" do
|
||||||
expect { brew "--cache", testball }
|
expect { brew "--cache", testball }
|
||||||
.to output(%r{#{HOMEBREW_CACHE}/downloads/[\da-f]{64}\-\-testball\-}).to_stdout
|
.to output(%r{#{HOMEBREW_CACHE}/downloads/[\da-f]{64}--testball-}).to_stdout
|
||||||
.and not_to_output.to_stderr
|
.and not_to_output.to_stderr
|
||||||
.and be_a_success
|
.and be_a_success
|
||||||
end
|
end
|
||||||
|
|||||||
@ -68,7 +68,7 @@ describe "brew install", :integration_test do
|
|||||||
# and there will be the git requirement, but we cannot instantiate git
|
# and there will be the git requirement, but we cannot instantiate git
|
||||||
# formula since we only have testball1 formula.
|
# formula since we only have testball1 formula.
|
||||||
expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" }
|
expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" }
|
||||||
.to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD\-d5eb689}).to_stdout
|
.to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689}).to_stdout
|
||||||
.and output(/Cloning into/).to_stderr
|
.and output(/Cloning into/).to_stderr
|
||||||
.and be_a_success
|
.and be_a_success
|
||||||
expect(HOMEBREW_CELLAR/"testball1/HEAD-d5eb689/foo/test").not_to be_a_file
|
expect(HOMEBREW_CELLAR/"testball1/HEAD-d5eb689/foo/test").not_to be_a_file
|
||||||
|
|||||||
@ -3,11 +3,12 @@
|
|||||||
shared_examples "parseable arguments" do
|
shared_examples "parseable arguments" do
|
||||||
subject(:method_name) do |example|
|
subject(:method_name) do |example|
|
||||||
example.metadata[:example_group][:parent_example_group][:description]
|
example.metadata[:example_group][:parent_example_group][:description]
|
||||||
.gsub(/^Homebrew\./, "")
|
.delete_prefix("Homebrew.")
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:command_name) do
|
let(:command_name) do
|
||||||
method_name.gsub(/_args$/, "").tr("_", "-")
|
method_name.delete_suffix("_args")
|
||||||
|
.tr("_", "-")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can parse arguments" do
|
it "can parse arguments" do
|
||||||
|
|||||||
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