Merge branch 'master' into mohammad
This commit is contained in:
commit
e058da1706
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -14,7 +14,7 @@ permissions:
|
||||
jobs:
|
||||
ubuntu:
|
||||
if: startsWith(github.repository, 'Homebrew/')
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
5
.github/workflows/sorbet.yml
vendored
5
.github/workflows/sorbet.yml
vendored
@ -46,12 +46,13 @@ jobs:
|
||||
if git ls-remote --exit-code --heads origin "${BRANCH}"
|
||||
then
|
||||
git checkout "${BRANCH}"
|
||||
git reset --hard origin/master
|
||||
git checkout "${GITHUB_WORKSPACE}/Library/Homebrew/sorbet"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
fi
|
||||
|
||||
if brew typecheck --update --fail-if-not-changed
|
||||
brew typecheck --update
|
||||
if ! git diff --stat --exit-code "${GITHUB_WORKSPACE}/Library/Homebrew/sorbet"
|
||||
then
|
||||
git add "${GITHUB_WORKSPACE}/Library/Homebrew/sorbet"
|
||||
git commit -m "sorbet: Update RBI files." \
|
||||
|
||||
9
.github/workflows/spdx.yml
vendored
9
.github/workflows/spdx.yml
vendored
@ -7,12 +7,15 @@ on:
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
spdx:
|
||||
if: github.repository == 'Homebrew/brew'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
@ -42,12 +45,12 @@ jobs:
|
||||
if git ls-remote --exit-code --heads origin "${BRANCH}"
|
||||
then
|
||||
git checkout "${BRANCH}"
|
||||
git reset --hard origin/master
|
||||
git checkout "${GITHUB_WORKSPACE}/Library/Homebrew/data/spdx"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
fi
|
||||
|
||||
if brew update-license-data --fail-if-not-changed
|
||||
if brew update-license-data
|
||||
then
|
||||
git add "${GITHUB_WORKSPACE}/Library/Homebrew/data/spdx"
|
||||
git commit -m "spdx: update license data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/master/.github/workflows/spdx.yml)."
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
name: Update maintainers, manpage and completions
|
||||
name: Update sponsors, maintainers, manpage and completions
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/update-man-completions.yml
|
||||
- .github/workflows/sponsors-maintainers-man-completions.yml
|
||||
- README.md
|
||||
- Library/Homebrew/cmd/**
|
||||
- Library/Homebrew/dev-cmd/**
|
||||
@ -12,8 +12,6 @@ on:
|
||||
- Library/Homebrew/cli/parser.rb
|
||||
- Library/Homebrew/completions.rb
|
||||
- Library/Homebrew/env_config.rb
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
@ -22,11 +20,12 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update-manpage:
|
||||
runs-on: ubuntu-latest
|
||||
updates:
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.repository == 'Homebrew/brew'
|
||||
steps:
|
||||
- name: Setup Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Configure Git user
|
||||
@ -39,35 +38,68 @@ jobs:
|
||||
with:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY }}
|
||||
|
||||
- name: Update maintainers, manpage and completions
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
restore-keys: ${{ runner.os }}-rubygems-
|
||||
|
||||
- name: Update sponsors, maintainers, manpage and completions
|
||||
id: update
|
||||
run: |
|
||||
git fetch origin
|
||||
|
||||
BRANCH=update-man-completions
|
||||
if [[ -n "$GITHUB_REF_NAME" && "$GITHUB_REF_NAME" != "master" ]]
|
||||
then
|
||||
BRANCH="$GITHUB_REF_NAME"
|
||||
else
|
||||
BRANCH=sponsors-maintainers-man-completions
|
||||
fi
|
||||
echo "::set-output name=branch::${BRANCH}"
|
||||
|
||||
if git ls-remote --exit-code --heads origin "${BRANCH}"
|
||||
then
|
||||
git checkout "${BRANCH}"
|
||||
git reset --hard origin/master
|
||||
git checkout "${GITHUB_WORKSPACE}/README.md" \
|
||||
"${GITHUB_WORKSPACE}/docs/Manpage.md" \
|
||||
"${GITHUB_WORKSPACE}/manpages/brew.1" \
|
||||
"${GITHUB_WORKSPACE}/completions"
|
||||
else
|
||||
git checkout --no-track -B "${BRANCH}" origin/master
|
||||
fi
|
||||
|
||||
if [[ "${{github.event_name}}" != "push" ]]
|
||||
if brew update-sponsors
|
||||
then
|
||||
brew update-maintainers
|
||||
git add "${GITHUB_WORKSPACE}/README.md"
|
||||
git commit -m "Update sponsors." \
|
||||
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
|
||||
COMMITTED=true
|
||||
fi
|
||||
|
||||
if brew generate-man-completions --fail-if-not-changed
|
||||
if brew update-maintainers
|
||||
then
|
||||
git add "${GITHUB_WORKSPACE}/README.md" \
|
||||
"${GITHUB_WORKSPACE}/docs/Manpage.md" \
|
||||
"${GITHUB_WORKSPACE}/manpages/brew.1"
|
||||
git commit -m "Update maintainers." \
|
||||
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
|
||||
COMMITTED=true
|
||||
fi
|
||||
|
||||
if brew generate-man-completions
|
||||
then
|
||||
git add "${GITHUB_WORKSPACE}/README.md" \
|
||||
"${GITHUB_WORKSPACE}/docs/Manpage.md" \
|
||||
"${GITHUB_WORKSPACE}/manpages/brew.1" \
|
||||
"${GITHUB_WORKSPACE}/completions"
|
||||
git commit -m "Update maintainers, manpage and completions." \
|
||||
-m "Autogenerated by the [update-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/update-man-completions.yml) workflow."
|
||||
git commit -m "Update manpage and completions." \
|
||||
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
|
||||
COMMITTED=true
|
||||
fi
|
||||
|
||||
if [[ -n "$COMMITTED" ]]
|
||||
then
|
||||
echo "::set-output name=committed::true"
|
||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||
@ -77,7 +109,7 @@ jobs:
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_BREW_UPDATE_MAINTAINERS_TOKEN }}
|
||||
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_BREW_UPDATE_SPONSORS_MAINTAINERS_TOKEN }}
|
||||
HOMEBREW_GPG_PASSPHRASE: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY_PASSPHRASE }}
|
||||
|
||||
- name: Push commits
|
||||
57
.github/workflows/tests.yml
vendored
57
.github/workflows/tests.yml
vendored
@ -20,7 +20,7 @@ concurrency:
|
||||
jobs:
|
||||
syntax:
|
||||
if: github.repository == 'Homebrew/brew'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
name: tap syntax (Linux)
|
||||
needs: syntax
|
||||
if: startsWith(github.repository, 'Homebrew/')
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
@ -82,13 +82,13 @@ jobs:
|
||||
brew update-test --commit=HEAD
|
||||
|
||||
- name: Run brew readall on all taps
|
||||
run: brew readall --aliases
|
||||
run: brew readall --eval-all --aliases
|
||||
|
||||
- name: Run brew style on homebrew-core for Linux
|
||||
run: brew style --display-cop-names homebrew/core
|
||||
|
||||
- name: Run brew audit --skip-style on all taps
|
||||
run: brew audit --skip-style --except=version --display-failures-only
|
||||
run: brew audit --eval-all --skip-style --except=version --display-failures-only
|
||||
|
||||
- name: Set up all Homebrew taps
|
||||
run: |
|
||||
@ -146,7 +146,7 @@ jobs:
|
||||
|
||||
vendored-gems:
|
||||
name: vendored gems (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
@ -167,31 +167,62 @@ jobs:
|
||||
|
||||
docker:
|
||||
needs: syntax
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
id: set-up-homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Build Docker image
|
||||
run: docker build -t brew --build-arg=version=16.04 .
|
||||
run: |
|
||||
docker build -t brew --build-arg=version=22.04 \
|
||||
--label org.opencontainers.image.created="$(date --rfc-3339=seconds --utc)" \
|
||||
--label org.opencontainers.image.url="https://brew.sh" \
|
||||
--label org.opencontainers.image.documentation="https://docs.brew.sh" \
|
||||
--label org.opencontainers.image.source="https://github.com/${GITHUB_REPOSITORY}" \
|
||||
--label org.opencontainers.image.revision="${GITHUB_SHA}" \
|
||||
--label org.opencontainers.image.vendor="${GITHUB_REPOSITORY_OWNER}" \
|
||||
--label org.opencontainers.image.licenses="BSD-2-Clause" \
|
||||
.
|
||||
|
||||
- name: Deploy the Docker image to GitHub Packages and Docker Hub
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
echo ${{secrets.HOMEBREW_BREW_GITHUB_PACKAGES_TOKEN}} |
|
||||
docker login ghcr.io -u BrewTestBot --password-stdin
|
||||
docker tag brew "ghcr.io/homebrew/ubuntu16.04:master"
|
||||
docker push "ghcr.io/homebrew/ubuntu16.04:master"
|
||||
docker tag brew "ghcr.io/homebrew/ubuntu22.04:master"
|
||||
docker push "ghcr.io/homebrew/ubuntu22.04:master"
|
||||
echo ${{secrets.HOMEBREW_BREW_DOCKER_TOKEN}} |
|
||||
docker login -u brewtestbot --password-stdin
|
||||
docker tag brew "homebrew/ubuntu16.04:master"
|
||||
docker tag brew "homebrew/ubuntu22.04:master"
|
||||
docker push "homebrew/ubuntu22.04:master"
|
||||
|
||||
- name: Build deprecated 16.04 Docker image
|
||||
run: |
|
||||
echo "homebrew/ubuntu16.04:master is deprecated and will soon be retired. Use homebrew/ubuntu22.04:master or homebrew/ubuntu16.04 or homebrew/brew. For CI, homebrew/ubuntu22.04:master is recommended." > .docker-deprecate
|
||||
docker build -t brew-deprecated --build-arg=version=16.04 \
|
||||
--label org.opencontainers.image.created="$(date --rfc-3339=seconds --utc)" \
|
||||
--label org.opencontainers.image.url="https://brew.sh" \
|
||||
--label org.opencontainers.image.documentation="https://docs.brew.sh" \
|
||||
--label org.opencontainers.image.source="https://github.com/${GITHUB_REPOSITORY}" \
|
||||
--label org.opencontainers.image.revision="${GITHUB_SHA}" \
|
||||
--label org.opencontainers.image.vendor="${GITHUB_REPOSITORY_OWNER}" \
|
||||
--label org.opencontainers.image.licenses="BSD-2-Clause" \
|
||||
--label org.opencontainers.image.support.end-of-support="2022-09-07T00:00:00Z" \
|
||||
.
|
||||
|
||||
- name: Deploy the deprecated 16.04 Docker image to GitHub Packages and Docker Hub
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
docker tag brew-deprecated "ghcr.io/homebrew/ubuntu16.04:master"
|
||||
docker push "ghcr.io/homebrew/ubuntu16.04:master"
|
||||
docker tag brew-deprecated "homebrew/ubuntu16.04:master"
|
||||
docker push "homebrew/ubuntu16.04:master"
|
||||
|
||||
tests:
|
||||
name: ${{ matrix.name }}
|
||||
needs: syntax
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@ -244,7 +275,7 @@ jobs:
|
||||
|
||||
test-default-formula-linux:
|
||||
name: test default formula (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
HOMEBREW_BOOTSNAP: 1
|
||||
steps:
|
||||
@ -301,7 +332,7 @@ jobs:
|
||||
Library/Taps/homebrew/homebrew-services
|
||||
|
||||
- name: Run brew readall on all taps
|
||||
run: brew readall --aliases
|
||||
run: brew readall --eval-all --aliases
|
||||
|
||||
- name: Install brew tests dependencies
|
||||
run: brew install subversion curl
|
||||
|
||||
6
.github/workflows/triage-issues.yml
vendored
6
.github/workflows/triage-issues.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
||||
contains(github.event.pull_request.labels.*.name, 'stale')
|
||||
)
|
||||
)
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Mark/Close Stale Issues and Pull Requests
|
||||
uses: actions/stale@v5
|
||||
@ -55,7 +55,7 @@ jobs:
|
||||
contains(github.event.pull_request.labels.*.name, 'stale')
|
||||
)
|
||||
)
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Mark/Close Stale `bump-formula-pr` and `bump-cask-pr` Pull Requests
|
||||
uses: actions/stale@v5
|
||||
@ -72,7 +72,7 @@ jobs:
|
||||
|
||||
lock-threads:
|
||||
if: startsWith(github.repository, 'Homebrew/') && github.event_name != 'issue_comment'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Lock Outdated Threads
|
||||
uses: dessant/lock-threads@e460dfeb36e731f3aeb214be6b0c9a9d9a67eda6
|
||||
|
||||
2
.github/workflows/triage.yml
vendored
2
.github/workflows/triage.yml
vendored
@ -18,7 +18,7 @@ concurrency: triage-${{ github.head_ref }}
|
||||
|
||||
jobs:
|
||||
review:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
if: startsWith(github.repository, 'Homebrew/')
|
||||
steps:
|
||||
- name: Re-run this workflow
|
||||
|
||||
14
.github/workflows/vendor-gems.yml
vendored
14
.github/workflows/vendor-gems.yml
vendored
@ -60,16 +60,12 @@ jobs:
|
||||
GEM_NAME: ${{ steps.checkout.outputs.gem_name }}
|
||||
HOMEBREW_GPG_PASSPHRASE: ${{ secrets.BREWTESTBOT_GPG_SIGNING_SUBKEY_PASSPHRASE }}
|
||||
run: |
|
||||
set -u
|
||||
|
||||
if brew typecheck --update --fail-if-not-changed
|
||||
brew typecheck --update
|
||||
if ! git diff --stat --exit-code "${GITHUB_WORKSPACE}/Library/Homebrew/sorbet"
|
||||
then
|
||||
if git add Library/Homebrew/sorbet
|
||||
then
|
||||
git commit -m "Update RBI files for ${GEM_NAME}."
|
||||
fi
|
||||
|
||||
git reset --hard
|
||||
git add "${GITHUB_WORKSPACE}/Library/Homebrew/sorbet"
|
||||
git commit -m "Update RBI files for ${GEM_NAME}." \
|
||||
-m "Autogenerated by the [vendor-gems](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/vendor-gemss.yml) workflow."
|
||||
fi
|
||||
|
||||
- name: Push to pull request
|
||||
|
||||
@ -21,6 +21,8 @@ RSpec/RepeatedDescription:
|
||||
Enabled: false
|
||||
RSpec/StubbedMock:
|
||||
Enabled: false
|
||||
RSpec/NoExpectationExample:
|
||||
Enabled: false
|
||||
|
||||
# TODO: try to reduce these
|
||||
RSpec/ExampleLength:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.1.6.1)
|
||||
activesupport (6.1.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
@ -58,7 +58,7 @@ GEM
|
||||
mime-types-data (3.2022.0105)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.16.3)
|
||||
msgpack (1.5.5)
|
||||
msgpack (1.5.6)
|
||||
mustache (1.1.1)
|
||||
net-http-digest_auth (1.4.1)
|
||||
net-http-persistent (4.0.1)
|
||||
@ -67,7 +67,7 @@ GEM
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
parallel (1.22.1)
|
||||
parallel_tests (3.11.1)
|
||||
parallel_tests (3.12.0)
|
||||
parallel
|
||||
parlour (8.0.0)
|
||||
commander (~> 4.5)
|
||||
@ -84,7 +84,7 @@ GEM
|
||||
method_source (~> 1.0)
|
||||
public_suffix (5.0.0)
|
||||
racc (1.6.0)
|
||||
rack (2.2.4)
|
||||
rack (3.0.0)
|
||||
rainbow (3.1.1)
|
||||
rbi (0.0.14)
|
||||
ast
|
||||
@ -104,7 +104,7 @@ GEM
|
||||
rspec-mocks (~> 3.11.0)
|
||||
rspec-core (3.11.0)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-expectations (3.11.0)
|
||||
rspec-expectations (3.11.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-github (2.3.1)
|
||||
@ -117,9 +117,9 @@ GEM
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-sorbet (1.8.3)
|
||||
rspec-sorbet (1.9.0)
|
||||
sorbet-runtime
|
||||
rspec-support (3.11.0)
|
||||
rspec-support (3.11.1)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
rspec_junit_formatter (0.5.1)
|
||||
@ -136,15 +136,15 @@ GEM
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.21.0)
|
||||
parser (>= 3.1.1.0)
|
||||
rubocop-performance (1.14.3)
|
||||
rubocop-performance (1.15.0)
|
||||
rubocop (>= 1.7.0, < 2.0)
|
||||
rubocop-ast (>= 0.4.0)
|
||||
rubocop-rails (2.15.2)
|
||||
rubocop-rails (2.16.0)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.7.0, < 2.0)
|
||||
rubocop-rspec (2.12.1)
|
||||
rubocop (~> 1.31)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
rubocop-rspec (2.13.1)
|
||||
rubocop (~> 1.33)
|
||||
rubocop-sorbet (0.6.11)
|
||||
rubocop (>= 0.90.0)
|
||||
ruby-macho (3.0.0)
|
||||
|
||||
@ -33,7 +33,7 @@ module Homebrew
|
||||
if cached_formula_json_file.exist? && !cached_formula_json_file.empty?
|
||||
curl_args.prepend("--time-cond", cached_formula_json_file)
|
||||
end
|
||||
curl_download(*curl_args, to: HOMEBREW_CACHE_API/"#{formula_api_path}.json", max_time: 5)
|
||||
curl_download(*curl_args, to: cached_formula_json_file, max_time: 5)
|
||||
|
||||
json_formulae = JSON.parse(cached_formula_json_file.read)
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ if ENV["HOMEBREW_STACKPROF"]
|
||||
end
|
||||
|
||||
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"]
|
||||
raise "#{__FILE__} must not be loaded via `require`." if $PROGRAM_NAME != __FILE__
|
||||
|
||||
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
|
||||
|
||||
@ -86,7 +87,8 @@ begin
|
||||
end
|
||||
|
||||
if internal_cmd || Commands.external_ruby_v2_cmd_path(cmd)
|
||||
if Commands::INSTALL_FROM_API_FORBIDDEN_COMMANDS.include?(cmd) && Homebrew::EnvConfig.install_from_api?
|
||||
if Commands::INSTALL_FROM_API_FORBIDDEN_COMMANDS.include?(cmd) &&
|
||||
Homebrew::EnvConfig.install_from_api? && !Homebrew::EnvConfig.developer?
|
||||
odie "This command cannot be run while HOMEBREW_INSTALL_FROM_API is set!"
|
||||
end
|
||||
|
||||
@ -120,8 +122,9 @@ begin
|
||||
# Unset HOMEBREW_HELP to avoid confusing the tap
|
||||
with_env HOMEBREW_HELP: nil do
|
||||
tap_commands = []
|
||||
cgroup = Utils.popen_read("cat", "/proc/1/cgroup")
|
||||
if %w[azpl_job actions_job docker garden kubepods].none? { |container| cgroup.include?(container) }
|
||||
if File.exist?("/.dockerenv") ||
|
||||
((cgroup = Utils.popen_read("cat", "/proc/1/cgroup").presence) &&
|
||||
%w[azpl_job actions_job docker garden kubepods].none? { |type| cgroup.include?(type) })
|
||||
brew_uid = HOMEBREW_BREW_FILE.stat.uid
|
||||
tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}] if Process.uid.zero? && !brew_uid.zero?
|
||||
end
|
||||
|
||||
@ -197,6 +197,7 @@ check-run-command-as-root() {
|
||||
[[ "$(id -u)" == 0 ]] || return
|
||||
|
||||
# Allow Azure Pipelines/GitHub Actions/Docker/Concourse/Kubernetes to do everything as root (as it's normal there)
|
||||
[[ -f /.dockerenv ]] && return
|
||||
[[ -f /proc/1/cgroup ]] && grep -E "azpl_job|actions_job|docker|garden|kubepods" -q /proc/1/cgroup && return
|
||||
|
||||
# Homebrew Services may need `sudo` for system-wide daemons.
|
||||
@ -358,6 +359,18 @@ fi
|
||||
##### Now, do everything else (that may be a bit slower).
|
||||
#####
|
||||
|
||||
# Docker image deprecation
|
||||
if [[ -f "${HOMEBREW_REPOSITORY}/.docker-deprecate" ]]
|
||||
then
|
||||
DOCKER_DEPRECATION_MESSAGE="$(cat "${HOMEBREW_REPOSITORY}/.docker-deprecate")"
|
||||
if [[ -n "${GITHUB_ACTIONS}" ]]
|
||||
then
|
||||
echo "::warning::${DOCKER_DEPRECATION_MESSAGE}" >&2
|
||||
else
|
||||
opoo "${DOCKER_DEPRECATION_MESSAGE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# USER isn't always set so provide a fall back for `brew` and subprocesses.
|
||||
export USER="${USER:-$(id -un)}"
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
# This script is loaded by formula_installer as a separate instance.
|
||||
# Thrown exceptions are propagated back to the parent process over a pipe
|
||||
|
||||
raise "#{__FILE__} must not be loaded via `require`." if $PROGRAM_NAME != __FILE__
|
||||
|
||||
old_trap = trap("INT") { exit! 130 }
|
||||
|
||||
require_relative "global"
|
||||
|
||||
@ -33,9 +33,17 @@ class BuildEnvironment
|
||||
module DSL
|
||||
extend T::Sig
|
||||
|
||||
# Initialise @env for each class which may use this DSL (e.g. each formula subclass).
|
||||
# `env` may never be called, and it needs to be initialised before the class is frozen.
|
||||
def inherited(child)
|
||||
super
|
||||
child.instance_eval do
|
||||
@env = BuildEnvironment.new
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(settings: Symbol).returns(BuildEnvironment) }
|
||||
def env(*settings)
|
||||
@env ||= BuildEnvironment.new
|
||||
@env.merge(settings)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "active_support/core_ext/object/deep_dup"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Abstract superclass for all artifacts.
|
||||
@ -127,8 +129,9 @@ module Cask
|
||||
|
||||
attr_reader :cask
|
||||
|
||||
def initialize(cask)
|
||||
def initialize(cask, *dsl_args)
|
||||
@cask = cask
|
||||
@dsl_args = dsl_args.deep_dup
|
||||
end
|
||||
|
||||
def config
|
||||
@ -139,6 +142,10 @@ module Cask
|
||||
def to_s
|
||||
"#{summarize} (#{self.class.english_name})"
|
||||
end
|
||||
|
||||
def to_args
|
||||
@dsl_args.reject(&:blank?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -32,6 +32,10 @@ module Cask
|
||||
abstract_phase(self.class.uninstall_dsl_key)
|
||||
end
|
||||
|
||||
def summarize
|
||||
directives.keys.map(&:to_s).join(", ")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def class_for_dsl_key(dsl_key)
|
||||
@ -44,10 +48,6 @@ module Cask
|
||||
|
||||
class_for_dsl_key(dsl_key).new(cask).instance_eval(&block)
|
||||
end
|
||||
|
||||
def summarize
|
||||
directives.keys.map(&:to_s).join(", ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -40,7 +40,7 @@ module Cask
|
||||
def initialize(cask, directives)
|
||||
directives.assert_valid_keys!(*ORDERED_DIRECTIVES)
|
||||
|
||||
super(cask)
|
||||
super(cask, **directives)
|
||||
directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a
|
||||
@directives = directives
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ module Cask
|
||||
attr_reader :path, :args
|
||||
|
||||
def initialize(cask, **args)
|
||||
super(cask)
|
||||
super(cask, **args)
|
||||
|
||||
if args.key?(:manual)
|
||||
@path = Pathname(args[:manual])
|
||||
|
||||
@ -23,7 +23,7 @@ module Cask
|
||||
end
|
||||
|
||||
def initialize(cask, path, **stanza_options)
|
||||
super(cask)
|
||||
super(cask, path, **stanza_options)
|
||||
@path = cask.staged_path.join(path)
|
||||
@stanza_options = stanza_options
|
||||
end
|
||||
|
||||
@ -42,12 +42,13 @@ module Cask
|
||||
attr_reader :source, :target
|
||||
|
||||
sig {
|
||||
params(cask: Cask, source: T.nilable(T.any(String, Pathname)), target: T.nilable(T.any(String, Pathname)))
|
||||
params(cask: Cask, source: T.nilable(T.any(String, Pathname)), target_hash: T.any(String, Pathname))
|
||||
.void
|
||||
}
|
||||
def initialize(cask, source, target: nil)
|
||||
super(cask)
|
||||
def initialize(cask, source, **target_hash)
|
||||
super(cask, source, **target_hash)
|
||||
|
||||
target = target_hash[:target]
|
||||
@source_string = source.to_s
|
||||
@target_string = target.to_s
|
||||
source = cask.staged_path.join(source)
|
||||
|
||||
@ -14,7 +14,7 @@ module Cask
|
||||
def self.from_args(cask, *args)
|
||||
raise CaskInvalidError.new(cask.token, "'stage_only' takes only a single argument: true") if args != [true]
|
||||
|
||||
new(cask)
|
||||
new(cask, true)
|
||||
end
|
||||
|
||||
sig { returns(T::Array[T::Boolean]) }
|
||||
|
||||
@ -581,7 +581,19 @@ module Cask
|
||||
next unless path.exist?
|
||||
|
||||
result = system_command("codesign", args: ["--verify", path], print_stderr: false)
|
||||
add_warning result.merged_output unless result.success?
|
||||
|
||||
next if result.success?
|
||||
|
||||
message = "Signature verification failed:\n#{result.merged_output}\nmacOS on ARM requires applications " \
|
||||
"to be signed. Please contact the upstream developer to let them know they should "
|
||||
|
||||
message += if result.stderr.include?("not signed at all")
|
||||
"sign their app."
|
||||
else
|
||||
"fix the signature of their app."
|
||||
end
|
||||
|
||||
add_warning message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -24,6 +24,11 @@ module Cask
|
||||
attr_accessor :download, :allow_reassignment
|
||||
|
||||
def self.all
|
||||
# TODO: uncomment for 3.7.0 and ideally avoid using ARGV by moving to e.g. CLI::Parser
|
||||
# if !ARGV.include?("--eval-all") && !Homebrew::EnvConfig.eval_all?
|
||||
# odeprecated "Cask::Cask#all without --all or HOMEBREW_EVAL_ALL"
|
||||
# end
|
||||
|
||||
Tap.flat_map(&:cask_files).map do |f|
|
||||
CaskLoader::FromTapPathLoader.new(f).load(config: nil)
|
||||
rescue CaskUnreadableError => e
|
||||
@ -235,7 +240,7 @@ module Cask
|
||||
"installed" => versions.last,
|
||||
"outdated" => outdated?,
|
||||
"sha256" => sha256,
|
||||
"artifacts" => artifacts.map(&method(:to_h_gsubs)),
|
||||
"artifacts" => artifacts_list,
|
||||
"caveats" => (to_h_string_gsubs(caveats) unless caveats.empty?),
|
||||
"depends_on" => depends_on,
|
||||
"conflicts_with" => conflicts_with,
|
||||
@ -281,6 +286,18 @@ module Cask
|
||||
|
||||
private
|
||||
|
||||
def artifacts_list
|
||||
artifacts.map do |artifact|
|
||||
key, value = if artifact.is_a? Artifact::AbstractFlightBlock
|
||||
artifact.summarize
|
||||
else
|
||||
[artifact.class.dsl_key, to_h_gsubs(artifact.to_args)]
|
||||
end
|
||||
|
||||
{ key => value }
|
||||
end
|
||||
end
|
||||
|
||||
def to_h_string_gsubs(string)
|
||||
string.to_s
|
||||
.gsub(Dir.home, "$HOME")
|
||||
|
||||
@ -1,8 +1,17 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "requirement"
|
||||
|
||||
# An adapter for casks to provide dependency information in a formula-like interface.
|
||||
class CaskDependent
|
||||
# Defines a dependency on another cask
|
||||
class Requirement < ::Requirement
|
||||
satisfy(build_env: false) do
|
||||
Cask::CaskLoader.load(cask).installed?
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :cask
|
||||
|
||||
def initialize(cask)
|
||||
@ -33,11 +42,21 @@ class CaskDependent
|
||||
dsl_reqs = @cask.depends_on
|
||||
|
||||
dsl_reqs.arch&.each do |arch|
|
||||
requirements << ArchRequirement.new([:x86_64]) if arch[:bits] == 64
|
||||
requirements << ArchRequirement.new([arch[:type]])
|
||||
arch = if arch[:bits] == 64
|
||||
if arch[:type] == :intel
|
||||
:x86_64
|
||||
else
|
||||
:"#{arch[:type]}64"
|
||||
end
|
||||
elsif arch[:type] == :intel && arch[:bits] == 32
|
||||
:i386
|
||||
else
|
||||
arch[:type]
|
||||
end
|
||||
requirements << ArchRequirement.new([arch])
|
||||
end
|
||||
dsl_reqs.cask.each do |cask_ref|
|
||||
requirements << Requirement.new([{ cask: cask_ref }])
|
||||
requirements << CaskDependent::Requirement.new([{ cask: cask_ref }])
|
||||
end
|
||||
requirements << dsl_reqs.macos if dsl_reqs.macos
|
||||
|
||||
|
||||
@ -235,6 +235,7 @@ module Homebrew
|
||||
cleanup_cache
|
||||
cleanup_logs
|
||||
cleanup_lockfiles
|
||||
cleanup_python_site_packages
|
||||
prune_prefix_symlinks_and_directories
|
||||
|
||||
unless dry_run?
|
||||
@ -484,6 +485,55 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_python_site_packages
|
||||
pyc_files = Hash.new { |h, k| h[k] = [] }
|
||||
seen_non_pyc_file = Hash.new { |h, k| h[k] = false }
|
||||
unused_pyc_files = []
|
||||
|
||||
HOMEBREW_PREFIX.glob("lib/python*/site-packages").each do |site_packages|
|
||||
site_packages.each_child do |child|
|
||||
next unless child.directory?
|
||||
# TODO: Work out a sensible way to clean up pip's, setuptools', and wheel's
|
||||
# {dist,site}-info directories. Alternatively, consider always removing
|
||||
# all `-info` directories, because we may not be making use of them.
|
||||
next if child.basename.to_s.end_with?("-info")
|
||||
|
||||
# Clean up old *.pyc files in the top-level __pycache__.
|
||||
if child.basename.to_s == "__pycache__"
|
||||
child.find do |path|
|
||||
next unless path.extname == ".pyc"
|
||||
next unless path.prune?(days)
|
||||
|
||||
unused_pyc_files << path
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
# Look for directories that contain only *.pyc files.
|
||||
child.find do |path|
|
||||
next if path.directory?
|
||||
|
||||
if path.extname == ".pyc"
|
||||
pyc_files[child] << path
|
||||
else
|
||||
seen_non_pyc_file[child] = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unused_pyc_files += pyc_files.reject { |k,| seen_non_pyc_file[k] }
|
||||
.values
|
||||
.flatten
|
||||
return if unused_pyc_files.blank?
|
||||
|
||||
unused_pyc_files.each do |pyc|
|
||||
cleanup_path(pyc) { pyc.unlink }
|
||||
end
|
||||
end
|
||||
|
||||
def prune_prefix_symlinks_and_directories
|
||||
ObserverPathnameExtension.reset_counts!
|
||||
|
||||
|
||||
@ -135,6 +135,9 @@ module Homebrew
|
||||
sig { returns(T::Boolean) }
|
||||
def all?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def eval_all?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def full?; end
|
||||
|
||||
|
||||
@ -22,10 +22,10 @@ module Homebrew
|
||||
may be appended to the command. When given multiple formula arguments,
|
||||
show the intersection of dependencies for each formula.
|
||||
EOS
|
||||
switch "-n",
|
||||
switch "-n", "--topological",
|
||||
description: "Sort dependencies in topological order."
|
||||
switch "--1",
|
||||
description: "Only show dependencies one level down, instead of recursing."
|
||||
switch "-1", "--direct", "--declared", "--1",
|
||||
description: "Show only the direct dependencies declared in the formula."
|
||||
switch "--union",
|
||||
description: "Show the union of dependencies for multiple <formula>, instead of the intersection."
|
||||
switch "--full-name",
|
||||
@ -54,20 +54,22 @@ module Homebrew
|
||||
switch "--installed",
|
||||
description: "List dependencies for formulae that are currently installed. If <formula> is " \
|
||||
"specified, list only its dependencies that are currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to list " \
|
||||
"their dependencies."
|
||||
switch "--all",
|
||||
description: "List dependencies for all available formulae."
|
||||
hidden: true
|
||||
switch "--for-each",
|
||||
description: "Switch into the mode used by the `--all` option, but only list dependencies " \
|
||||
"for each provided <formula>, one formula per line. This is used for " \
|
||||
"debugging the `--installed`/`--all` display mode."
|
||||
switch "--formula", "--formulae",
|
||||
depends_on: "--installed",
|
||||
description: "Treat all named arguments as formulae."
|
||||
switch "--cask", "--casks",
|
||||
depends_on: "--installed",
|
||||
description: "Treat all named arguments as casks."
|
||||
|
||||
conflicts "--tree", "--graph"
|
||||
conflicts "--installed", "--eval-all"
|
||||
conflicts "--installed", "--all"
|
||||
conflicts "--formula", "--cask"
|
||||
formula_options
|
||||
@ -79,9 +81,18 @@ module Homebrew
|
||||
def deps
|
||||
args = deps_args.parse
|
||||
|
||||
all = args.eval_all?
|
||||
if args.all?
|
||||
unless all
|
||||
odeprecated "brew deps --all",
|
||||
"brew deps --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
all = true
|
||||
end
|
||||
|
||||
Formulary.enable_factory_cache!
|
||||
|
||||
recursive = !args.send(:"1?")
|
||||
recursive = !args.direct?
|
||||
installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
|
||||
|
||||
@use_runtime_dependencies = installed && recursive &&
|
||||
@ -120,7 +131,7 @@ module Homebrew
|
||||
|
||||
puts_deps_tree dependents, recursive: recursive, args: args
|
||||
return
|
||||
elsif args.all?
|
||||
elsif all
|
||||
puts_deps sorted_dependents(Formula.all + Cask::Cask.all), recursive: recursive, args: args
|
||||
return
|
||||
elsif !args.no_named? && args.for_each?
|
||||
@ -149,7 +160,7 @@ module Homebrew
|
||||
condense_requirements(all_deps, args: args)
|
||||
all_deps.map! { |d| dep_display_name(d, args: args) }
|
||||
all_deps.uniq!
|
||||
all_deps.sort! unless args.n?
|
||||
all_deps.sort! unless args.topological?
|
||||
puts all_deps
|
||||
end
|
||||
|
||||
@ -286,8 +297,14 @@ module Homebrew
|
||||
end
|
||||
|
||||
display_s = "#{tree_lines} #{dep_display_name(dep, args: args)}"
|
||||
|
||||
# Detect circular dependencies and consider them a failure if present.
|
||||
is_circular = dep_stack.include?(dep.name)
|
||||
display_s = "#{display_s} (CIRCULAR DEPENDENCY)" if is_circular
|
||||
if is_circular
|
||||
display_s = "#{display_s} (CIRCULAR DEPENDENCY)"
|
||||
Homebrew.failed = true
|
||||
end
|
||||
|
||||
puts "#{prefix}#{display_s}"
|
||||
|
||||
next if !recursive || is_circular
|
||||
|
||||
@ -18,8 +18,7 @@ module Homebrew
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Display <formula>'s name and one-line description.
|
||||
Formula descriptions are cached; the cache is created on the
|
||||
first search, making that search slower than subsequent ones.
|
||||
The cache is created on the first search, making that search slower than subsequent ones.
|
||||
EOS
|
||||
switch "-s", "--search",
|
||||
description: "Search both names and descriptions for <text>. If <text> is flanked by " \
|
||||
@ -30,6 +29,9 @@ module Homebrew
|
||||
switch "-d", "--description",
|
||||
description: "Search just descriptions for <text>. If <text> is flanked by slashes, " \
|
||||
"it is interpreted as a regular expression."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
||||
"descriptions. Implied if HOMEBREW_EVAL_ALL is set."
|
||||
switch "--formula", "--formulae",
|
||||
description: "Treat all named arguments as formulae."
|
||||
switch "--cask", "--casks",
|
||||
@ -44,6 +46,10 @@ module Homebrew
|
||||
def desc
|
||||
args = desc_args.parse
|
||||
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew desc", "brew desc --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
|
||||
search_type = if args.search?
|
||||
:either
|
||||
elsif args.name?
|
||||
|
||||
24
Library/Homebrew/cmd/docs.rb
Normal file
24
Library/Homebrew/cmd/docs.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
module Homebrew
|
||||
extend T::Sig
|
||||
|
||||
module_function
|
||||
|
||||
sig { returns(CLI::Parser) }
|
||||
def docs_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Open Homebrew's online documentation (#{HOMEBREW_DOCS_WWW}) in a browser.
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def docs
|
||||
exec_browser HOMEBREW_DOCS_WWW
|
||||
end
|
||||
end
|
||||
@ -13,6 +13,8 @@ module Homebrew
|
||||
|
||||
module_function
|
||||
|
||||
FETCH_MAX_TRIES = 5
|
||||
|
||||
sig { returns(CLI::Parser) }
|
||||
def fetch_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
@ -31,7 +33,8 @@ module Homebrew
|
||||
"seeing if an existing VCS cache has been updated."
|
||||
switch "--retry",
|
||||
description: "Retry if downloading fails or re-download if the checksum of a previously cached " \
|
||||
"version no longer matches."
|
||||
"version no longer matches. Tries at most #{FETCH_MAX_TRIES} times with " \
|
||||
"exponential backoff."
|
||||
switch "--deps",
|
||||
description: "Also download dependencies for any listed <formula>."
|
||||
switch "-s", "--build-from-source",
|
||||
@ -159,10 +162,17 @@ module Homebrew
|
||||
end
|
||||
|
||||
def retry_fetch?(f, args:)
|
||||
@fetch_failed ||= Set.new
|
||||
if args.retry? && @fetch_failed.add?(f)
|
||||
ohai "Retrying download"
|
||||
@fetch_tries ||= Hash.new { |h, k| h[k] = 1 }
|
||||
if args.retry? && (@fetch_tries[f] < FETCH_MAX_TRIES)
|
||||
wait = 2 ** @fetch_tries[f]
|
||||
remaining = FETCH_MAX_TRIES - @fetch_tries[f]
|
||||
what = "try".pluralize(remaining)
|
||||
|
||||
ohai "Retrying download in #{wait}s... (#{remaining} #{what} left)"
|
||||
sleep wait
|
||||
|
||||
f.clear_cache
|
||||
@fetch_tries[f] += 1
|
||||
true
|
||||
else
|
||||
Homebrew.failed = true
|
||||
|
||||
@ -58,9 +58,13 @@ module Homebrew
|
||||
switch "--installed",
|
||||
depends_on: "--json",
|
||||
description: "Print JSON of formulae that are currently installed."
|
||||
switch "--all",
|
||||
switch "--eval-all",
|
||||
depends_on: "--json",
|
||||
description: "Print JSON of all available formulae."
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to print their " \
|
||||
"JSON. Implied if HOMEBREW_EVAL_ALL is set."
|
||||
switch "--all",
|
||||
hidden: true,
|
||||
depends_on: "--json"
|
||||
switch "--variations",
|
||||
depends_on: "--json",
|
||||
description: "Include the variations hash in each formula's JSON output."
|
||||
@ -71,6 +75,7 @@ module Homebrew
|
||||
switch "--cask", "--casks",
|
||||
description: "Treat all named arguments as casks."
|
||||
|
||||
conflicts "--installed", "--eval-all"
|
||||
conflicts "--installed", "--all"
|
||||
conflicts "--formula", "--cask"
|
||||
|
||||
@ -103,7 +108,13 @@ module Homebrew
|
||||
|
||||
print_analytics(args: args)
|
||||
elsif args.json
|
||||
print_json(args: args)
|
||||
all = args.eval_all?
|
||||
if !all && args.all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew info --all", "brew info --eval-all or HOMEBREW_EVAL_ALL"
|
||||
all = true
|
||||
end
|
||||
|
||||
print_json(all, args: args)
|
||||
elsif args.github?
|
||||
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
||||
|
||||
@ -187,15 +198,15 @@ module Homebrew
|
||||
version_hash[version]
|
||||
end
|
||||
|
||||
sig { params(args: CLI::Args).void }
|
||||
def print_json(args:)
|
||||
raise FormulaOrCaskUnspecifiedError if !(args.all? || args.installed?) && args.no_named?
|
||||
sig { params(all: T::Boolean, args: CLI::Args).void }
|
||||
def print_json(all, args:)
|
||||
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?
|
||||
|
||||
json = case json_version(args.json)
|
||||
when :v1, :default
|
||||
raise UsageError, "cannot specify --cask with --json=v1!" if args.cask?
|
||||
|
||||
formulae = if args.all?
|
||||
formulae = if all
|
||||
Formula.all.sort
|
||||
elsif args.installed?
|
||||
Formula.installed.sort
|
||||
@ -211,7 +222,7 @@ module Homebrew
|
||||
formulae.map(&:to_hash)
|
||||
end
|
||||
when :v2
|
||||
formulae, casks = if args.all?
|
||||
formulae, casks = if all
|
||||
[Formula.all.sort, Cask::Cask.all.sort_by(&:full_name)]
|
||||
elsif args.installed?
|
||||
[Formula.installed.sort, Cask::Caskroom.casks.sort_by(&:full_name)]
|
||||
|
||||
@ -19,8 +19,11 @@ module Homebrew
|
||||
description: "Show all options on a single line separated by spaces."
|
||||
switch "--installed",
|
||||
description: "Show options for formulae that are currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to show their " \
|
||||
"options."
|
||||
switch "--all",
|
||||
description: "Show options for all available formulae."
|
||||
hidden: true
|
||||
flag "--command=",
|
||||
description: "Show options for the specified <command>."
|
||||
|
||||
@ -33,7 +36,13 @@ module Homebrew
|
||||
def options
|
||||
args = options_args.parse
|
||||
|
||||
all = args.eval_all?
|
||||
if args.all?
|
||||
odeprecated "brew info --all", "brew info --eval-all" if !all && !Homebrew::EnvConfig.eval_all?
|
||||
all = true
|
||||
end
|
||||
|
||||
if all
|
||||
puts_options Formula.all.sort, args: args
|
||||
elsif args.installed?
|
||||
puts_options Formula.installed.sort, args: args
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
require "readall"
|
||||
require "cli/parser"
|
||||
require "env_config"
|
||||
|
||||
module Homebrew
|
||||
extend T::Sig
|
||||
@ -22,6 +23,9 @@ module Homebrew
|
||||
description: "Verify any alias symlinks in each tap."
|
||||
switch "--syntax",
|
||||
description: "Syntax-check all of Homebrew's Ruby files (if no `<tap>` is passed)."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not. " \
|
||||
"Implied if HOMEBREW_EVAL_ALL is set."
|
||||
|
||||
named_args :tap
|
||||
end
|
||||
@ -39,6 +43,9 @@ module Homebrew
|
||||
|
||||
options = { aliases: args.aliases? }
|
||||
taps = if args.no_named?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew readall", "brew readall --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
Tap
|
||||
else
|
||||
args.named.to_installed_taps
|
||||
|
||||
@ -44,6 +44,10 @@ module Homebrew
|
||||
switch "--desc",
|
||||
description: "Search for formulae with a description matching <text> and casks with " \
|
||||
"a name or description matching <text>."
|
||||
switch "--eval-all",
|
||||
depends_on: "--desc",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to search their " \
|
||||
"descriptions. Implied if HOMEBREW_EVAL_ALL is set."
|
||||
switch "--pull-request",
|
||||
description: "Search for GitHub pull requests containing <text>."
|
||||
switch "--open",
|
||||
@ -75,6 +79,9 @@ module Homebrew
|
||||
string_or_regex = query_regexp(query)
|
||||
|
||||
if args.desc?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew search --desc", "brew search --desc --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
search_descriptions(string_or_regex, args)
|
||||
elsif args.pull_request?
|
||||
search_pull_requests(query, args)
|
||||
|
||||
@ -43,6 +43,9 @@ module Homebrew
|
||||
description: "Migrate tapped formulae from symlink-based to directory-based structure."
|
||||
switch "--list-pinned",
|
||||
description: "List all pinned taps."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all the formulae, casks and aliases in the new tap to check validity. " \
|
||||
"Implied if HOMEBREW_EVAL_ALL is set."
|
||||
|
||||
named_args :tap, max: 2
|
||||
end
|
||||
@ -65,7 +68,8 @@ module Homebrew
|
||||
tap.install clone_target: args.named.second,
|
||||
force_auto_update: args.force_auto_update?,
|
||||
custom_remote: args.custom_remote?,
|
||||
quiet: args.quiet?
|
||||
quiet: args.quiet?,
|
||||
verify: args.eval_all? || Homebrew::EnvConfig.eval_all?
|
||||
rescue TapRemoteMismatchError, TapNoCustomRemoteError => e
|
||||
odie e
|
||||
rescue TapAlreadyTappedError
|
||||
|
||||
@ -547,7 +547,7 @@ EOS
|
||||
for DIR in "${HOMEBREW_REPOSITORY}" "${HOMEBREW_LIBRARY}"/Taps/*/*
|
||||
do
|
||||
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]] &&
|
||||
[[ -n "${HOMEBREW_UPDATE_AUTO}" ]] &&
|
||||
[[ -z "${HOMEBREW_DEVELOPER}" || -n "${HOMEBREW_UPDATE_AUTO}" ]] &&
|
||||
[[ "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" ]]
|
||||
then
|
||||
continue
|
||||
@ -705,6 +705,7 @@ EOS
|
||||
for DIR in "${HOMEBREW_REPOSITORY}" "${HOMEBREW_LIBRARY}"/Taps/*/*
|
||||
do
|
||||
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]] &&
|
||||
[[ -z "${HOMEBREW_DEVELOPER}" || -n "${HOMEBREW_UPDATE_AUTO}" ]] &&
|
||||
[[ "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" ||
|
||||
"${DIR}" == "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-cask" ]]
|
||||
then
|
||||
@ -748,11 +749,11 @@ EOS
|
||||
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]]
|
||||
then
|
||||
mkdir -p "${HOMEBREW_CACHE}/api"
|
||||
# TODO: use --header If-Modified-Since
|
||||
curl \
|
||||
"${CURL_DISABLE_CURLRC_ARGS[@]}" \
|
||||
--fail --compressed --silent --max-time 5 \
|
||||
--location --remote-time --output "${HOMEBREW_CACHE}/api/formula.json" \
|
||||
--time-cond "${HOMEBREW_CACHE}/api/formula.json" \
|
||||
--user-agent "${HOMEBREW_USER_AGENT_CURL}" \
|
||||
"https://formulae.brew.sh/api/formula.json"
|
||||
# TODO: we probably want to print an error if this fails.
|
||||
|
||||
@ -30,9 +30,11 @@ module Homebrew
|
||||
description: "Resolve more than one level of dependencies."
|
||||
switch "--installed",
|
||||
description: "Only list formulae and casks that are currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to show " \
|
||||
"their dependents."
|
||||
switch "--all",
|
||||
description: "List all formulae and casks whether installed or not.",
|
||||
hidden: true
|
||||
hidden: true
|
||||
switch "--include-build",
|
||||
description: "Include all formulae that specify <formula> as `:build` type dependency."
|
||||
switch "--include-test",
|
||||
@ -88,8 +90,6 @@ module Homebrew
|
||||
show_formulae_and_casks = !args.formula? && !args.cask?
|
||||
includes, ignores = args_includes_ignores(args)
|
||||
|
||||
# TODO: 3.6.0: odeprecate not specifying args.all?, require args.installed?
|
||||
|
||||
deps = []
|
||||
if use_runtime_dependents
|
||||
if show_formulae_and_casks || args.formula?
|
||||
@ -106,6 +106,18 @@ module Homebrew
|
||||
|
||||
deps
|
||||
else
|
||||
all = args.eval_all?
|
||||
if args.all?
|
||||
unless all
|
||||
odeprecated "brew uses --all",
|
||||
"brew uses --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
all = true
|
||||
end
|
||||
|
||||
if !args.installed? && !(all || Homebrew::EnvConfig.eval_all?)
|
||||
odeprecated "brew uses", "brew uses --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
if show_formulae_and_casks || args.formula?
|
||||
deps += args.installed? ? Formula.installed : Formula.all
|
||||
end
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "delegate"
|
||||
require "cask_dependent"
|
||||
|
||||
# A collection of dependencies.
|
||||
#
|
||||
|
||||
@ -26,16 +26,25 @@ class DependencyCollector
|
||||
|
||||
sig { void }
|
||||
def initialize
|
||||
# Ensure this is synced with `initialize_dup` and `freeze` (excluding simple objects like integers and booleans)
|
||||
@deps = Dependencies.new
|
||||
@requirements = Requirements.new
|
||||
|
||||
init_global_dep_tree_if_needed!
|
||||
end
|
||||
|
||||
def initialize_copy(other)
|
||||
def initialize_dup(other)
|
||||
super
|
||||
@deps = @deps.dup
|
||||
@requirements = @requirements.dup
|
||||
end
|
||||
|
||||
def freeze
|
||||
@deps.freeze
|
||||
@requirements.freeze
|
||||
super
|
||||
end
|
||||
|
||||
def add(spec)
|
||||
case dep = fetch(spec)
|
||||
when Dependency
|
||||
@ -68,6 +77,12 @@ class DependencyCollector
|
||||
parse_spec(spec, Array(tags))
|
||||
end
|
||||
|
||||
sig { params(related_formula_names: T::Array[String]).returns(T.nilable(Dependency)) }
|
||||
def gcc_dep_if_needed(related_formula_names); end
|
||||
|
||||
sig { params(related_formula_names: T::Array[String]).returns(T.nilable(Dependency)) }
|
||||
def glibc_dep_if_needed(related_formula_names); end
|
||||
|
||||
def git_dep_if_needed(tags)
|
||||
return if Utils::Git.available?
|
||||
|
||||
@ -110,6 +125,9 @@ class DependencyCollector
|
||||
|
||||
private
|
||||
|
||||
sig { void }
|
||||
def init_global_dep_tree_if_needed!; end
|
||||
|
||||
def parse_spec(spec, tags)
|
||||
case spec
|
||||
when String
|
||||
|
||||
@ -34,9 +34,9 @@ class DescriptionCacheStore < CacheStore
|
||||
#
|
||||
# @return [nil]
|
||||
def populate_if_empty!
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return unless database.empty?
|
||||
|
||||
# TODO: 3.6.0: consider if we want to actually read all contents of all formulae or odeprecate.
|
||||
Formula.all.each { |f| update!(f.full_name, f.desc) }
|
||||
end
|
||||
|
||||
@ -45,6 +45,7 @@ class DescriptionCacheStore < CacheStore
|
||||
# @param report [Report] an update report generated by cmd/update.rb
|
||||
# @return [nil]
|
||||
def update_from_report!(report)
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return populate_if_empty! if database.empty?
|
||||
return if report.empty?
|
||||
|
||||
@ -63,6 +64,7 @@ class DescriptionCacheStore < CacheStore
|
||||
# @param formula_names [Array] the formulae to update
|
||||
# @return [nil]
|
||||
def update_from_formula_names!(formula_names)
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return populate_if_empty! if database.empty?
|
||||
|
||||
formula_names.each do |name|
|
||||
@ -100,9 +102,9 @@ class CaskDescriptionCacheStore < DescriptionCacheStore
|
||||
#
|
||||
# @return [nil]
|
||||
def populate_if_empty!
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return unless database.empty?
|
||||
|
||||
# TODO: 3.6.0: consider if we want to actually read all contents of all casks or odeprecate.
|
||||
Cask::Cask.all.each { |c| update!(c.full_name, [c.name.join(", "), c.desc.presence]) }
|
||||
end
|
||||
|
||||
@ -111,6 +113,7 @@ class CaskDescriptionCacheStore < DescriptionCacheStore
|
||||
# @param report [Report] an update report generated by cmd/update.rb
|
||||
# @return [nil]
|
||||
def update_from_report!(report)
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return populate_if_empty! if database.empty?
|
||||
return if report.empty?
|
||||
|
||||
@ -126,6 +129,7 @@ class CaskDescriptionCacheStore < DescriptionCacheStore
|
||||
# @param cask_tokens [Array] the casks to update
|
||||
# @return [nil]
|
||||
def update_from_cask_tokens!(cask_tokens)
|
||||
return unless Homebrew::EnvConfig.eval_all?
|
||||
return populate_if_empty! if database.empty?
|
||||
|
||||
cask_tokens.each do |token|
|
||||
|
||||
@ -41,9 +41,11 @@ module Homebrew
|
||||
description: "Run additional, slower style checks that require a network connection."
|
||||
switch "--installed",
|
||||
description: "Only check formulae and casks that are currently installed."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to audit them. " \
|
||||
"Implied if HOMEBREW_EVAL_ALL is set."
|
||||
switch "--all",
|
||||
description: "Check all formulae and casks whether installed or not.",
|
||||
hidden: true
|
||||
hidden: true
|
||||
switch "--new", "--new-formula", "--new-cask",
|
||||
description: "Run various additional style checks to determine if a new formula or cask is eligible " \
|
||||
"for Homebrew. This should be used when creating new formula and implies " \
|
||||
@ -118,8 +120,6 @@ module Homebrew
|
||||
ENV.activate_extensions!
|
||||
ENV.setup_build_environment
|
||||
|
||||
# TODO: 3.6.0: odeprecate not specifying args.all?, require args.installed?
|
||||
|
||||
audit_formulae, audit_casks = if args.tap
|
||||
Tap.fetch(args.tap).then do |tap|
|
||||
[
|
||||
@ -131,6 +131,10 @@ module Homebrew
|
||||
no_named_args = true
|
||||
[Formula.installed, Cask::Caskroom.casks]
|
||||
elsif args.no_named?
|
||||
if !args.eval_all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew audit",
|
||||
"brew audit --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
no_named_args = true
|
||||
[Formula.all, Cask::Cask.all]
|
||||
else
|
||||
|
||||
@ -121,8 +121,8 @@ module Homebrew
|
||||
if new_version.present?
|
||||
if new_version.latest?
|
||||
opoo "Ignoring specified `--sha256=` argument." if new_hash.present?
|
||||
new_hash = :no_check
|
||||
elsif new_hash.nil? || cask.languages.present?
|
||||
replacement_pairs << [old_hash, ":no_check"]
|
||||
elsif old_hash != :no_check && (new_hash.nil? || cask.languages.present?)
|
||||
tmp_contents = Utils::Inreplace.inreplace_pairs(cask.sourcefile_path,
|
||||
replacement_pairs.uniq.compact,
|
||||
read_only_run: true,
|
||||
@ -131,43 +131,34 @@ module Homebrew
|
||||
tmp_cask = Cask::CaskLoader.load(tmp_contents)
|
||||
tmp_config = tmp_cask.config
|
||||
|
||||
new_hash = fetch_cask(tmp_contents)[1] if old_hash != :no_check && new_hash.nil?
|
||||
[:arm, :intel].each do |arch|
|
||||
Homebrew::SimulateSystem.arch = arch
|
||||
|
||||
cask.languages.each do |language|
|
||||
lang_config = tmp_config.merge(Cask::Config.new(explicit: { languages: [language] }))
|
||||
replacement_pairs << fetch_cask(tmp_contents, config: lang_config)
|
||||
end
|
||||
languages = cask.languages
|
||||
languages = [nil] if languages.empty?
|
||||
languages.each do |language|
|
||||
new_hash_config = if language.blank?
|
||||
tmp_config
|
||||
else
|
||||
tmp_config.merge(Cask::Config.new(explicit: { languages: [language] }))
|
||||
end
|
||||
|
||||
# TODO: remove the `Hardware::CPU.intel?` substitution once no casks use the conditional
|
||||
other_intel = !Hardware::CPU.intel?
|
||||
Homebrew::SimulateSystem.arch = other_intel ? :intel : :arm
|
||||
other_contents = tmp_contents.gsub("Hardware::CPU.intel?", other_intel.to_s)
|
||||
other_cask = Cask::CaskLoader.load(other_contents)
|
||||
new_hash_cask = Cask::CaskLoader.load(tmp_contents)
|
||||
new_hash_cask.config = new_hash_config
|
||||
old_hash = new_hash_cask.sha256.to_s
|
||||
|
||||
if other_cask.url.to_s != tmp_cask.url.to_s
|
||||
if other_cask.sha256 != :no_check && other_cask.language.blank?
|
||||
replacement_pairs << fetch_cask(other_contents)
|
||||
cask_download = Cask::Download.new(new_hash_cask, quarantine: true)
|
||||
download = cask_download.fetch(verify_download_integrity: false)
|
||||
Utils::Tar.validate_file(download)
|
||||
|
||||
replacement_pairs << [new_hash_cask.sha256.to_s, download.sha256]
|
||||
end
|
||||
|
||||
other_cask.languages.each do |language|
|
||||
lang_config = other_cask.config.merge(Cask::Config.new(explicit: { languages: [language] }))
|
||||
replacement_pairs << fetch_cask(other_contents, config: lang_config)
|
||||
end
|
||||
Homebrew::SimulateSystem.clear
|
||||
end
|
||||
|
||||
Homebrew::SimulateSystem.clear
|
||||
end
|
||||
end
|
||||
|
||||
if new_hash.present? && cask.language.blank? # avoid repeated replacement for multilanguage cask
|
||||
hash_regex = (old_hash == :no_check) ? ":no_check" : "[\"']#{Regexp.escape(old_hash.to_s)}[\"']"
|
||||
|
||||
replacement_pairs << [
|
||||
/#{hash_regex}/m,
|
||||
((new_hash == :no_check) ? ":no_check" : "\"#{new_hash}\"").to_s,
|
||||
]
|
||||
end
|
||||
|
||||
Utils::Inreplace.inreplace_pairs(cask.sourcefile_path,
|
||||
replacement_pairs.uniq.compact,
|
||||
read_only_run: args.dry_run?,
|
||||
|
||||
@ -18,8 +18,8 @@ module Homebrew
|
||||
Create a pull request to update <formula> with a new URL or a new tag.
|
||||
|
||||
If a <URL> is specified, the <SHA-256> checksum of the new download should also
|
||||
be specified. A best effort to determine the <SHA-256> and <formula> name will
|
||||
be made if either or both values are not supplied by the user.
|
||||
be specified. A best effort to determine the <SHA-256> will be made if not supplied
|
||||
by the user.
|
||||
|
||||
If a <tag> is specified, the Git commit <revision> corresponding to that tag
|
||||
should also be specified. A best effort to determine the <revision> will be made
|
||||
@ -34,9 +34,6 @@ module Homebrew
|
||||
EOS
|
||||
switch "-n", "--dry-run",
|
||||
description: "Print what would be done rather than doing it."
|
||||
switch "--all",
|
||||
description: "Read all formulae if necessary to determine URL.",
|
||||
hidden: true
|
||||
switch "--write-only",
|
||||
description: "Make the expected file modifications without taking any Git actions."
|
||||
switch "--commit",
|
||||
@ -89,7 +86,6 @@ module Homebrew
|
||||
conflicts "--no-audit", "--strict"
|
||||
conflicts "--no-audit", "--online"
|
||||
conflicts "--url", "--tag"
|
||||
conflicts "--installed", "--all"
|
||||
|
||||
named_args :formula, max: 1
|
||||
end
|
||||
@ -110,9 +106,7 @@ module Homebrew
|
||||
ENV["BROWSER"] = Homebrew::EnvConfig.browser
|
||||
|
||||
formula = args.named.to_formulae.first
|
||||
|
||||
new_url = args.url
|
||||
formula ||= determine_formula_from_url(new_url) if new_url.present?
|
||||
raise FormulaUnspecifiedError if formula.blank?
|
||||
|
||||
odie "This formula is disabled!" if formula.disabled?
|
||||
@ -368,27 +362,6 @@ module Homebrew
|
||||
GitHub.create_bump_pr(pr_info, args: args)
|
||||
end
|
||||
|
||||
def determine_formula_from_url(url)
|
||||
# Split the new URL on / and find any formulae that have the same URL
|
||||
# except for the last component, but don't try to match any more than the
|
||||
# first five components since sometimes the last component isn't the only
|
||||
# one to change.
|
||||
url_split = url.split("/")
|
||||
maximum_url_components_to_match = 5
|
||||
components_to_match = [url_split.count - 1, maximum_url_components_to_match].min
|
||||
base_url = url_split.first(components_to_match).join("/")
|
||||
base_url = /#{Regexp.escape(base_url)}/
|
||||
guesses = []
|
||||
# TODO: 3.6.0: odeprecate not specifying args.all?
|
||||
Formula.all.each do |f|
|
||||
guesses << f if f.stable&.url&.match(base_url)
|
||||
end
|
||||
return guesses.shift if guesses.count == 1
|
||||
return if guesses.count <= 1
|
||||
|
||||
odie "Couldn't guess formula for sure; could be one of these:\n#{guesses.map(&:name).join(", ")}"
|
||||
end
|
||||
|
||||
def determine_mirror(url)
|
||||
case url
|
||||
when %r{.*ftp\.gnu\.org/gnu.*}
|
||||
|
||||
@ -23,6 +23,7 @@ module Homebrew
|
||||
Generate Homebrew's manpages and shell completions.
|
||||
EOS
|
||||
switch "--fail-if-not-changed",
|
||||
hidden: true,
|
||||
description: "Return a failing status code if no changes are detected in the manpage outputs. " \
|
||||
"This can be used to notify CI when the manpages are out of date. Additionally, " \
|
||||
"the date used in new manpages will match those in the existing manpages (to allow " \
|
||||
@ -34,27 +35,30 @@ module Homebrew
|
||||
def generate_man_completions
|
||||
args = generate_man_completions_args.parse
|
||||
|
||||
odeprecated "brew generate-man-completions --fail-if-not-changed" if args.fail_if_not_changed?
|
||||
|
||||
Commands.rebuild_internal_commands_completion_list
|
||||
regenerate_man_pages(preserve_date: args.fail_if_not_changed?, quiet: args.quiet?)
|
||||
regenerate_man_pages(quiet: args.quiet?)
|
||||
Completions.update_shell_completions!
|
||||
|
||||
diff = system_command "git", args: [
|
||||
"-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", "docs/Manpage.md", "manpages", "completions"
|
||||
]
|
||||
|
||||
return unless diff.status.success?
|
||||
|
||||
puts "No changes to manpage or completions output detected."
|
||||
Homebrew.failed = true if args.fail_if_not_changed?
|
||||
if diff.status.success?
|
||||
ofail "No changes to manpage or completions."
|
||||
else
|
||||
puts "Manpage and completions updated."
|
||||
end
|
||||
end
|
||||
|
||||
def regenerate_man_pages(preserve_date:, quiet:)
|
||||
# TODO: move this method and all called functions to manpages.rb
|
||||
def regenerate_man_pages(quiet:)
|
||||
Homebrew.install_bundler_gems!
|
||||
|
||||
markup = build_man_page(quiet: quiet)
|
||||
convert_man_page(markup, TARGET_DOC_PATH/"Manpage.md", preserve_date: preserve_date)
|
||||
convert_man_page(markup, TARGET_DOC_PATH/"Manpage.md")
|
||||
markup = I18n.transliterate(markup, locale: :en)
|
||||
convert_man_page(markup, TARGET_MAN_PATH/"brew.1", preserve_date: preserve_date)
|
||||
convert_man_page(markup, TARGET_MAN_PATH/"brew.1")
|
||||
end
|
||||
|
||||
def build_man_page(quiet:)
|
||||
@ -94,13 +98,13 @@ module Homebrew
|
||||
path.basename.to_s.sub(/\.(rb|sh)$/, "").sub(/^--/, "~~")
|
||||
end
|
||||
|
||||
def convert_man_page(markup, target, preserve_date:)
|
||||
def convert_man_page(markup, target)
|
||||
manual = target.basename(".1")
|
||||
organisation = "Homebrew"
|
||||
|
||||
# Set the manpage date to the existing one if we're checking for changes.
|
||||
# Set the manpage date to the existing one if we're updating.
|
||||
# This avoids the only change being e.g. a new date.
|
||||
date = if preserve_date && target.extname == ".1" && target.exist?
|
||||
date = if target.extname == ".1" && target.exist?
|
||||
/"(\d{1,2})" "([A-Z][a-z]+) (\d{4})" "#{organisation}" "#{manual}"/ =~ target.read
|
||||
Date.parse("#{Regexp.last_match(1)} #{Regexp.last_match(2)} #{Regexp.last_match(3)}")
|
||||
else
|
||||
|
||||
@ -24,13 +24,15 @@ module Homebrew
|
||||
`~/.brew_livecheck_watchlist`.
|
||||
EOS
|
||||
switch "--full-name",
|
||||
description: "Print formulae/casks with fully-qualified names."
|
||||
description: "Print formulae and casks with fully-qualified names."
|
||||
flag "--tap=",
|
||||
description: "Check formulae/casks within the given tap, specified as <user>`/`<repo>."
|
||||
description: "Check formulae and casks within the given tap, specified as <user>`/`<repo>."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to check them."
|
||||
switch "--all",
|
||||
description: "Check all available formulae/casks."
|
||||
hidden: true
|
||||
switch "--installed",
|
||||
description: "Check formulae/casks that are currently installed."
|
||||
description: "Check formulae and casks that are currently installed."
|
||||
switch "--newer-only",
|
||||
description: "Show the latest version only if it's newer than the formula/cask."
|
||||
switch "--json",
|
||||
@ -45,7 +47,7 @@ module Homebrew
|
||||
description: "Only check casks."
|
||||
|
||||
conflicts "--debug", "--json"
|
||||
conflicts "--tap=", "--all", "--installed"
|
||||
conflicts "--tap=", "--eval-all", "--installed"
|
||||
conflicts "--cask", "--formula"
|
||||
|
||||
named_args [:formula, :cask]
|
||||
@ -55,6 +57,12 @@ module Homebrew
|
||||
def livecheck
|
||||
args = livecheck_args.parse
|
||||
|
||||
all = args.eval_all?
|
||||
if args.all?
|
||||
odeprecated "brew livecheck --all", "brew livecheck --eval-all" if !all && !Homebrew::EnvConfig.eval_all?
|
||||
all = true
|
||||
end
|
||||
|
||||
if args.debug? && args.verbose?
|
||||
puts args
|
||||
puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present?
|
||||
@ -69,7 +77,7 @@ module Homebrew
|
||||
formulae = args.cask? ? [] : Formula.installed
|
||||
casks = args.formula? ? [] : Cask::Caskroom.casks
|
||||
formulae + casks
|
||||
elsif args.all?
|
||||
elsif all
|
||||
formulae = args.cask? ? [] : Formula.all
|
||||
casks = args.formula? ? [] : Cask::Cask.all
|
||||
formulae + casks
|
||||
|
||||
@ -368,28 +368,32 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def pr_check_conflicts(user, repo, pr)
|
||||
long_build_pr_files = GitHub.search_issues(
|
||||
"org:#{user}", repo: repo, state: "open", label: "\"no long build conflict\""
|
||||
def pr_check_conflicts(repo, pr)
|
||||
long_build_pr_files = GitHub.issues(
|
||||
repo: repo, state: "open", labels: "no long build conflict",
|
||||
).each_with_object({}) do |long_build_pr, hash|
|
||||
next unless long_build_pr.key?("pull_request")
|
||||
|
||||
number = long_build_pr["number"]
|
||||
next if number == pr.to_i
|
||||
|
||||
GitHub.get_pull_request_changed_files("#{user}/#{repo}", number).each do |file|
|
||||
GitHub.get_pull_request_changed_files(repo, number).each do |file|
|
||||
key = file["filename"]
|
||||
hash[key] ||= []
|
||||
hash[key] << number
|
||||
end
|
||||
end
|
||||
|
||||
this_pr_files = GitHub.get_pull_request_changed_files("#{user}/#{repo}", pr)
|
||||
return if long_build_pr_files.blank?
|
||||
|
||||
this_pr_files = GitHub.get_pull_request_changed_files(repo, pr)
|
||||
|
||||
conflicts = this_pr_files.each_with_object({}) do |file, hash|
|
||||
filename = file["filename"]
|
||||
next unless long_build_pr_files.key?(filename)
|
||||
|
||||
long_build_pr_files[filename].each do |pr_number|
|
||||
key = "#{user}/#{repo}/pull/#{pr_number}"
|
||||
key = "#{repo}/pull/#{pr_number}"
|
||||
hash[key] ||= []
|
||||
hash[key] << filename
|
||||
end
|
||||
@ -440,7 +444,7 @@ module Homebrew
|
||||
opoo "Current branch is #{tap.path.git_branch}: do you need to pull inside #{tap.path.git_origin_branch}?"
|
||||
end
|
||||
|
||||
pr_check_conflicts(user, repo, pr)
|
||||
pr_check_conflicts("#{user}/#{repo}", pr)
|
||||
|
||||
ohai "Fetching #{tap} pull request ##{pr}"
|
||||
Dir.mktmpdir pr do |dir|
|
||||
|
||||
@ -20,13 +20,13 @@ module Homebrew
|
||||
description: "Silence all non-critical errors."
|
||||
switch "--update",
|
||||
description: "Update RBI files."
|
||||
switch "--all",
|
||||
depends_on: "--update",
|
||||
description: "Regenerate all RBI files rather than just updated gems."
|
||||
switch "--update-all",
|
||||
description: "Update all RBI files rather than just updated gems."
|
||||
switch "--suggest-typed",
|
||||
depends_on: "--update",
|
||||
description: "Try upgrading `typed` sigils."
|
||||
switch "--fail-if-not-changed",
|
||||
hidden: true,
|
||||
description: "Return a failing status code if all gems are up to date " \
|
||||
"and gem definitions do not need a tapioca update."
|
||||
flag "--dir=",
|
||||
@ -50,7 +50,9 @@ module Homebrew
|
||||
Homebrew.install_bundler_gems!(groups: ["sorbet"])
|
||||
|
||||
HOMEBREW_LIBRARY_PATH.cd do
|
||||
if args.update?
|
||||
if args.update? || args.update_all?
|
||||
odeprecated "brew typecheck --update --fail-if-not-changed" if args.fail_if_not_changed?
|
||||
|
||||
excluded_gems = [
|
||||
"did_you_mean", # RBI file is already provided by Sorbet
|
||||
"webrobots", # RBI file is bugged
|
||||
@ -60,7 +62,7 @@ module Homebrew
|
||||
"msgpack:false", # Investigate removing this with Tapioca 0.8
|
||||
]
|
||||
tapioca_args = ["--exclude", *excluded_gems, "--typed-overrides", *typed_overrides]
|
||||
tapioca_args << "--all" if args.all?
|
||||
tapioca_args << "--all" if args.update_all?
|
||||
|
||||
ohai "Updating Tapioca RBI files..."
|
||||
safe_system "bundle", "exec", "tapioca", "gem", *tapioca_args
|
||||
@ -100,8 +102,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
Homebrew.failed = system("git", "diff", "--stat", "--exit-code") if args.fail_if_not_changed?
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@ -20,11 +20,13 @@ module Homebrew
|
||||
description: "Use the specified bottle tag (e.g. `big_sur`) instead of the current OS."
|
||||
switch "--dependents",
|
||||
description: "Skip getting analytics data and sort by number of dependents instead."
|
||||
switch "--all", "--total",
|
||||
switch "--total",
|
||||
description: "Print the number of unbottled and total formulae."
|
||||
switch "--eval-all",
|
||||
description: "Evaluate all available formulae and casks, whether installed or not, to check them. " \
|
||||
"Implied if HOMEBREW_EVAL_ALL is set."
|
||||
|
||||
conflicts "--dependents", "--all"
|
||||
conflicts "--installed", "--all"
|
||||
conflicts "--dependents", "--total"
|
||||
|
||||
named_args :formula
|
||||
end
|
||||
@ -42,16 +44,22 @@ module Homebrew
|
||||
Utils::Bottles.tag
|
||||
end
|
||||
|
||||
# TODO: 3.6.0: odeprecate args.total?
|
||||
all = args.eval_all?
|
||||
if args.total?
|
||||
if !all && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew unbottled --total", "brew unbottled --total --eval-all or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
all = true
|
||||
end
|
||||
|
||||
if args.named.blank?
|
||||
ohai "Getting formulae..."
|
||||
elsif args.all?
|
||||
raise UsageError, "cannot specify `<formula>` and `--all`/`--total`."
|
||||
elsif all
|
||||
raise UsageError, "cannot specify `<formula>` and `--eval-all`/`--total`."
|
||||
end
|
||||
|
||||
formulae, all_formulae, formula_installs =
|
||||
formulae_all_installs_from_args(args)
|
||||
formulae_all_installs_from_args(args, all)
|
||||
deps_hash, uses_hash = deps_uses_from_formulae(all_formulae)
|
||||
|
||||
if args.dependents?
|
||||
@ -60,9 +68,7 @@ module Homebrew
|
||||
dependents = uses_hash[f.name]&.length || 0
|
||||
formula_dependents[f.name] ||= dependents
|
||||
end.reverse
|
||||
end
|
||||
|
||||
if args.all?
|
||||
elsif all
|
||||
output_total(formulae)
|
||||
return
|
||||
end
|
||||
@ -78,16 +84,18 @@ module Homebrew
|
||||
output_unbottled(formulae, deps_hash, noun, hash, args.named.present?)
|
||||
end
|
||||
|
||||
def formulae_all_installs_from_args(args)
|
||||
def formulae_all_installs_from_args(args, all)
|
||||
if args.named.present?
|
||||
formulae = all_formulae = args.named.to_formulae
|
||||
elsif args.all?
|
||||
formulae = all_formulae = Formula.all
|
||||
elsif args.dependents?
|
||||
# TODO: 3.6.0: odeprecate not specifying args.all? for args.dependents?
|
||||
if !args.all? && !Homebrew::EnvConfig.eval_all?
|
||||
odeprecated "brew unbottled --dependents", "brew unbottled --all --dependents or HOMEBREW_EVAL_ALL"
|
||||
end
|
||||
formulae = all_formulae = Formula.all
|
||||
|
||||
@sort = " (sorted by number of dependents)"
|
||||
elsif all
|
||||
formulae = all_formulae = Formula.all
|
||||
else
|
||||
formula_installs = {}
|
||||
|
||||
|
||||
@ -3,9 +3,11 @@
|
||||
|
||||
require "cli/parser"
|
||||
require "utils/spdx"
|
||||
require "system_command"
|
||||
|
||||
module Homebrew
|
||||
extend T::Sig
|
||||
include SystemCommand::Mixin
|
||||
|
||||
module_function
|
||||
|
||||
@ -16,6 +18,7 @@ module Homebrew
|
||||
Update SPDX license data in the Homebrew repository.
|
||||
EOS
|
||||
switch "--fail-if-not-changed",
|
||||
hidden: true,
|
||||
description: "Return a failing status code if current license data's version is the same as " \
|
||||
"the upstream. This can be used to notify CI when the SPDX license data is out of date."
|
||||
|
||||
@ -25,11 +28,16 @@ module Homebrew
|
||||
|
||||
def update_license_data
|
||||
args = update_license_data_args.parse
|
||||
ohai "Updating SPDX license data..."
|
||||
odeprecated "brew update-license-data --fail-if-not-changed" if args.fail_if_not_changed?
|
||||
|
||||
SPDX.download_latest_license_data!
|
||||
return unless args.fail_if_not_changed?
|
||||
|
||||
Homebrew.failed = system("git", "diff", "--stat", "--exit-code", SPDX::DATA_PATH)
|
||||
diff = system_command "git", args: [
|
||||
"-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", SPDX::DATA_PATH
|
||||
]
|
||||
if diff.status.success?
|
||||
ofail "No changes to SPDX license data."
|
||||
else
|
||||
puts "SPDX license data updated."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
|
||||
require "cli/parser"
|
||||
require "utils/github"
|
||||
|
||||
# TODO: move function to manpages.rb and require that instead
|
||||
require "dev-cmd/generate-man-completions"
|
||||
|
||||
module Homebrew
|
||||
@ -57,9 +59,10 @@ module Homebrew
|
||||
"-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", "README.md"
|
||||
]
|
||||
if diff.status.success?
|
||||
puts "No changes to list of maintainers."
|
||||
ofail "No changes to list of maintainers."
|
||||
else
|
||||
Homebrew.regenerate_man_pages(preserve_date: true, quiet: true)
|
||||
# TODO: move function to manpages.rb and call that instead
|
||||
Homebrew.regenerate_man_pages(quiet: true)
|
||||
puts "List of maintainers updated in the README and the generated man pages."
|
||||
end
|
||||
end
|
||||
|
||||
@ -9,11 +9,11 @@ module Homebrew
|
||||
|
||||
module_function
|
||||
|
||||
NAMED_TIER_AMOUNT = 100
|
||||
URL_TIER_AMOUNT = 1000
|
||||
NAMED_MONTHLY_AMOUNT = 100
|
||||
URL_MONTHLY_AMOUNT = 1000
|
||||
|
||||
sig { returns(CLI::Parser) }
|
||||
def sponsors_args
|
||||
def update_sponsors_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Update the list of GitHub Sponsors in the `Homebrew/brew` README.
|
||||
@ -23,38 +23,36 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def sponsor_name(s)
|
||||
s["name"] || s["login"]
|
||||
def sponsor_name(sponsor)
|
||||
sponsor[:name] || sponsor[:login]
|
||||
end
|
||||
|
||||
def sponsor_logo(s)
|
||||
"https://github.com/#{s["login"]}.png?size=64"
|
||||
def sponsor_logo(sponsor)
|
||||
"https://github.com/#{sponsor[:login]}.png?size=64"
|
||||
end
|
||||
|
||||
def sponsor_url(s)
|
||||
"https://github.com/#{s["login"]}"
|
||||
def sponsor_url(sponsor)
|
||||
"https://github.com/#{sponsor[:login]}"
|
||||
end
|
||||
|
||||
def sponsors
|
||||
sponsors_args.parse
|
||||
def update_sponsors
|
||||
update_sponsors_args.parse
|
||||
|
||||
named_sponsors = []
|
||||
logo_sponsors = []
|
||||
largest_monthly_amount = 0
|
||||
|
||||
GitHub.sponsors_by_tier("Homebrew").each do |tier|
|
||||
if tier["tier"] >= NAMED_TIER_AMOUNT
|
||||
named_sponsors += tier["sponsors"].map do |s|
|
||||
"[#{sponsor_name(s)}](#{sponsor_url(s)})"
|
||||
end
|
||||
end
|
||||
GitHub.sponsorships("Homebrew").each do |s|
|
||||
largest_monthly_amount = [s[:monthly_amount], s[:closest_tier_monthly_amount]].max
|
||||
named_sponsors << "[#{sponsor_name(s)}](#{sponsor_url(s)})" if largest_monthly_amount >= NAMED_MONTHLY_AMOUNT
|
||||
|
||||
next if tier["tier"] < URL_TIER_AMOUNT
|
||||
next if largest_monthly_amount < URL_MONTHLY_AMOUNT
|
||||
|
||||
logo_sponsors += tier["sponsors"].map do |s|
|
||||
"[})](#{sponsor_url(s)})"
|
||||
end
|
||||
logo_sponsors << "[})](#{sponsor_url(s)})"
|
||||
end
|
||||
|
||||
odie "No sponsorships amounts found! Ensure you have sufficient permissions!" if largest_monthly_amount.zero?
|
||||
|
||||
named_sponsors << "many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew)"
|
||||
|
||||
readme = HOMEBREW_REPOSITORY/"README.md"
|
||||
@ -68,7 +66,7 @@ module Homebrew
|
||||
"-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", "README.md"
|
||||
]
|
||||
if diff.status.success?
|
||||
puts "No changes to list of sponsors."
|
||||
ofail "No changes to list of sponsors."
|
||||
else
|
||||
puts "List of sponsors updated in the README."
|
||||
end
|
||||
@ -98,6 +98,16 @@ class DevelopmentTools
|
||||
@gcc_version = {}
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def build_system_too_old?
|
||||
false
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def system_gcc_too_old?
|
||||
false
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def ca_file_handles_most_https_certificates?
|
||||
# The system CA file is too old for some modern HTTPS certificates on
|
||||
|
||||
@ -591,7 +591,11 @@ module Homebrew
|
||||
|
||||
def check_coretap_integrity
|
||||
coretap = CoreTap.instance
|
||||
return if !coretap.installed? && EnvConfig.install_from_api?
|
||||
unless coretap.installed?
|
||||
return if EnvConfig.install_from_api?
|
||||
|
||||
CoreTap.ensure_installed!
|
||||
end
|
||||
|
||||
broken_tap(coretap) || examine_git_origin(coretap.path, Homebrew::EnvConfig.core_git_remote)
|
||||
end
|
||||
|
||||
@ -153,6 +153,11 @@ module Homebrew
|
||||
"editors will do strange things in this case.",
|
||||
default_text: "`$EDITOR` or `$VISUAL`.",
|
||||
},
|
||||
HOMEBREW_EVAL_ALL: {
|
||||
description: "If set, `brew` commands evaluate all formulae and casks, executing their arbitrary code, by " \
|
||||
"default without requiring --eval-all. Required to cache formula and cask descriptions.",
|
||||
boolean: true,
|
||||
},
|
||||
HOMEBREW_FAIL_LOG_LINES: {
|
||||
description: "Output this many lines of output on formula `system` failures.",
|
||||
default: 15,
|
||||
|
||||
@ -5,11 +5,17 @@ class Module
|
||||
def attr_rw(*attrs)
|
||||
attrs.each do |attr|
|
||||
module_eval <<-EOS, __FILE__, __LINE__+1
|
||||
def #{attr}(val=nil) # def prefix(val=nil)
|
||||
@#{attr} ||= nil # @prefix ||= nil
|
||||
return @#{attr} if val.nil? # return @prefix if val.nil?
|
||||
@#{attr} = val # @prefix = val
|
||||
end # end
|
||||
def #{attr}(val=nil) # def prefix(val=nil)
|
||||
if val.nil? # if val.nil?
|
||||
if instance_variable_defined?(:@#{attr}) # if instance_variable_defined?(:@prefix)
|
||||
return @#{attr} # return @prefix
|
||||
else # else
|
||||
return nil # return nil
|
||||
end # end
|
||||
end # end
|
||||
#
|
||||
@#{attr} = val # @prefix = val
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/mac/dependency_collector" if OS.mac?
|
||||
if OS.mac?
|
||||
require "extend/os/mac/dependency_collector"
|
||||
elsif OS.linux?
|
||||
require "extend/os/linux/dependency_collector"
|
||||
end
|
||||
|
||||
89
Library/Homebrew/extend/os/linux/dependency_collector.rb
Normal file
89
Library/Homebrew/extend/os/linux/dependency_collector.rb
Normal file
@ -0,0 +1,89 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "os/linux/glibc"
|
||||
|
||||
class DependencyCollector
|
||||
extend T::Sig
|
||||
|
||||
undef gcc_dep_if_needed
|
||||
undef glibc_dep_if_needed
|
||||
undef init_global_dep_tree_if_needed!
|
||||
|
||||
sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) }
|
||||
def gcc_dep_if_needed(related_formula_names)
|
||||
# gcc is required for libgcc_s.so.1 if glibc or gcc are too old
|
||||
return unless DevelopmentTools.build_system_too_old?
|
||||
return if building_global_dep_tree?
|
||||
return if related_formula_names.include?(GCC)
|
||||
return if global_dep_tree[GCC]&.intersect?(related_formula_names)
|
||||
|
||||
Dependency.new(GCC)
|
||||
end
|
||||
|
||||
sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) }
|
||||
def glibc_dep_if_needed(related_formula_names)
|
||||
return unless OS::Linux::Glibc.below_ci_version?
|
||||
return if building_global_dep_tree?
|
||||
return if related_formula_names.include?(GLIBC)
|
||||
return if global_dep_tree[GLIBC]&.intersect?(related_formula_names)
|
||||
|
||||
Dependency.new(GLIBC)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
GLIBC = "glibc"
|
||||
GCC = CompilerSelector.preferred_gcc.freeze
|
||||
|
||||
sig { void }
|
||||
def init_global_dep_tree_if_needed!
|
||||
return unless DevelopmentTools.build_system_too_old?
|
||||
return if building_global_dep_tree?
|
||||
return unless global_dep_tree.empty?
|
||||
|
||||
building_global_dep_tree!
|
||||
global_dep_tree[GLIBC] = Set.new(global_deps_for(GLIBC))
|
||||
# gcc depends on glibc
|
||||
global_dep_tree[GCC] = Set.new([*global_deps_for(GCC), GLIBC, *@@global_dep_tree[GLIBC]])
|
||||
built_global_dep_tree!
|
||||
end
|
||||
|
||||
sig { params(name: String).returns(T::Array[String]) }
|
||||
def global_deps_for(name)
|
||||
@global_deps_for ||= {}
|
||||
# Always strip out glibc and gcc from all parts of dependency tree when
|
||||
# we're calculating their dependency trees. Other parts of Homebrew will
|
||||
# catch any circular dependencies.
|
||||
@global_deps_for[name] ||= Formula[name].deps.map(&:name).flat_map do |dep|
|
||||
[dep, *global_deps_for(dep)].compact
|
||||
end.uniq
|
||||
end
|
||||
|
||||
# Use class variables to avoid this expensive logic needing to be done more
|
||||
# than once.
|
||||
# rubocop:disable Style/ClassVars
|
||||
@@global_dep_tree = {}
|
||||
@@building_global_dep_tree = false
|
||||
|
||||
sig { returns(T::Hash[String, T::Set[String]]) }
|
||||
def global_dep_tree
|
||||
@@global_dep_tree
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def building_global_dep_tree!
|
||||
@@building_global_dep_tree = true
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def built_global_dep_tree!
|
||||
@@building_global_dep_tree = false
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def building_global_dep_tree?
|
||||
@@building_global_dep_tree.present?
|
||||
end
|
||||
# rubocop:enable Style/ClassVars
|
||||
end
|
||||
@ -21,6 +21,18 @@ class DevelopmentTools
|
||||
:gcc
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def build_system_too_old?
|
||||
return @build_system_too_old if defined? @build_system_too_old
|
||||
|
||||
@build_system_too_old = (system_gcc_too_old? || OS::Linux::Glibc.below_ci_version?)
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def system_gcc_too_old?
|
||||
gcc_version("gcc") < OS::LINUX_GCC_CI_VERSION
|
||||
end
|
||||
|
||||
sig { returns(T::Hash[String, T.nilable(String)]) }
|
||||
def build_system_info
|
||||
generic_build_system_info.merge({
|
||||
|
||||
@ -144,6 +144,7 @@ module Homebrew
|
||||
gcc_dependents = Formula.installed.select do |formula|
|
||||
next false unless formula.tap&.core_tap?
|
||||
|
||||
# FIXME: This includes formulae that have no runtime dependency on GCC.
|
||||
formula.recursive_dependencies.map(&:name).include? "gcc"
|
||||
rescue TapFormulaUnavailableError
|
||||
false
|
||||
@ -153,7 +154,7 @@ module Homebrew
|
||||
badly_linked = gcc_dependents.select do |dependent|
|
||||
keg = Keg.new(dependent.prefix)
|
||||
keg.binary_executable_or_library_files.any? do |binary|
|
||||
paths = binary.rpath.split(":")
|
||||
paths = binary.rpaths
|
||||
versioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/\d+$}) }
|
||||
unversioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/current$}) }
|
||||
|
||||
|
||||
5
Library/Homebrew/extend/os/linux/extend/pathname.rbi
Normal file
5
Library/Homebrew/extend/os/linux/extend/pathname.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
class Pathname
|
||||
include ELFShim
|
||||
end
|
||||
@ -5,6 +5,7 @@ class Formula
|
||||
undef shared_library
|
||||
undef loader_path
|
||||
undef deuniversalize_machos
|
||||
undef add_global_deps_to_spec
|
||||
|
||||
sig { params(name: String, version: T.nilable(T.any(String, Integer))).returns(String) }
|
||||
def shared_library(name, version = nil)
|
||||
@ -23,4 +24,22 @@ class Formula
|
||||
|
||||
sig { params(targets: T.nilable(T.any(Pathname, String))).void }
|
||||
def deuniversalize_machos(*targets); end
|
||||
|
||||
sig { params(spec: SoftwareSpec).void }
|
||||
def add_global_deps_to_spec(spec)
|
||||
return unless DevelopmentTools.build_system_too_old?
|
||||
|
||||
@global_deps ||= begin
|
||||
dependency_collector = spec.dependency_collector
|
||||
related_formula_names = Set.new([
|
||||
name,
|
||||
*versioned_formulae_names,
|
||||
])
|
||||
[
|
||||
dependency_collector.gcc_dep_if_needed(related_formula_names),
|
||||
dependency_collector.glibc_dep_if_needed(related_formula_names),
|
||||
].compact.freeze
|
||||
end
|
||||
@global_deps.each { |dep| spec.dependency_collector.add(dep) }
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,21 +5,45 @@ module Homebrew
|
||||
module Install
|
||||
module_function
|
||||
|
||||
DYNAMIC_LINKERS = [
|
||||
"/lib64/ld-linux-x86-64.so.2",
|
||||
"/lib64/ld64.so.2",
|
||||
"/lib/ld-linux.so.3",
|
||||
"/lib/ld-linux.so.2",
|
||||
"/lib/ld-linux-aarch64.so.1",
|
||||
"/lib/ld-linux-armhf.so.3",
|
||||
"/system/bin/linker64",
|
||||
"/system/bin/linker",
|
||||
# This is a list of known paths to the host dynamic linker on Linux if
|
||||
# the host glibc is new enough. The symlink_ld_so method will fail if
|
||||
# the host linker cannot be found in this list.
|
||||
DYNAMIC_LINKERS = %w[
|
||||
/lib64/ld-linux-x86-64.so.2
|
||||
/lib64/ld64.so.2
|
||||
/lib/ld-linux.so.3
|
||||
/lib/ld-linux.so.2
|
||||
/lib/ld-linux-aarch64.so.1
|
||||
/lib/ld-linux-armhf.so.3
|
||||
/system/bin/linker64
|
||||
/system/bin/linker
|
||||
].freeze
|
||||
private_constant :DYNAMIC_LINKERS
|
||||
|
||||
GCC_VERSION_SUFFIX = OS::LINUX_GCC_CI_VERSION.delete_suffix(".0").freeze
|
||||
|
||||
# We link GCC runtime libraries that are not specificaly used for Fortran,
|
||||
# which are linked by the GCC formula. We only use the versioned shared libraries
|
||||
# as the other shared and static libraries are only used at build time where
|
||||
# GCC can find its own libraries.
|
||||
GCC_RUNTIME_LIBS = %w[
|
||||
libatomic.so.1
|
||||
libgcc_s.so.1
|
||||
libgomp.so.1
|
||||
libstdc++.so.6
|
||||
].freeze
|
||||
private_constant :GCC_RUNTIME_LIBS
|
||||
|
||||
def perform_preinstall_checks(all_fatal: false, cc: nil)
|
||||
generic_perform_preinstall_checks(all_fatal: all_fatal, cc: cc)
|
||||
symlink_ld_so
|
||||
symlink_gcc_libs
|
||||
end
|
||||
|
||||
def global_post_install
|
||||
generic_global_post_install
|
||||
symlink_ld_so
|
||||
symlink_gcc_libs
|
||||
end
|
||||
|
||||
def check_cpu
|
||||
@ -51,5 +75,24 @@ module Homebrew
|
||||
FileUtils.ln_sf ld_so, brew_ld_so
|
||||
end
|
||||
private_class_method :symlink_ld_so
|
||||
|
||||
def symlink_gcc_libs
|
||||
gcc_opt_prefix = HOMEBREW_PREFIX/"opt/#{OS::LINUX_PREFERRED_GCC_FORMULA}"
|
||||
|
||||
GCC_RUNTIME_LIBS.each do |library|
|
||||
gcc_library = gcc_opt_prefix/"lib/gcc/#{GCC_VERSION_SUFFIX}/#{library}"
|
||||
gcc_library_symlink = HOMEBREW_PREFIX/"lib/#{library}"
|
||||
# Skip if the link target doesn't exist.
|
||||
next unless gcc_library.readable?
|
||||
|
||||
# Also skip if the symlink already exists.
|
||||
next if gcc_library_symlink.readable? && (gcc_library_symlink.readlink == gcc_library)
|
||||
|
||||
odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable?
|
||||
|
||||
FileUtils.ln_sf gcc_library, gcc_library_symlink
|
||||
end
|
||||
end
|
||||
private_class_method :symlink_gcc_libs
|
||||
end
|
||||
end
|
||||
|
||||
@ -80,9 +80,14 @@ class LinkageChecker
|
||||
@unwanted_system_dylibs = @system_dylibs.reject do |s|
|
||||
SYSTEM_LIBRARY_ALLOWLIST.include? File.basename(s)
|
||||
end
|
||||
# FIXME: Remove this when these dependencies are injected correctly (e.g. through `DependencyCollector`)
|
||||
# See discussion at
|
||||
# https://github.com/Homebrew/brew/pull/13577
|
||||
@undeclared_deps -= [CompilerSelector.preferred_gcc, "glibc", "gcc"]
|
||||
|
||||
# We build all formulae with an RPATH that includes the gcc formula's runtime lib directory.
|
||||
# See: https://github.com/Homebrew/brew/blob/e689cc07/Library/Homebrew/extend/os/linux/extend/ENV/super.rb#L53
|
||||
# This results in formulae showing linkage with gcc whenever it is installed, even if no dependency is declared.
|
||||
# See discussions at:
|
||||
# https://github.com/Homebrew/brew/pull/13659
|
||||
# https://github.com/Homebrew/brew/pull/13796
|
||||
# TODO: Find a nicer way to handle this. (e.g. examining the ELF file to determine the required libstdc++.)
|
||||
@undeclared_deps.delete("gcc")
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
# typed: strict
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Readall
|
||||
class << self
|
||||
def valid_casks?(*)
|
||||
def valid_casks?(_casks)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
5
Library/Homebrew/extend/os/mac/extend/pathname.rbi
Normal file
5
Library/Homebrew/extend/os/mac/extend/pathname.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
class Pathname
|
||||
include MachOShim
|
||||
end
|
||||
@ -181,6 +181,14 @@ class Formula
|
||||
|
||||
# @private
|
||||
def initialize(name, path, spec, alias_path: nil, force_bottle: false)
|
||||
# Only allow instances of subclasses. The base class does not hold any spec information (URLs etc).
|
||||
raise "Do not call `Formula.new' directly without a subclass." unless self.class < Formula
|
||||
|
||||
# Stop any subsequent modification of a formula's definition.
|
||||
# Changes do not propagate to existing instances of formulae.
|
||||
# Now that we have an instance, it's too late to make any changes to the class-level definition.
|
||||
self.class.freeze
|
||||
|
||||
@name = name
|
||||
@path = path
|
||||
@alias_path = alias_path
|
||||
@ -262,9 +270,13 @@ class Formula
|
||||
return unless spec.url
|
||||
|
||||
spec.owner = self
|
||||
add_global_deps_to_spec(spec)
|
||||
instance_variable_set("@#{name}", spec)
|
||||
end
|
||||
|
||||
sig { params(spec: SoftwareSpec).void }
|
||||
def add_global_deps_to_spec(spec); end
|
||||
|
||||
def determine_active_spec(requested)
|
||||
spec = send(requested) || stable || head
|
||||
spec || raise(FormulaSpecificationError, "formulae require at least a URL")
|
||||
@ -443,7 +455,17 @@ class Formula
|
||||
# Returns any `@`-versioned formulae names for any formula (including versioned formulae).
|
||||
sig { returns(T::Array[String]) }
|
||||
def versioned_formulae_names
|
||||
@versioned_formulae_names ||= Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb")).map do |versioned_path|
|
||||
versioned_paths = if tap
|
||||
# Faster path, due to `tap.versioned_formula_files` caching.
|
||||
name_prefix = "#{name.gsub(/(@[\d.]+)?$/, "")}@"
|
||||
tap.versioned_formula_files.select do |file|
|
||||
file.basename.to_s.start_with?(name_prefix)
|
||||
end
|
||||
else
|
||||
Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb"))
|
||||
end
|
||||
|
||||
versioned_paths.map do |versioned_path|
|
||||
next if versioned_path == path
|
||||
|
||||
versioned_path.basename(".rb").to_s
|
||||
@ -453,7 +475,7 @@ class Formula
|
||||
# Returns any `@`-versioned Formula objects for any Formula (including versioned formulae).
|
||||
sig { returns(T::Array[Formula]) }
|
||||
def versioned_formulae
|
||||
@versioned_formulae ||= versioned_formulae_names.map do |name|
|
||||
versioned_formulae_names.map do |name|
|
||||
Formula[name]
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
@ -1723,14 +1745,14 @@ class Formula
|
||||
elsif shell_parameter_format == :arg
|
||||
"--shell=#{shell}"
|
||||
elsif shell_parameter_format == :none
|
||||
""
|
||||
nil
|
||||
else
|
||||
"#{shell_parameter_format}#{shell}"
|
||||
end
|
||||
|
||||
popen_read_args = %w[]
|
||||
popen_read_args << commands
|
||||
popen_read_args << shell_parameter
|
||||
popen_read_args << shell_parameter if shell_parameter.present?
|
||||
popen_read_args.flatten!
|
||||
|
||||
script_path.dirname.mkpath
|
||||
@ -1784,7 +1806,10 @@ class Formula
|
||||
# this should only be used when users specify `--all` to a command
|
||||
# @private
|
||||
def self.all
|
||||
# TODO: 3.6.0: consider checking ARGV for --all
|
||||
# TODO: uncomment for 3.7.0 and ideally avoid using ARGV by moving to e.g. CLI::Parser
|
||||
# if !ARGV.include?("--eval-all") && !Homebrew::EnvConfig.eval_all?
|
||||
# odeprecated "Formula#all without --all or HOMEBREW_EVAL_ALL"
|
||||
# end
|
||||
|
||||
files.map do |file|
|
||||
Formulary.factory(file)
|
||||
@ -2678,9 +2703,26 @@ class Formula
|
||||
# The methods below define the formula DSL.
|
||||
class << self
|
||||
extend Predicable
|
||||
extend T::Sig
|
||||
include BuildEnvironment::DSL
|
||||
include OnSystem::MacOSAndLinux
|
||||
|
||||
# Initialise instance variables for each subclass. These need to be initialised before the class is frozen,
|
||||
# and some DSL may never be called so it can't be done lazily.
|
||||
def inherited(child)
|
||||
super
|
||||
child.instance_eval do
|
||||
# Ensure this is synced with `freeze`
|
||||
@stable = SoftwareSpec.new(flags: build_flags)
|
||||
@head = HeadSoftwareSpec.new(flags: build_flags)
|
||||
@livecheck = Livecheck.new(self)
|
||||
@conflicts = []
|
||||
@skip_clean_paths = Set.new
|
||||
@link_overwrite_paths = Set.new
|
||||
@allowed_missing_libraries = Set.new
|
||||
end
|
||||
end
|
||||
|
||||
def method_added(method)
|
||||
super
|
||||
|
||||
@ -2692,6 +2734,16 @@ class Formula
|
||||
end
|
||||
end
|
||||
|
||||
def freeze
|
||||
specs.each(&:freeze)
|
||||
@livecheck.freeze
|
||||
@conflicts.freeze
|
||||
@skip_clean_paths.freeze
|
||||
@link_overwrite_paths.freeze
|
||||
@allowed_missing_libraries.freeze
|
||||
super
|
||||
end
|
||||
|
||||
# Whether this formula contains OS/arch-specific blocks
|
||||
# (e.g. `on_macos`, `on_arm`, `on_monterey :or_older`, `on_system :linux, macos: :big_sur_or_newer`).
|
||||
# @private
|
||||
@ -2772,6 +2824,18 @@ class Formula
|
||||
# @private
|
||||
attr_reader :plist_manual
|
||||
|
||||
# @private
|
||||
attr_reader :conflicts
|
||||
|
||||
# @private
|
||||
attr_reader :skip_clean_paths
|
||||
|
||||
# @private
|
||||
attr_reader :link_overwrite_paths
|
||||
|
||||
# @private
|
||||
attr_reader :allowed_missing_libraries
|
||||
|
||||
# If `pour_bottle?` returns `false` the user-visible reason to display for
|
||||
# why they cannot use the bottle.
|
||||
# @private
|
||||
@ -2802,7 +2866,7 @@ class Formula
|
||||
# A list of the {.stable} and {.head} {SoftwareSpec}s.
|
||||
# @private
|
||||
def specs
|
||||
@specs ||= [stable, head].freeze
|
||||
[stable, head].freeze
|
||||
end
|
||||
|
||||
# @!attribute [w] url
|
||||
@ -2886,8 +2950,9 @@ class Formula
|
||||
#
|
||||
# Formulae which should not be bottled should be tagged with:
|
||||
# <pre>bottle :disable, "reasons"</pre>
|
||||
def bottle(*args, &block)
|
||||
stable.bottle(*args, &block)
|
||||
sig { params(block: T.proc.bind(BottleSpecification).void).void }
|
||||
def bottle(&block)
|
||||
stable.bottle(&block)
|
||||
end
|
||||
|
||||
# @private
|
||||
@ -2918,7 +2983,6 @@ class Formula
|
||||
# depends_on "libffi"
|
||||
# end</pre>
|
||||
def stable(&block)
|
||||
@stable ||= SoftwareSpec.new(flags: build_flags)
|
||||
return @stable unless block
|
||||
|
||||
@stable.instance_eval(&block)
|
||||
@ -2937,7 +3001,6 @@ class Formula
|
||||
# or (if autodetect fails):
|
||||
# <pre>head "https://hg.is.awesome.but.git.has.won.example.com/", using: :hg</pre>
|
||||
def head(val = nil, specs = {}, &block)
|
||||
@head ||= HeadSoftwareSpec.new(flags: build_flags)
|
||||
if block
|
||||
@head.instance_eval(&block)
|
||||
elsif val
|
||||
@ -3088,11 +3151,6 @@ class Formula
|
||||
@plist_manual = options[:manual]
|
||||
end
|
||||
|
||||
# @private
|
||||
def conflicts
|
||||
@conflicts ||= []
|
||||
end
|
||||
|
||||
# One or more formulae that conflict with this one and why.
|
||||
# <pre>conflicts_with "imagemagick", because: "both install `convert` binaries"</pre>
|
||||
def conflicts_with(*names)
|
||||
@ -3113,11 +3171,6 @@ class Formula
|
||||
skip_clean_paths.merge(paths)
|
||||
end
|
||||
|
||||
# @private
|
||||
def skip_clean_paths
|
||||
@skip_clean_paths ||= Set.new
|
||||
end
|
||||
|
||||
# Software that will not be symlinked into the `brew --prefix` and will
|
||||
# only live in its Cellar. Other formulae can depend on it and Homebrew
|
||||
# will add the necessary includes, libraries, and other paths while
|
||||
@ -3221,7 +3274,6 @@ class Formula
|
||||
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
||||
# end</pre>
|
||||
def livecheck(&block)
|
||||
@livecheck ||= Livecheck.new(self)
|
||||
return @livecheck unless block
|
||||
|
||||
@livecheckable = true
|
||||
@ -3377,11 +3429,6 @@ class Formula
|
||||
link_overwrite_paths.merge(paths)
|
||||
end
|
||||
|
||||
# @private
|
||||
def link_overwrite_paths
|
||||
@link_overwrite_paths ||= Set.new
|
||||
end
|
||||
|
||||
# Permit links to certain libraries that don't exist. Available on Linux only.
|
||||
def ignore_missing_libraries(*libs)
|
||||
unless Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||
@ -3395,11 +3442,6 @@ class Formula
|
||||
|
||||
allowed_missing_libraries.merge(libraries)
|
||||
end
|
||||
|
||||
# @private
|
||||
def allowed_missing_libraries
|
||||
@allowed_missing_libraries ||= Set.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -52,14 +52,16 @@ module Homebrew
|
||||
|
||||
def audit_file
|
||||
if formula.core_formula? && @versioned_formula
|
||||
unversioned_name = formula.name.gsub(/@.*$/, "")
|
||||
|
||||
# ignore when an unversioned formula doesn't exist after an explicit rename
|
||||
return if formula.tap.formula_renames.key?(unversioned_name)
|
||||
|
||||
# build this ourselves as we want e.g. homebrew/core to be present
|
||||
full_name = "#{formula.tap}/#{unversioned_name}"
|
||||
|
||||
unversioned_formula = begin
|
||||
# build this ourselves as we want e.g. homebrew/core to be present
|
||||
full_name = if formula.tap
|
||||
"#{formula.tap}/#{formula.name}"
|
||||
else
|
||||
formula.name
|
||||
end
|
||||
Formulary.factory(full_name.gsub(/@.*$/, "")).path
|
||||
Formulary.factory(full_name).path
|
||||
rescue FormulaUnavailableError, TapFormulaAmbiguityError,
|
||||
TapFormulaWithOldnameAmbiguityError
|
||||
Pathname.new formula.path.to_s.gsub(/@.*\.rb$/, ".rb")
|
||||
@ -194,6 +196,13 @@ module Homebrew
|
||||
if formula.license.present?
|
||||
licenses, exceptions = SPDX.parse_license_expression formula.license
|
||||
|
||||
sspl_licensed = licenses.any? { |license| license.to_s.start_with?("SSPL") }
|
||||
if sspl_licensed && @core_tap
|
||||
problem <<~EOS
|
||||
Formula #{formula.name} is SSPL-licensed. Software under the SSPL must not be packaged in homebrew/core.
|
||||
EOS
|
||||
end
|
||||
|
||||
non_standard_licenses = licenses.reject { |license| SPDX.valid_license? license }
|
||||
if non_standard_licenses.present?
|
||||
problem <<~EOS
|
||||
@ -263,10 +272,7 @@ module Homebrew
|
||||
next
|
||||
end
|
||||
|
||||
# FIXME: Remove `glib-utils` exemption when the following PRs are merged:
|
||||
# https://github.com/Homebrew/homebrew-core/pull/108307
|
||||
# https://github.com/Homebrew/homebrew-core/pull/108497
|
||||
if dep_f.oldname && dep.name.split("/").last == dep_f.oldname && dep_f.oldname != "glib-utils"
|
||||
if dep_f.oldname && dep.name.split("/").last == dep_f.oldname
|
||||
problem "Dependency '#{dep.name}' was renamed; use new name '#{dep_f.name}'."
|
||||
end
|
||||
|
||||
@ -335,13 +341,6 @@ module Homebrew
|
||||
end
|
||||
|
||||
return unless @core_tap
|
||||
|
||||
bad_gcc_dep = linux_only_gcc_dep?(formula) && (@strict || begin
|
||||
fv = FormulaVersions.new(formula)
|
||||
fv.formula_at_revision("origin/HEAD") { |prev_f| !linux_only_gcc_dep?(prev_f) }
|
||||
end)
|
||||
problem "Formulae in homebrew/core should not have a Linux-only dependency on GCC." if bad_gcc_dep
|
||||
|
||||
return if formula.tap&.audit_exception :versioned_dependencies_conflicts_allowlist, formula.name
|
||||
|
||||
# The number of conflicts on Linux is absurd.
|
||||
@ -415,6 +414,21 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def audit_gcc_dependency
|
||||
return unless @core_tap
|
||||
return if !@strict && !(@git && formula.tap.git?) # git log is required for non-strict audit
|
||||
return unless Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||
return unless linux_only_gcc_dep?(formula)
|
||||
|
||||
bad_gcc_dep = @strict || begin
|
||||
fv = FormulaVersions.new(formula)
|
||||
fv.formula_at_revision("origin/HEAD") { |prev_f| !linux_only_gcc_dep?(prev_f) }
|
||||
end
|
||||
return unless bad_gcc_dep
|
||||
|
||||
problem "Formulae in homebrew/core should not have a Linux-only dependency on GCC."
|
||||
end
|
||||
|
||||
def audit_postgresql
|
||||
return unless formula.name == "postgresql"
|
||||
return unless @core_tap
|
||||
@ -477,13 +491,10 @@ module Homebrew
|
||||
|
||||
return unless DevelopmentTools.curl_handles_most_https_certificates?
|
||||
|
||||
use_homebrew_curl = false
|
||||
%w[Stable HEAD].each do |name|
|
||||
spec_name = name.downcase.to_sym
|
||||
next unless (spec = formula.send(spec_name))
|
||||
use_homebrew_curl = [:stable, :head].any? do |spec_name|
|
||||
next false unless (spec = formula.send(spec_name))
|
||||
|
||||
use_homebrew_curl = spec.using == :homebrew_curl
|
||||
break if use_homebrew_curl
|
||||
spec.using == :homebrew_curl
|
||||
end
|
||||
|
||||
if (http_content_problem = curl_check_http_content(homepage,
|
||||
@ -865,14 +876,30 @@ module Homebrew
|
||||
end
|
||||
|
||||
def linux_only_gcc_dep?(formula)
|
||||
# TODO: Make this check work when running on Linux and not simulating macOS too.
|
||||
return false unless Homebrew::SimulateSystem.simulating_or_running_on_macos?
|
||||
odie "`#linux_only_gcc_dep?` works only on Linux!" if Homebrew::SimulateSystem.simulating_or_running_on_macos?
|
||||
return false if formula.deps.map(&:name).exclude?("gcc")
|
||||
|
||||
formula_hash = formula.to_hash_with_variations
|
||||
deps = formula_hash["dependencies"]
|
||||
linux_deps = formula_hash.dig("variations", :x86_64_linux, "dependencies")
|
||||
variations = formula.to_hash_with_variations["variations"]
|
||||
# The formula has no variations, so all OS-version-arch triples depend on GCC.
|
||||
return false if variations.blank?
|
||||
|
||||
deps.exclude?("gcc") && linux_deps&.include?("gcc")
|
||||
MacOSVersions::SYMBOLS.each_key do |macos_version|
|
||||
[:arm, :intel].each do |arch|
|
||||
bottle_tag = Utils::Bottles::Tag.new(system: macos_version, arch: arch)
|
||||
next unless bottle_tag.valid_combination?
|
||||
|
||||
variation_dependencies = variations.dig(bottle_tag.to_sym, "dependencies")
|
||||
# This variation either:
|
||||
# 1. does not exist
|
||||
# 2. has no variation-specific dependencies
|
||||
# In either case, it matches Linux.
|
||||
return false if variation_dependencies.blank?
|
||||
# We found a non-Linux variation that depends on GCC.
|
||||
return false if variation_dependencies.include?("gcc")
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -581,11 +581,9 @@ class FormulaInstaller
|
||||
end
|
||||
|
||||
def expand_dependencies_for_formula(formula, inherited_options)
|
||||
any_bottle_used = false
|
||||
|
||||
# Cache for this expansion only. FormulaInstaller has a lot of inputs which can alter expansion.
|
||||
cache_key = "FormulaInstaller-#{formula.full_name}-#{Time.now.to_f}"
|
||||
expanded_deps = Dependency.expand(formula, cache_key: cache_key) do |dependent, dep|
|
||||
Dependency.expand(formula, cache_key: cache_key) do |dependent, dep|
|
||||
inherited_options[dep.name] |= inherited_options_for(dep)
|
||||
build = effective_build_options_for(
|
||||
dependent,
|
||||
@ -601,36 +599,14 @@ class FormulaInstaller
|
||||
Dependency.prune
|
||||
elsif dep.satisfied?(inherited_options[dep.name])
|
||||
Dependency.skip
|
||||
else
|
||||
any_bottle_used ||= install_bottle_for?(dep.to_formula, build)
|
||||
end
|
||||
end
|
||||
|
||||
[expanded_deps, any_bottle_used]
|
||||
end
|
||||
|
||||
def expand_dependencies
|
||||
inherited_options = Hash.new { |hash, key| hash[key] = Options.new }
|
||||
any_bottle_used = pour_bottle?
|
||||
|
||||
expanded_deps, any_dep_bottle_used = expand_dependencies_for_formula(formula, inherited_options)
|
||||
any_bottle_used ||= any_dep_bottle_used
|
||||
|
||||
# We require some dependencies (glibc, GCC 5, etc.) if binaries were built.
|
||||
# Native binaries shouldn't exist in cross-platform `all` bottles.
|
||||
if any_bottle_used && !formula.bottled?(:all) && !Keg.bottle_dependencies.empty?
|
||||
all_bottle_deps = Keg.bottle_dependencies.flat_map do |bottle_dep|
|
||||
bottle_dep.recursive_dependencies.map(&:name) + [bottle_dep.name]
|
||||
end
|
||||
|
||||
if all_bottle_deps.exclude?(formula.name)
|
||||
bottle_deps = Keg.bottle_dependencies.flat_map do |bottle_dep|
|
||||
expanded_bottle_deps, = expand_dependencies_for_formula(bottle_dep, inherited_options)
|
||||
expanded_bottle_deps
|
||||
end
|
||||
expanded_deps = Dependency.merge_repeats(bottle_deps + expanded_deps)
|
||||
end
|
||||
end
|
||||
expanded_deps = expand_dependencies_for_formula(formula, inherited_options)
|
||||
|
||||
expanded_deps.map { |dep| [dep, inherited_options[dep.name]] }
|
||||
end
|
||||
@ -799,6 +775,8 @@ class FormulaInstaller
|
||||
|
||||
fix_dynamic_linkage(keg) if !@poured_bottle || !formula.bottle_specification.skip_relocation?
|
||||
|
||||
Homebrew::Install.global_post_install
|
||||
|
||||
if build_bottle?
|
||||
ohai "Not running 'post_install' as we're building a bottle"
|
||||
puts "You can run it manually using:"
|
||||
@ -1187,6 +1165,8 @@ class FormulaInstaller
|
||||
|
||||
if pour_bottle?(output_warning: true)
|
||||
formula.fetch_bottle_tab
|
||||
elsif Homebrew::EnvConfig.install_from_api?
|
||||
odie "Unable to build #{formula.name} from source with HOMEBREW_INSTALL_FROM_API."
|
||||
else
|
||||
formula.fetch_patches
|
||||
formula.resources.each(&:fetch)
|
||||
|
||||
@ -45,6 +45,7 @@ HOMEBREW_REQUIRED_RUBY_VERSION = ENV.fetch("HOMEBREW_REQUIRED_RUBY_VERSION").fre
|
||||
HOMEBREW_PRODUCT = ENV.fetch("HOMEBREW_PRODUCT").freeze
|
||||
HOMEBREW_VERSION = ENV.fetch("HOMEBREW_VERSION").freeze
|
||||
HOMEBREW_WWW = "https://brew.sh"
|
||||
HOMEBREW_DOCS_WWW = "https://docs.brew.sh"
|
||||
HOMEBREW_SYSTEM = ENV.fetch("HOMEBREW_SYSTEM").freeze
|
||||
HOMEBREW_PROCESSOR = ENV.fetch("HOMEBREW_PROCESSOR").freeze
|
||||
|
||||
|
||||
@ -30,6 +30,10 @@ module Homebrew
|
||||
Diagnostic.checks(:build_from_source_checks, fatal: all_fatal)
|
||||
end
|
||||
|
||||
def global_post_install; end
|
||||
alias generic_global_post_install global_post_install
|
||||
module_function :generic_global_post_install
|
||||
|
||||
def check_prefix
|
||||
if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) &&
|
||||
HOMEBREW_PREFIX.to_s == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
|
||||
|
||||
@ -366,17 +366,6 @@ class Keg
|
||||
def self.file_linked_libraries(_file, _string)
|
||||
[]
|
||||
end
|
||||
|
||||
def self.bottle_dependencies
|
||||
return [] unless Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||
|
||||
@bottle_dependencies ||= begin
|
||||
formulae = []
|
||||
gcc = Formulary.factory(CompilerSelector.preferred_gcc)
|
||||
formulae << gcc if DevelopmentTools.gcc_version("gcc") < gcc.version.to_i
|
||||
formulae
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "extend/os/keg_relocate"
|
||||
|
||||
@ -82,9 +82,20 @@ class Options
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
# Ensure this is synced with `initialize_dup` and `freeze` (excluding simple objects like integers and booleans)
|
||||
@options = Set.new(*args)
|
||||
end
|
||||
|
||||
def initialize_dup(other)
|
||||
super
|
||||
@options = @options.dup
|
||||
end
|
||||
|
||||
def freeze
|
||||
@options.dup
|
||||
super
|
||||
end
|
||||
|
||||
def each(*args, &block)
|
||||
@options.each(*args, &block)
|
||||
end
|
||||
|
||||
@ -45,15 +45,12 @@ module OS
|
||||
|
||||
::OS_VERSION = ENV.fetch("HOMEBREW_OS_VERSION").freeze
|
||||
|
||||
LINUX_CI_OS_VERSION = "Ubuntu 16.04"
|
||||
LINUX_GLIBC_CI_VERSION = "2.23"
|
||||
LINUX_GCC_CI_VERSION = "5.0"
|
||||
LINUX_PREFERRED_GCC_FORMULA = "gcc@5"
|
||||
|
||||
# Ubuntu 22.04 (see Linux-CI.md)
|
||||
# See Linux-CI.md
|
||||
LINUX_CI_OS_VERSION = "Ubuntu 22.04"
|
||||
LINUX_GLIBC_CI_VERSION = "2.35"
|
||||
LINUX_GLIBC_NEXT_CI_VERSION = "2.35"
|
||||
# LINUX_GCC_CI_VERSION = "11.0"
|
||||
# LINUX_PREFERRED_GCC_FORMULA = "gcc@11"
|
||||
LINUX_GCC_CI_VERSION = "11.0"
|
||||
LINUX_PREFERRED_GCC_FORMULA = "gcc@11"
|
||||
|
||||
if OS.mac?
|
||||
require "os/mac"
|
||||
|
||||
@ -97,7 +97,7 @@ module ELFShim
|
||||
# An array of runtime search path entries, such as:
|
||||
# ["/lib", "/usr/lib", "/usr/local/lib"]
|
||||
def rpaths
|
||||
rpath.split(":")
|
||||
Array(rpath&.split(":"))
|
||||
end
|
||||
|
||||
def interpreter
|
||||
|
||||
@ -44,6 +44,11 @@ module OS
|
||||
def below_minimum_version?
|
||||
system_version < minimum_version
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def below_ci_version?
|
||||
system_version < LINUX_GLIBC_CI_VERSION
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
raise "#{__FILE__} must not be loaded via `require`." if $PROGRAM_NAME != __FILE__
|
||||
|
||||
old_trap = trap("INT") { exit! 130 }
|
||||
|
||||
require_relative "global"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formula"
|
||||
|
||||
@ -20,6 +20,10 @@ class Requirement
|
||||
attr_reader :tags, :name, :cask, :download
|
||||
|
||||
def initialize(tags = [])
|
||||
# Only allow instances of subclasses. This base class enforces no constraints on its own.
|
||||
# Individual subclasses use the `satisfy` DSL to define those constraints.
|
||||
raise "Do not call `Requirement.new' directly without a subclass." unless self.class < Requirement
|
||||
|
||||
@cask = self.class.cask
|
||||
@download = self.class.download
|
||||
tags.each do |tag|
|
||||
@ -141,9 +145,9 @@ class Requirement
|
||||
private
|
||||
|
||||
def infer_name
|
||||
klass = self.class.name || self.class.to_s
|
||||
klass = klass.sub(/(Dependency|Requirement)$/, "")
|
||||
.sub(/^(\w+::)*/, "")
|
||||
klass = self.class.name
|
||||
klass = klass&.sub(/(Dependency|Requirement)$/, "")
|
||||
&.sub(/^(\w+::)*/, "")
|
||||
return klass.downcase if klass.present?
|
||||
|
||||
return @cask if @cask.present?
|
||||
|
||||
@ -29,6 +29,7 @@ class Resource
|
||||
attr_accessor :name
|
||||
|
||||
def initialize(name = nil, &block)
|
||||
# Ensure this is synced with `initialize_dup` and `freeze` (excluding simple objects like integers and booleans)
|
||||
@name = name
|
||||
@url = nil
|
||||
@version = nil
|
||||
@ -37,11 +38,35 @@ class Resource
|
||||
@checksum = nil
|
||||
@using = nil
|
||||
@patches = []
|
||||
@livecheck = nil
|
||||
@livecheck = Livecheck.new(self)
|
||||
@livecheckable = false
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
|
||||
def initialize_dup(other)
|
||||
super
|
||||
@name = @name.dup
|
||||
@version = @version.dup
|
||||
@mirrors = @mirrors.dup
|
||||
@specs = @specs.dup
|
||||
@checksum = @checksum.dup
|
||||
@using = @using.dup
|
||||
@patches = @patches.dup
|
||||
@livecheck = @livecheck.dup
|
||||
end
|
||||
|
||||
def freeze
|
||||
@name.freeze
|
||||
@version.freeze
|
||||
@mirrors.freeze
|
||||
@specs.freeze
|
||||
@checksum.freeze
|
||||
@using.freeze
|
||||
@patches.freeze
|
||||
@livecheck.freeze
|
||||
super
|
||||
end
|
||||
|
||||
def owner=(owner)
|
||||
@owner = owner
|
||||
patches.each { |p| p.owner = owner }
|
||||
@ -185,7 +210,6 @@ class Resource
|
||||
# regex /foo-(\d+(?:\.\d+)+)\.tar/
|
||||
# end</pre>
|
||||
def livecheck(&block)
|
||||
@livecheck ||= Livecheck.new(self) if block
|
||||
return @livecheck unless block
|
||||
|
||||
@livecheckable = true
|
||||
@ -215,13 +239,13 @@ class Resource
|
||||
@download_strategy = DownloadStrategyDetector.detect(url, using)
|
||||
@specs.merge!(specs)
|
||||
@downloader = nil
|
||||
@version = detect_version(@version)
|
||||
end
|
||||
|
||||
def version(val = nil)
|
||||
@version ||= begin
|
||||
version = detect_version(val)
|
||||
version.null? ? nil : version
|
||||
end
|
||||
return @version if val.nil?
|
||||
|
||||
@version = detect_version(val)
|
||||
end
|
||||
|
||||
def mirror(val)
|
||||
@ -242,15 +266,15 @@ class Resource
|
||||
private
|
||||
|
||||
def detect_version(val)
|
||||
return Version::NULL if val.nil? && url.nil?
|
||||
|
||||
case val
|
||||
when nil then Version.detect(url, **specs)
|
||||
version = case val
|
||||
when nil then url.nil? ? Version::NULL : Version.detect(url, **specs)
|
||||
when String then Version.create(val)
|
||||
when Version then val
|
||||
else
|
||||
raise TypeError, "version '#{val.inspect}' should be a string"
|
||||
end
|
||||
|
||||
version unless version.null?
|
||||
end
|
||||
|
||||
# A resource containing a Go package.
|
||||
|
||||
@ -49,7 +49,7 @@ module RuboCop
|
||||
stanzas.sort do |s1, s2|
|
||||
i1 = stanza_order_index(s1)
|
||||
i2 = stanza_order_index(s2)
|
||||
if i1 == i2
|
||||
if i1 == i2 || i1.blank? || i2.blank?
|
||||
i1 = stanzas.index(s1)
|
||||
i2 = stanzas.index(s2)
|
||||
end
|
||||
|
||||
@ -55,6 +55,8 @@ module RuboCop
|
||||
end.freeze
|
||||
|
||||
STANZA_ORDER = STANZA_GROUPS.flatten.freeze
|
||||
|
||||
ON_SYSTEM_METHODS = [:arm, :intel, *MacOSVersions::SYMBOLS.keys].map { |option| :"on_#{option}" }.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -19,8 +19,10 @@ module RuboCop
|
||||
|
||||
def stanza?
|
||||
return true if arch_variable?
|
||||
return false if !send_type? && !block_type?
|
||||
return true if ON_SYSTEM_METHODS.include?(method_name)
|
||||
|
||||
(send_type? || block_type?) && STANZA_ORDER.include?(method_name)
|
||||
STANZA_ORDER.include?(method_name)
|
||||
end
|
||||
|
||||
def heredoc?
|
||||
|
||||
@ -39,6 +39,9 @@ module RuboCop
|
||||
|
||||
audit_on_system_blocks(stanza.stanza_node, stanza.stanza_name)
|
||||
end
|
||||
|
||||
audit_arch_conditionals(cask_body)
|
||||
simplify_sha256_stanzas
|
||||
end
|
||||
|
||||
private
|
||||
@ -46,6 +49,33 @@ module RuboCop
|
||||
attr_reader :cask_block
|
||||
|
||||
def_delegators :cask_block, :toplevel_stanzas, :cask_body
|
||||
|
||||
def simplify_sha256_stanzas
|
||||
nodes = {}
|
||||
|
||||
sha256_on_arch_stanzas(cask_body) do |node, method, value|
|
||||
nodes[method.to_s.delete_prefix("on_").to_sym] = { node: node, value: value }
|
||||
end
|
||||
|
||||
return if !nodes.key?(:arm) || !nodes.key?(:intel)
|
||||
|
||||
offending_node(nodes[:arm][:node])
|
||||
replacement_string = "sha256 arm: #{nodes[:arm][:value].inspect}, intel: #{nodes[:intel][:value].inspect}"
|
||||
|
||||
problem "Use `#{replacement_string}` instead of nesting the `sha256` stanzas in " \
|
||||
"`on_intel` and `on_arm` blocks" do |corrector|
|
||||
corrector.replace(nodes[:arm][:node].source_range, replacement_string)
|
||||
corrector.replace(nodes[:intel][:node].source_range, "")
|
||||
end
|
||||
end
|
||||
|
||||
def_node_search :sha256_on_arch_stanzas, <<~PATTERN
|
||||
$(block
|
||||
(send nil? ${:on_intel :on_arm})
|
||||
(args)
|
||||
(send nil? :sha256
|
||||
(str $_)))
|
||||
PATTERN
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
17
Library/Homebrew/rubocops/cask/on_system_conditionals.rbi
Normal file
17
Library/Homebrew/rubocops/cask/on_system_conditionals.rbi
Normal file
@ -0,0 +1,17 @@
|
||||
# typed: strict
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Cask
|
||||
class OnSystemConditionals < Base
|
||||
sig {
|
||||
params(
|
||||
base_node: Parser::AST::Node,
|
||||
block: T.proc.params(node: Parser::AST::Node, method: Symbol, value: String).void,
|
||||
).void
|
||||
}
|
||||
def sha256_on_arch_stanzas(base_node, &block); end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -415,6 +415,151 @@ module RuboCop
|
||||
end
|
||||
end
|
||||
|
||||
# This cop makes sure that the `generate_completions_from_executable` DSL is used.
|
||||
#
|
||||
# @api private
|
||||
class GenerateCompletionsDSL < FormulaCop
|
||||
extend AutoCorrector
|
||||
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
install = find_method_def(body_node, :install)
|
||||
return if install.blank?
|
||||
|
||||
correctable_shell_completion_node(install) do |node, shell, base_name, executable, subcmd, shell_parameter| # rubocop:disable Metrics/ParameterLists
|
||||
# generate_completions_from_executable only applicable if shell is passed
|
||||
next unless shell_parameter.match?(/(bash|zsh|fish)/)
|
||||
|
||||
base_name = base_name.delete_prefix("_").delete_suffix(".fish")
|
||||
shell = shell.to_s.delete_suffix("_completion").to_sym
|
||||
shell_parameter_stripped = shell_parameter
|
||||
.delete_suffix("bash")
|
||||
.delete_suffix("zsh")
|
||||
.delete_suffix("fish")
|
||||
shell_parameter_format = if shell_parameter_stripped.empty?
|
||||
nil
|
||||
elsif shell_parameter_stripped == "--"
|
||||
:flag
|
||||
elsif shell_parameter_stripped == "--shell="
|
||||
:arg
|
||||
else
|
||||
shell_parameter_stripped
|
||||
end
|
||||
|
||||
replacement_args = %w[]
|
||||
replacement_args << executable.source
|
||||
replacement_args << subcmd.source
|
||||
replacement_args << "base_name: \"#{base_name}\"" unless base_name == @formula_name
|
||||
replacement_args << "shells: [:#{shell}]"
|
||||
unless shell_parameter_format.nil?
|
||||
replacement_args << "shell_parameter_format: #{shell_parameter_format.inspect}"
|
||||
end
|
||||
|
||||
offending_node(node)
|
||||
replacement = "generate_completions_from_executable(#{replacement_args.join(", ")})"
|
||||
|
||||
problem "Use `#{replacement}` instead of `#{@offensive_node.source}`." do |corrector|
|
||||
corrector.replace(@offensive_node.source_range, replacement)
|
||||
end
|
||||
end
|
||||
|
||||
shell_completion_node(install) do |node|
|
||||
next if node.source.include?("<<~") # skip heredoc completion scripts
|
||||
next if node.source.match?(/{.*=>.*}/) # skip commands needing custom ENV variables
|
||||
|
||||
offending_node(node)
|
||||
problem "Use `generate_completions_from_executable` DSL instead of `#{@offensive_node.source}`."
|
||||
end
|
||||
end
|
||||
|
||||
# match ({bash,zsh,fish}_completion/"_?foo{.fish}?").write Utils.safe_popen_read(foo, subcmd, shell_parameter)
|
||||
def_node_search :correctable_shell_completion_node, <<~EOS
|
||||
$(send
|
||||
(begin
|
||||
(send
|
||||
(send nil? ${:bash_completion :zsh_completion :fish_completion}) :/
|
||||
(str $_))) :write
|
||||
(send
|
||||
(const nil? :Utils) :safe_popen_read
|
||||
$(send
|
||||
(send nil? :bin) :/
|
||||
(str _))
|
||||
$(str _)
|
||||
(str $_)))
|
||||
EOS
|
||||
|
||||
# matches ({bash,zsh,fish}_completion/"_?foo{.fish}?").write output
|
||||
def_node_search :shell_completion_node, <<~EOS
|
||||
$(send
|
||||
(begin
|
||||
(send
|
||||
(send nil? {:bash_completion :zsh_completion :fish_completion}) :/
|
||||
(str _))) :write _)
|
||||
EOS
|
||||
end
|
||||
|
||||
# This cop makes sure that the `generate_completions_from_executable` DSL is used with only
|
||||
# a single, combined call for all shells.
|
||||
#
|
||||
# @api private
|
||||
class SingleGenerateCompletionsDSLCall < FormulaCop
|
||||
extend AutoCorrector
|
||||
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
install = find_method_def(body_node, :install)
|
||||
return if install.blank?
|
||||
|
||||
methods = find_every_method_call_by_name(install, :generate_completions_from_executable)
|
||||
return if methods.length <= 1
|
||||
|
||||
offenses = []
|
||||
shells = []
|
||||
methods.each do |method|
|
||||
next unless method.source.include?("shells:")
|
||||
|
||||
shells << method.source.match(/shells: \[(:bash|:zsh|:fish)\]/).captures.first
|
||||
offenses << method
|
||||
end
|
||||
|
||||
return if offenses.blank?
|
||||
|
||||
T.must(offenses[0...-1]).each_with_index do |node, i|
|
||||
# commands have to be the same to be combined
|
||||
# send_type? matches `bin/"foo"`, str_type? matches remaining command parts,
|
||||
# the rest are kwargs we need to filter out
|
||||
method_commands = node.arguments.filter { |arg| arg.send_type? || arg.str_type? }
|
||||
next_method_commands = offenses[i + 1].arguments.filter { |arg| arg.send_type? || arg.str_type? }
|
||||
unless method_commands == next_method_commands
|
||||
shells.delete_at(i)
|
||||
next
|
||||
end
|
||||
|
||||
offending_node(node)
|
||||
problem "Use a single `generate_completions_from_executable` " \
|
||||
"call combining all specified shells." do |corrector|
|
||||
# adjust range by -4 and +1 to also include & remove leading spaces and trailing \n
|
||||
corrector.replace(@offensive_node.source_range.adjust(begin_pos: -4, end_pos: 1), "")
|
||||
end
|
||||
end
|
||||
|
||||
return if shells.length <= 1 # no shells to combine left
|
||||
|
||||
offending_node(offenses.last)
|
||||
replacement = if (%w[:bash :zsh :fish] - shells).empty?
|
||||
@offensive_node.source.sub(/shells: \[(:bash|:zsh|:fish)\]/, "")
|
||||
.sub(", )", ")") # clean up dangling trailing comma
|
||||
.sub("(, ", "(") # clean up dangling leading comma
|
||||
.sub(", , ", ", ") # clean up dangling enclosed comma
|
||||
else
|
||||
@offensive_node.source.sub(/shells: \[(:bash|:zsh|:fish)\]/,
|
||||
"shells: [#{shells.join(", ")}]")
|
||||
end
|
||||
|
||||
problem "Use `#{replacement}` instead of `#{@offensive_node.source}`." do |corrector|
|
||||
corrector.replace(@offensive_node.source_range, replacement)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This cop checks for other miscellaneous style violations.
|
||||
#
|
||||
# @api private
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
#!/bin/bash
|
||||
exec brew rubocop "$@"
|
||||
HOMEBREW_PREFIX_BIN="$(cd "$(dirname "$0")"/../../../../ && pwd)/bin/"
|
||||
exec "${HOMEBREW_PREFIX_BIN}"brew rubocop "$@"
|
||||
|
||||
@ -36,6 +36,7 @@ class SoftwareSpec
|
||||
def_delegators :@resource, :sha256
|
||||
|
||||
def initialize(flags: [])
|
||||
# Ensure this is synced with `initialize_dup` and `freeze` (excluding simple objects like integers and booleans)
|
||||
@resource = Resource.new
|
||||
@resources = {}
|
||||
@dependency_collector = DependencyCollector.new
|
||||
@ -50,6 +51,38 @@ class SoftwareSpec
|
||||
@uses_from_macos_elements = []
|
||||
end
|
||||
|
||||
def initialize_dup(other)
|
||||
super
|
||||
@resource = @resource.dup
|
||||
@resources = @resources.dup
|
||||
@dependency_collector = @dependency_collector.dup
|
||||
@bottle_specification = @bottle_specification.dup
|
||||
@patches = @patches.dup
|
||||
@options = @options.dup
|
||||
@flags = @flags.dup
|
||||
@deprecated_flags = @deprecated_flags.dup
|
||||
@deprecated_options = @deprecated_options.dup
|
||||
@build = @build.dup
|
||||
@compiler_failures = @compiler_failures.dup
|
||||
@uses_from_macos_elements = @uses_from_macos_elements.dup
|
||||
end
|
||||
|
||||
def freeze
|
||||
@resource.freeze
|
||||
@resources.freeze
|
||||
@dependency_collector.freeze
|
||||
@bottle_specification.freeze
|
||||
@patches.freeze
|
||||
@options.freeze
|
||||
@flags.freeze
|
||||
@deprecated_flags.freeze
|
||||
@deprecated_options.freeze
|
||||
@build.freeze
|
||||
@compiler_failures.freeze
|
||||
@uses_from_macos_elements.freeze
|
||||
super
|
||||
end
|
||||
|
||||
def owner=(owner)
|
||||
@name = owner.name
|
||||
@full_name = owner.full_name
|
||||
@ -321,7 +354,7 @@ class Bottle
|
||||
@cellar = tag_spec.cellar
|
||||
@rebuild = spec.rebuild
|
||||
|
||||
@resource.version = formula.pkg_version
|
||||
@resource.version = formula.pkg_version.to_s
|
||||
@resource.checksum = tag_spec.checksum
|
||||
|
||||
@fetch_tab_retried = false
|
||||
|
||||
@ -2784,7 +2784,6 @@ end
|
||||
module ActiveSupport::VERSION; end
|
||||
ActiveSupport::VERSION::MAJOR = T.let(T.unsafe(nil), Integer)
|
||||
ActiveSupport::VERSION::MINOR = T.let(T.unsafe(nil), Integer)
|
||||
ActiveSupport::VERSION::PRE = T.let(T.unsafe(nil), String)
|
||||
ActiveSupport::VERSION::STRING = T.let(T.unsafe(nil), String)
|
||||
ActiveSupport::VERSION::TINY = T.let(T.unsafe(nil), Integer)
|
||||
|
||||
@ -220,6 +220,7 @@ class Addressable::URI
|
||||
|
||||
protected
|
||||
|
||||
def force_utf8_encoding_if_needed(str); end
|
||||
def remove_composite_values; end
|
||||
def replace_self(uri); end
|
||||
def split_path(path); end
|
||||
@ -51,10 +51,12 @@ class Bootsnap::InvalidConfiguration < ::StandardError; end
|
||||
|
||||
module Bootsnap::LoadPathCache
|
||||
class << self
|
||||
def enabled?; end
|
||||
def load_path_cache; end
|
||||
def loaded_features_index; end
|
||||
def setup(cache_path:, development_mode:); end
|
||||
def supported?; end
|
||||
def unload!; end
|
||||
end
|
||||
end
|
||||
|
||||
@ -63,7 +65,7 @@ Bootsnap::LoadPathCache::CACHED_EXTENSIONS = T.let(T.unsafe(nil), Array)
|
||||
class Bootsnap::LoadPathCache::Cache
|
||||
def initialize(store, path_obj, development_mode: T.unsafe(nil)); end
|
||||
|
||||
def find(feature, try_extensions: T.unsafe(nil)); end
|
||||
def find(feature); end
|
||||
def load_dir(dir); end
|
||||
def push_paths(sender, *paths); end
|
||||
def reinitialize(path_obj = T.unsafe(nil)); end
|
||||
@ -76,7 +78,7 @@ class Bootsnap::LoadPathCache::Cache
|
||||
def maybe_append_extension(feature); end
|
||||
def now; end
|
||||
def push_paths_locked(*paths); end
|
||||
def search_index(feature, try_extensions: T.unsafe(nil)); end
|
||||
def search_index(feature); end
|
||||
def stale?; end
|
||||
def try_ext(feature); end
|
||||
def try_index(feature); end
|
||||
@ -88,7 +90,8 @@ Bootsnap::LoadPathCache::Cache::BUILTIN_FEATURES = T.let(T.unsafe(nil), Hash)
|
||||
|
||||
module Bootsnap::LoadPathCache::ChangeObserver
|
||||
class << self
|
||||
def register(observer, arr); end
|
||||
def register(arr, observer); end
|
||||
def unregister(arr); end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1288,6 +1288,7 @@ class Nokogiri::XML::Reader
|
||||
def attribute(_arg0); end
|
||||
def attribute_at(_arg0); end
|
||||
def attribute_count; end
|
||||
def attribute_hash; end
|
||||
def attribute_nodes; end
|
||||
def attributes; end
|
||||
def attributes?; end
|
||||
@ -1430,6 +1430,7 @@ end
|
||||
class Parser::Source::Range
|
||||
include ::Comparable
|
||||
include ::RuboCop::AST::Ext::Range
|
||||
include ::RuboCop::Ext::Range
|
||||
|
||||
def initialize(source_buffer, begin_pos, end_pos); end
|
||||
|
||||
@ -150,7 +150,7 @@ class Rack::Builder
|
||||
def call(env); end
|
||||
def freeze_app; end
|
||||
def map(path, &block); end
|
||||
def run(app); end
|
||||
def run(app = T.unsafe(nil), &block); end
|
||||
def to_app; end
|
||||
def use(middleware, *args, &block); end
|
||||
def warmup(prc = T.unsafe(nil), &block); end
|
||||
@ -161,9 +161,9 @@ class Rack::Builder
|
||||
|
||||
class << self
|
||||
def app(default_app = T.unsafe(nil), &block); end
|
||||
def load_file(path, opts = T.unsafe(nil)); end
|
||||
def load_file(path); end
|
||||
def new_from_string(builder_script, file = T.unsafe(nil)); end
|
||||
def parse_file(config, opts = T.unsafe(nil)); end
|
||||
def parse_file(path); end
|
||||
end
|
||||
end
|
||||
|
||||
@ -221,7 +221,7 @@ class Rack::CommonLogger
|
||||
private
|
||||
|
||||
def extract_content_length(headers); end
|
||||
def log(env, status, header, began_at); end
|
||||
def log(env, status, response_headers, began_at); end
|
||||
end
|
||||
|
||||
Rack::CommonLogger::FORMAT = T.let(T.unsafe(nil), String)
|
||||
@ -281,6 +281,8 @@ class Rack::Deflater::GzipStream
|
||||
def write(data); end
|
||||
end
|
||||
|
||||
Rack::Deflater::GzipStream::BUFFER_LENGTH = T.let(T.unsafe(nil), Integer)
|
||||
|
||||
class Rack::Directory
|
||||
def initialize(root, app = T.unsafe(nil)); end
|
||||
|
||||
@ -319,7 +321,6 @@ class Rack::ETag
|
||||
private
|
||||
|
||||
def digest_body(body); end
|
||||
def etag_body?(body); end
|
||||
def etag_status?(status); end
|
||||
def skip_caching?(headers); end
|
||||
end
|
||||
@ -381,10 +382,6 @@ class Rack::Files
|
||||
def fail(status, body, headers = T.unsafe(nil)); end
|
||||
def filesize(path); end
|
||||
def mime_type(path, default_mime); end
|
||||
|
||||
class << self
|
||||
def method_added(name); end
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Files::ALLOWED_VERBS = T.let(T.unsafe(nil), Array)
|
||||
@ -426,40 +423,6 @@ Rack::HTTPS = T.let(T.unsafe(nil), String)
|
||||
Rack::HTTP_COOKIE = T.let(T.unsafe(nil), String)
|
||||
Rack::HTTP_HOST = T.let(T.unsafe(nil), String)
|
||||
Rack::HTTP_PORT = T.let(T.unsafe(nil), String)
|
||||
Rack::HTTP_VERSION = T.let(T.unsafe(nil), String)
|
||||
|
||||
module Rack::Handler
|
||||
class << self
|
||||
def default; end
|
||||
def get(server); end
|
||||
def pick(server_names); end
|
||||
def register(server, klass); end
|
||||
def try_require(prefix, const_name); end
|
||||
end
|
||||
end
|
||||
|
||||
class Rack::Handler::CGI
|
||||
class << self
|
||||
def run(app, **options); end
|
||||
def send_body(body); end
|
||||
def send_headers(status, headers); end
|
||||
def serve(app); end
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Handler::SERVER_NAMES = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class Rack::Handler::WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
|
||||
def initialize(server, app); end
|
||||
|
||||
def service(req, res); end
|
||||
|
||||
class << self
|
||||
def run(app, **options); end
|
||||
def shutdown; end
|
||||
def valid_options; end
|
||||
end
|
||||
end
|
||||
|
||||
class Rack::Head
|
||||
def initialize(app); end
|
||||
@ -467,36 +430,77 @@ class Rack::Head
|
||||
def call(env); end
|
||||
end
|
||||
|
||||
class Rack::Headers < ::Hash
|
||||
def [](key); end
|
||||
def []=(key, value); end
|
||||
def assoc(key); end
|
||||
def compare_by_identity; end
|
||||
def delete(key); end
|
||||
def dig(key, *a); end
|
||||
def fetch(key, *default, &block); end
|
||||
def fetch_values(*a); end
|
||||
def has_key?(key); end
|
||||
def include?(key); end
|
||||
def invert; end
|
||||
def key?(key); end
|
||||
def member?(key); end
|
||||
def merge(hash, &block); end
|
||||
def merge!(hash, &block); end
|
||||
def reject(&block); end
|
||||
def replace(hash); end
|
||||
def select(&block); end
|
||||
def slice(*a); end
|
||||
def store(key, value); end
|
||||
def to_proc; end
|
||||
def transform_keys(&block); end
|
||||
def transform_keys!; end
|
||||
def transform_values(&block); end
|
||||
def update(hash, &block); end
|
||||
def values_at(*keys); end
|
||||
|
||||
private
|
||||
|
||||
def downcase_key(key); end
|
||||
|
||||
class << self
|
||||
def [](*items); end
|
||||
end
|
||||
end
|
||||
|
||||
Rack::LINK = T.let(T.unsafe(nil), String)
|
||||
|
||||
class Rack::Lint
|
||||
include ::Rack::Lint::Assertion
|
||||
|
||||
def initialize(app); end
|
||||
|
||||
def _call(env); end
|
||||
def call(env = T.unsafe(nil)); end
|
||||
end
|
||||
|
||||
class Rack::Lint::LintError < ::RuntimeError; end
|
||||
|
||||
class Rack::Lint::Wrapper
|
||||
def initialize(app, env); end
|
||||
|
||||
def call(stream); end
|
||||
def check_content_length(status, headers); end
|
||||
def check_content_type(status, headers); end
|
||||
def check_env(env); end
|
||||
def check_environment(env); end
|
||||
def check_error(error); end
|
||||
def check_headers(header); end
|
||||
def check_header_value(key, value); end
|
||||
def check_headers(headers); end
|
||||
def check_hijack(env); end
|
||||
def check_hijack_response(headers, env); end
|
||||
def check_input(input); end
|
||||
def check_status(status); end
|
||||
def close; end
|
||||
def each; end
|
||||
def verify_content_length(bytes); end
|
||||
def respond_to?(name, *_arg1); end
|
||||
def response; end
|
||||
def to_ary; end
|
||||
def verify_content_length(size); end
|
||||
def verify_to_path; end
|
||||
end
|
||||
|
||||
module Rack::Lint::Assertion
|
||||
def assert(message); end
|
||||
end
|
||||
|
||||
class Rack::Lint::ErrorWrapper
|
||||
include ::Rack::Lint::Assertion
|
||||
|
||||
class Rack::Lint::Wrapper::ErrorWrapper
|
||||
def initialize(error); end
|
||||
|
||||
def close(*args); end
|
||||
@ -505,38 +509,31 @@ class Rack::Lint::ErrorWrapper
|
||||
def write(str); end
|
||||
end
|
||||
|
||||
class Rack::Lint::HijackWrapper
|
||||
include ::Rack::Lint::Assertion
|
||||
extend ::Forwardable
|
||||
|
||||
def initialize(io); end
|
||||
|
||||
def close(*args, &block); end
|
||||
def close_read(*args, &block); end
|
||||
def close_write(*args, &block); end
|
||||
def closed?(*args, &block); end
|
||||
def flush(*args, &block); end
|
||||
def read(*args, &block); end
|
||||
def read_nonblock(*args, &block); end
|
||||
def write(*args, &block); end
|
||||
def write_nonblock(*args, &block); end
|
||||
end
|
||||
|
||||
Rack::Lint::HijackWrapper::REQUIRED_METHODS = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class Rack::Lint::InputWrapper
|
||||
include ::Rack::Lint::Assertion
|
||||
|
||||
class Rack::Lint::Wrapper::InputWrapper
|
||||
def initialize(input); end
|
||||
|
||||
def close(*args); end
|
||||
def each(*args); end
|
||||
def gets(*args); end
|
||||
def read(*args); end
|
||||
def rewind(*args); end
|
||||
end
|
||||
|
||||
class Rack::Lint::LintError < ::RuntimeError; end
|
||||
class Rack::Lint::Wrapper::StreamWrapper
|
||||
extend ::Forwardable
|
||||
|
||||
def initialize(stream); end
|
||||
|
||||
def <<(*args, &block); end
|
||||
def close(*args, &block); end
|
||||
def close_read(*args, &block); end
|
||||
def close_write(*args, &block); end
|
||||
def closed?(*args, &block); end
|
||||
def flush(*args, &block); end
|
||||
def read(*args, &block); end
|
||||
def write(*args, &block); end
|
||||
end
|
||||
|
||||
Rack::Lint::Wrapper::StreamWrapper::REQUIRED_METHODS = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class Rack::Lock
|
||||
def initialize(app, mutex = T.unsafe(nil)); end
|
||||
@ -653,7 +650,7 @@ end
|
||||
module Rack::Multipart
|
||||
class << self
|
||||
def build_multipart(params, first = T.unsafe(nil)); end
|
||||
def extract_multipart(req, params = T.unsafe(nil)); end
|
||||
def extract_multipart(request, params = T.unsafe(nil)); end
|
||||
def parse_multipart(env, params = T.unsafe(nil)); end
|
||||
end
|
||||
end
|
||||
@ -671,6 +668,8 @@ Rack::Multipart::EXTENDED_OTHER_NAME = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Multipart::EXTENDED_OTHER_PARAMETER = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Multipart::EXTENDED_OTHER_VALUE = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Multipart::EXTENDED_PARAMETER = T.let(T.unsafe(nil), Regexp)
|
||||
class Rack::Multipart::EmptyContentError < ::EOFError; end
|
||||
class Rack::Multipart::Error < ::StandardError; end
|
||||
|
||||
class Rack::Multipart::Generator
|
||||
def initialize(params, first = T.unsafe(nil)); end
|
||||
@ -695,21 +694,21 @@ class Rack::Multipart::MultipartPartLimitError < ::Errno::EMFILE; end
|
||||
class Rack::Multipart::Parser
|
||||
def initialize(boundary, tempfile, bufsize, query_parser); end
|
||||
|
||||
def on_read(content); end
|
||||
def parse(io); end
|
||||
def result; end
|
||||
def state; end
|
||||
|
||||
private
|
||||
|
||||
def consume_boundary; end
|
||||
def full_boundary; end
|
||||
def dequote(str); end
|
||||
def get_filename(head); end
|
||||
def handle_consume_token; end
|
||||
def handle_empty_content!(content); end
|
||||
def handle_fast_forward; end
|
||||
def handle_mime_body; end
|
||||
def handle_mime_head; end
|
||||
def run_parser; end
|
||||
def read_data(io, outbuf); end
|
||||
def tag_multipart_encoding(filename, content_type, name, body); end
|
||||
|
||||
class << self
|
||||
@ -718,14 +717,12 @@ class Rack::Multipart::Parser
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Multipart::Parser::BOUNDARY_REGEX = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Multipart::Parser::BUFSIZE = T.let(T.unsafe(nil), Integer)
|
||||
|
||||
class Rack::Multipart::Parser::BoundedIO
|
||||
def initialize(io, content_length); end
|
||||
|
||||
def read(size, outbuf = T.unsafe(nil)); end
|
||||
def rewind; end
|
||||
end
|
||||
|
||||
Rack::Multipart::Parser::CHARSET = T.let(T.unsafe(nil), String)
|
||||
@ -807,23 +804,30 @@ class Rack::NullLogger
|
||||
def datetime_format; end
|
||||
def datetime_format=(datetime_format); end
|
||||
def debug(progname = T.unsafe(nil), &block); end
|
||||
def debug!; end
|
||||
def debug?; end
|
||||
def error(progname = T.unsafe(nil), &block); end
|
||||
def error!; end
|
||||
def error?; end
|
||||
def fatal(progname = T.unsafe(nil), &block); end
|
||||
def fatal!; end
|
||||
def fatal?; end
|
||||
def formatter; end
|
||||
def formatter=(formatter); end
|
||||
def info(progname = T.unsafe(nil), &block); end
|
||||
def info!; end
|
||||
def info?; end
|
||||
def level; end
|
||||
def level=(level); end
|
||||
def log(severity, message = T.unsafe(nil), progname = T.unsafe(nil), &block); end
|
||||
def progname; end
|
||||
def progname=(progname); end
|
||||
def reopen(logdev = T.unsafe(nil)); end
|
||||
def sev_threshold; end
|
||||
def sev_threshold=(sev_threshold); end
|
||||
def unknown(progname = T.unsafe(nil), &block); end
|
||||
def warn(progname = T.unsafe(nil), &block); end
|
||||
def warn!; end
|
||||
def warn?; end
|
||||
end
|
||||
|
||||
@ -835,25 +839,24 @@ Rack::PUT = T.let(T.unsafe(nil), String)
|
||||
Rack::QUERY_STRING = T.let(T.unsafe(nil), String)
|
||||
|
||||
class Rack::QueryParser
|
||||
def initialize(params_class, key_space_limit, param_depth_limit); end
|
||||
def initialize(params_class, _key_space_limit = T.unsafe(nil), param_depth_limit); end
|
||||
|
||||
def key_space_limit; end
|
||||
def make_params; end
|
||||
def new_depth_limit(param_depth_limit); end
|
||||
def new_space_limit(key_space_limit); end
|
||||
def normalize_params(params, name, v, depth); end
|
||||
def normalize_params(params, name, v, _depth = T.unsafe(nil)); end
|
||||
def param_depth_limit; end
|
||||
def parse_nested_query(qs, d = T.unsafe(nil)); end
|
||||
def parse_query(qs, d = T.unsafe(nil), &unescaper); end
|
||||
def parse_nested_query(qs, separator = T.unsafe(nil)); end
|
||||
def parse_query(qs, separator = T.unsafe(nil), &unescaper); end
|
||||
|
||||
private
|
||||
|
||||
def _normalize_params(params, name, v, depth); end
|
||||
def params_hash_has_key?(hash, key); end
|
||||
def params_hash_type?(obj); end
|
||||
def unescape(s); end
|
||||
|
||||
class << self
|
||||
def make_default(key_space_limit, param_depth_limit); end
|
||||
def make_default(_key_space_limit = T.unsafe(nil), param_depth_limit); end
|
||||
end
|
||||
end
|
||||
|
||||
@ -863,7 +866,7 @@ class Rack::QueryParser::InvalidParameterError < ::ArgumentError; end
|
||||
class Rack::QueryParser::ParameterTypeError < ::TypeError; end
|
||||
|
||||
class Rack::QueryParser::Params
|
||||
def initialize(limit); end
|
||||
def initialize; end
|
||||
|
||||
def [](key); end
|
||||
def []=(key, value); end
|
||||
@ -875,15 +878,12 @@ end
|
||||
class Rack::QueryParser::ParamsTooDeepError < ::RangeError; end
|
||||
Rack::RACK_ERRORS = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_HIJACK = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_HIJACK_IO = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_INPUT = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_IS_HIJACK = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_LOGGER = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_METHODOVERRIDE_ORIGINAL_METHOD = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_MULTIPART_BUFFER_SIZE = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_MULTIPART_TEMPFILE_FACTORY = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_MULTIPROCESS = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_MULTITHREAD = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_RECURSIVE_INCLUDE = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_REQUEST_COOKIE_HASH = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_REQUEST_COOKIE_STRING = T.let(T.unsafe(nil), String)
|
||||
@ -892,10 +892,9 @@ Rack::RACK_REQUEST_FORM_INPUT = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_REQUEST_FORM_VARS = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_REQUEST_QUERY_HASH = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_REQUEST_QUERY_STRING = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_RUNONCE = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_RESPONSE_FINISHED = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_SESSION = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_SESSION_OPTIONS = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_SESSION_UNPACKED_COOKIE_DATA = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_SHOWSTATUS_DETAIL = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_TEMPFILES = T.let(T.unsafe(nil), String)
|
||||
Rack::RACK_URL_SCHEME = T.let(T.unsafe(nil), String)
|
||||
@ -941,8 +940,12 @@ class Rack::Request
|
||||
def xhr?; end
|
||||
|
||||
class << self
|
||||
def forwarded_priority; end
|
||||
def forwarded_priority=(_arg0); end
|
||||
def ip_filter; end
|
||||
def ip_filter=(_arg0); end
|
||||
def x_forwarded_proto_priority; end
|
||||
def x_forwarded_proto_priority=(_arg0); end
|
||||
end
|
||||
end
|
||||
|
||||
@ -997,7 +1000,6 @@ module Rack::Request::Helpers
|
||||
def logger; end
|
||||
def media_type; end
|
||||
def media_type_params; end
|
||||
def multithread?; end
|
||||
def options?; end
|
||||
def params; end
|
||||
def parseable_data?; end
|
||||
@ -1034,8 +1036,9 @@ module Rack::Request::Helpers
|
||||
|
||||
def allowed_scheme(header); end
|
||||
def default_session; end
|
||||
def extract_proto_header(header); end
|
||||
def forwarded_priority; end
|
||||
def forwarded_scheme; end
|
||||
def get_http_forwarded(token); end
|
||||
def parse_http_accept_header(header); end
|
||||
def parse_multipart; end
|
||||
def parse_query(qs, d = T.unsafe(nil)); end
|
||||
@ -1044,11 +1047,14 @@ module Rack::Request::Helpers
|
||||
def split_authority(authority); end
|
||||
def split_header(value); end
|
||||
def wrap_ipv6(host); end
|
||||
def x_forwarded_proto_priority; end
|
||||
end
|
||||
|
||||
Rack::Request::Helpers::AUTHORITY = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Request::Helpers::DEFAULT_PORTS = T.let(T.unsafe(nil), Hash)
|
||||
Rack::Request::Helpers::FORM_DATA_MEDIA_TYPES = T.let(T.unsafe(nil), Array)
|
||||
Rack::Request::Helpers::FORWARDED_SCHEME_HEADERS = T.let(T.unsafe(nil), Hash)
|
||||
Rack::Request::Helpers::HTTP_FORWARDED = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::HTTP_X_FORWARDED_FOR = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::HTTP_X_FORWARDED_HOST = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::HTTP_X_FORWARDED_PORT = T.let(T.unsafe(nil), String)
|
||||
@ -1056,7 +1062,6 @@ Rack::Request::Helpers::HTTP_X_FORWARDED_PROTO = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::HTTP_X_FORWARDED_SCHEME = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::HTTP_X_FORWARDED_SSL = T.let(T.unsafe(nil), String)
|
||||
Rack::Request::Helpers::PARSEABLE_DATA_MEDIA_TYPES = T.let(T.unsafe(nil), Array)
|
||||
Rack::Request::SCHEME_WHITELIST = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class Rack::Response
|
||||
include ::Rack::Response::Helpers
|
||||
@ -1064,7 +1069,7 @@ class Rack::Response
|
||||
def initialize(body = T.unsafe(nil), status = T.unsafe(nil), headers = T.unsafe(nil)); end
|
||||
|
||||
def [](key); end
|
||||
def []=(key, v); end
|
||||
def []=(key, value); end
|
||||
def body; end
|
||||
def body=(_arg0); end
|
||||
def chunked?; end
|
||||
@ -1080,7 +1085,7 @@ class Rack::Response
|
||||
def length; end
|
||||
def length=(_arg0); end
|
||||
def redirect(target, status = T.unsafe(nil)); end
|
||||
def set_header(key, v); end
|
||||
def set_header(key, value); end
|
||||
def status; end
|
||||
def status=(_arg0); end
|
||||
def to_a(&block); end
|
||||
@ -1095,11 +1100,11 @@ Rack::Response::CHUNKED = T.let(T.unsafe(nil), String)
|
||||
|
||||
module Rack::Response::Helpers
|
||||
def accepted?; end
|
||||
def add_header(key, v); end
|
||||
def add_header(key, value); end
|
||||
def bad_request?; end
|
||||
def cache!(duration = T.unsafe(nil), directive: T.unsafe(nil)); end
|
||||
def cache_control; end
|
||||
def cache_control=(v); end
|
||||
def cache_control=(value); end
|
||||
def client_error?; end
|
||||
def content_length; end
|
||||
def content_type; end
|
||||
@ -1108,7 +1113,7 @@ module Rack::Response::Helpers
|
||||
def delete_cookie(key, value = T.unsafe(nil)); end
|
||||
def do_not_cache!; end
|
||||
def etag; end
|
||||
def etag=(v); end
|
||||
def etag=(value); end
|
||||
def forbidden?; end
|
||||
def include?(header); end
|
||||
def informational?; end
|
||||
@ -1120,15 +1125,17 @@ module Rack::Response::Helpers
|
||||
def method_not_allowed?; end
|
||||
def moved_permanently?; end
|
||||
def no_content?; end
|
||||
def not_acceptable?; end
|
||||
def not_found?; end
|
||||
def ok?; end
|
||||
def precondition_failed?; end
|
||||
def redirect?; end
|
||||
def redirection?; end
|
||||
def request_timeout?; end
|
||||
def server_error?; end
|
||||
def set_cookie(key, value); end
|
||||
def set_cookie_header; end
|
||||
def set_cookie_header=(v); end
|
||||
def set_cookie_header=(value); end
|
||||
def successful?; end
|
||||
def unauthorized?; end
|
||||
def unprocessable?; end
|
||||
@ -1148,7 +1155,7 @@ class Rack::Response::Raw
|
||||
def get_header(key); end
|
||||
def has_header?(key); end
|
||||
def headers; end
|
||||
def set_header(key, v); end
|
||||
def set_header(key, value); end
|
||||
def status; end
|
||||
def status=(_arg0); end
|
||||
end
|
||||
@ -1163,6 +1170,7 @@ class Rack::RewindableInput
|
||||
def gets; end
|
||||
def read(*args); end
|
||||
def rewind; end
|
||||
def size; end
|
||||
|
||||
private
|
||||
|
||||
@ -1170,6 +1178,12 @@ class Rack::RewindableInput
|
||||
def make_rewindable; end
|
||||
end
|
||||
|
||||
class Rack::RewindableInput::Middleware
|
||||
def initialize(app); end
|
||||
|
||||
def call(env); end
|
||||
end
|
||||
|
||||
class Rack::Runtime
|
||||
def initialize(app, name = T.unsafe(nil)); end
|
||||
|
||||
@ -1195,238 +1209,6 @@ class Rack::Sendfile
|
||||
def variation(env); end
|
||||
end
|
||||
|
||||
class Rack::Server
|
||||
def initialize(options = T.unsafe(nil)); end
|
||||
|
||||
def app; end
|
||||
def default_options; end
|
||||
def middleware; end
|
||||
def options; end
|
||||
def options=(_arg0); end
|
||||
def server; end
|
||||
def start(&block); end
|
||||
|
||||
private
|
||||
|
||||
def build_app(app); end
|
||||
def build_app_and_options_from_config; end
|
||||
def build_app_from_string; end
|
||||
def check_pid!; end
|
||||
def daemonize_app; end
|
||||
def handle_profiling(heapfile, profile_mode, filename); end
|
||||
def make_profile_name(filename); end
|
||||
def opt_parser; end
|
||||
def parse_options(args); end
|
||||
def pidfile_process_status; end
|
||||
def wrapped_app; end
|
||||
def write_pid; end
|
||||
|
||||
class << self
|
||||
def default_middleware_by_environment; end
|
||||
def logging_middleware; end
|
||||
def middleware; end
|
||||
def start(options = T.unsafe(nil)); end
|
||||
end
|
||||
end
|
||||
|
||||
class Rack::Server::Options
|
||||
def handler_opts(options); end
|
||||
def parse!(args); end
|
||||
end
|
||||
|
||||
module Rack::Session; end
|
||||
module Rack::Session::Abstract; end
|
||||
|
||||
class Rack::Session::Abstract::ID < ::Rack::Session::Abstract::Persisted
|
||||
def delete_session(req, sid, options); end
|
||||
def find_session(req, sid); end
|
||||
def write_session(req, sid, session, options); end
|
||||
|
||||
class << self
|
||||
def inherited(klass); end
|
||||
end
|
||||
end
|
||||
|
||||
class Rack::Session::Abstract::Persisted
|
||||
def initialize(app, options = T.unsafe(nil)); end
|
||||
|
||||
def call(env); end
|
||||
def commit_session(req, res); end
|
||||
def context(env, app = T.unsafe(nil)); end
|
||||
def default_options; end
|
||||
def key; end
|
||||
def sid_secure; end
|
||||
|
||||
private
|
||||
|
||||
def commit_session?(req, session, options); end
|
||||
def cookie_value(data); end
|
||||
def current_session_id(req); end
|
||||
def delete_session(req, sid, options); end
|
||||
def extract_session_id(request); end
|
||||
def find_session(env, sid); end
|
||||
def force_options?(options); end
|
||||
def forced_session_update?(session, options); end
|
||||
def generate_sid(secure = T.unsafe(nil)); end
|
||||
def initialize_sid; end
|
||||
def load_session(req); end
|
||||
def loaded_session?(session); end
|
||||
def make_request(env); end
|
||||
def prepare_session(req); end
|
||||
def security_matches?(request, options); end
|
||||
def session_class; end
|
||||
def session_exists?(req); end
|
||||
def set_cookie(request, res, cookie); end
|
||||
def write_session(req, sid, session, options); end
|
||||
end
|
||||
|
||||
Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS = T.let(T.unsafe(nil), Hash)
|
||||
|
||||
class Rack::Session::Abstract::PersistedSecure < ::Rack::Session::Abstract::Persisted
|
||||
def extract_session_id(*_arg0); end
|
||||
def generate_sid(*_arg0); end
|
||||
|
||||
private
|
||||
|
||||
def cookie_value(data); end
|
||||
def session_class; end
|
||||
end
|
||||
|
||||
class Rack::Session::Abstract::PersistedSecure::SecureSessionHash < ::Rack::Session::Abstract::SessionHash
|
||||
def [](key); end
|
||||
end
|
||||
|
||||
class Rack::Session::Abstract::SessionHash
|
||||
include ::Enumerable
|
||||
|
||||
def initialize(store, req); end
|
||||
|
||||
def [](key); end
|
||||
def []=(key, value); end
|
||||
def clear; end
|
||||
def delete(key); end
|
||||
def destroy; end
|
||||
def dig(key, *keys); end
|
||||
def each(&block); end
|
||||
def empty?; end
|
||||
def exists?; end
|
||||
def fetch(key, default = T.unsafe(nil), &block); end
|
||||
def has_key?(key); end
|
||||
def id; end
|
||||
def id=(_arg0); end
|
||||
def include?(key); end
|
||||
def inspect; end
|
||||
def key?(key); end
|
||||
def keys; end
|
||||
def loaded?; end
|
||||
def merge!(hash); end
|
||||
def options; end
|
||||
def replace(hash); end
|
||||
def store(key, value); end
|
||||
def to_hash; end
|
||||
def update(hash); end
|
||||
def values; end
|
||||
|
||||
private
|
||||
|
||||
def load!; end
|
||||
def load_for_read!; end
|
||||
def load_for_write!; end
|
||||
def stringify_keys(other); end
|
||||
|
||||
class << self
|
||||
def find(req); end
|
||||
def set(req, session); end
|
||||
def set_options(req, options); end
|
||||
end
|
||||
end
|
||||
|
||||
Rack::Session::Abstract::SessionHash::Unspecified = T.let(T.unsafe(nil), Object)
|
||||
|
||||
class Rack::Session::Cookie < ::Rack::Session::Abstract::PersistedSecure
|
||||
def initialize(app, options = T.unsafe(nil)); end
|
||||
|
||||
def coder; end
|
||||
|
||||
private
|
||||
|
||||
def delete_session(req, session_id, options); end
|
||||
def digest_match?(data, digest); end
|
||||
def extract_session_id(request); end
|
||||
def find_session(req, sid); end
|
||||
def generate_hmac(data, secret); end
|
||||
def persistent_session_id!(data, sid = T.unsafe(nil)); end
|
||||
def secure?(options); end
|
||||
def unpacked_cookie_data(request); end
|
||||
def write_session(req, session_id, session, options); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::Base64
|
||||
def decode(str); end
|
||||
def encode(str); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::Base64::JSON < ::Rack::Session::Cookie::Base64
|
||||
def decode(str); end
|
||||
def encode(obj); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::Base64::Marshal < ::Rack::Session::Cookie::Base64
|
||||
def decode(str); end
|
||||
def encode(str); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::Base64::ZipJSON < ::Rack::Session::Cookie::Base64
|
||||
def decode(str); end
|
||||
def encode(obj); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::Identity
|
||||
def decode(str); end
|
||||
def encode(str); end
|
||||
end
|
||||
|
||||
class Rack::Session::Cookie::SessionId
|
||||
def initialize(session_id, cookie_value); end
|
||||
|
||||
def cookie_value; end
|
||||
end
|
||||
|
||||
class Rack::Session::Pool < ::Rack::Session::Abstract::PersistedSecure
|
||||
def initialize(app, options = T.unsafe(nil)); end
|
||||
|
||||
def delete_session(req, session_id, options); end
|
||||
def find_session(req, sid); end
|
||||
def generate_sid; end
|
||||
def mutex; end
|
||||
def pool; end
|
||||
def with_lock(req); end
|
||||
def write_session(req, session_id, new_session, options); end
|
||||
|
||||
private
|
||||
|
||||
def get_session_with_fallback(sid); end
|
||||
end
|
||||
|
||||
Rack::Session::Pool::DEFAULT_OPTIONS = T.let(T.unsafe(nil), Hash)
|
||||
|
||||
class Rack::Session::SessionId
|
||||
def initialize(public_id); end
|
||||
|
||||
def cookie_value; end
|
||||
def empty?; end
|
||||
def inspect; end
|
||||
def private_id; end
|
||||
def public_id; end
|
||||
def to_s; end
|
||||
|
||||
private
|
||||
|
||||
def hash_sid(sid); end
|
||||
end
|
||||
|
||||
Rack::Session::SessionId::ID_VERSION = T.let(T.unsafe(nil), Integer)
|
||||
|
||||
class Rack::ShowExceptions
|
||||
def initialize(app); end
|
||||
|
||||
@ -1498,22 +1280,25 @@ module Rack::Utils
|
||||
def byte_ranges(env, size); end
|
||||
def clean_path_info(path_info); end
|
||||
def clock_time; end
|
||||
def delete_cookie_header!(header, key, value = T.unsafe(nil)); end
|
||||
def delete_cookie_header!(headers, key, value = T.unsafe(nil)); end
|
||||
def delete_set_cookie_header(key, value = T.unsafe(nil)); end
|
||||
def delete_set_cookie_header!(header, key, value = T.unsafe(nil)); end
|
||||
def escape(s); end
|
||||
def escape_html(string); end
|
||||
def escape_path(s); end
|
||||
def forwarded_values(forwarded_header); end
|
||||
def get_byte_ranges(http_range, size); end
|
||||
def make_delete_cookie_header(header, key, value); end
|
||||
def parse_cookies(env); end
|
||||
def parse_cookies_header(header); end
|
||||
def parse_cookies_header(value); end
|
||||
def parse_nested_query(qs, d = T.unsafe(nil)); end
|
||||
def parse_query(qs, d = T.unsafe(nil), &unescaper); end
|
||||
def q_values(q_value_header); end
|
||||
def rfc2109(time); end
|
||||
def rfc2822(time); end
|
||||
def secure_compare(a, b); end
|
||||
def select_best_encoding(available_encodings, accept_encoding); end
|
||||
def set_cookie_header!(header, key, value); end
|
||||
def set_cookie_header(key, value); end
|
||||
def set_cookie_header!(headers, key, value); end
|
||||
def status_code(status); end
|
||||
def unescape(s, encoding = T.unsafe(nil)); end
|
||||
def unescape_path(s); end
|
||||
@ -1530,10 +1315,13 @@ module Rack::Utils
|
||||
def clock_time; end
|
||||
def default_query_parser; end
|
||||
def default_query_parser=(_arg0); end
|
||||
def delete_cookie_header!(header, key, value = T.unsafe(nil)); end
|
||||
def delete_cookie_header!(headers, key, value = T.unsafe(nil)); end
|
||||
def delete_set_cookie_header(key, value = T.unsafe(nil)); end
|
||||
def delete_set_cookie_header!(header, key, value = T.unsafe(nil)); end
|
||||
def escape(s); end
|
||||
def escape_html(string); end
|
||||
def escape_path(s); end
|
||||
def forwarded_values(forwarded_header); end
|
||||
def get_byte_ranges(http_range, size); end
|
||||
def key_space_limit; end
|
||||
def key_space_limit=(v); end
|
||||
@ -1543,15 +1331,15 @@ module Rack::Utils
|
||||
def param_depth_limit; end
|
||||
def param_depth_limit=(v); end
|
||||
def parse_cookies(env); end
|
||||
def parse_cookies_header(header); end
|
||||
def parse_cookies_header(value); end
|
||||
def parse_nested_query(qs, d = T.unsafe(nil)); end
|
||||
def parse_query(qs, d = T.unsafe(nil), &unescaper); end
|
||||
def q_values(q_value_header); end
|
||||
def rfc2109(time); end
|
||||
def rfc2822(time); end
|
||||
def secure_compare(a, b); end
|
||||
def select_best_encoding(available_encodings, accept_encoding); end
|
||||
def set_cookie_header!(header, key, value); end
|
||||
def set_cookie_header(key, value); end
|
||||
def set_cookie_header!(headers, key, value); end
|
||||
def status_code(status); end
|
||||
def unescape(s, encoding = T.unsafe(nil)); end
|
||||
def unescape_path(s); end
|
||||
@ -1577,32 +1365,10 @@ Rack::Utils::ESCAPE_HTML_PATTERN = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Utils::HTTP_STATUS_CODES = T.let(T.unsafe(nil), Hash)
|
||||
|
||||
class Rack::Utils::HeaderHash < ::Hash
|
||||
def initialize(hash = T.unsafe(nil)); end
|
||||
|
||||
def [](k); end
|
||||
def []=(k, v); end
|
||||
def clear; end
|
||||
def delete(k); end
|
||||
def each; end
|
||||
def has_key?(k); end
|
||||
def include?(k); end
|
||||
def key?(k); end
|
||||
def member?(k); end
|
||||
def merge(other); end
|
||||
def merge!(other); end
|
||||
def replace(other); end
|
||||
def to_hash; end
|
||||
|
||||
protected
|
||||
|
||||
def names; end
|
||||
|
||||
private
|
||||
|
||||
def initialize_copy(other); end
|
||||
|
||||
class << self
|
||||
def [](headers); end
|
||||
def allocate; end
|
||||
def new(hash = T.unsafe(nil)); end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1611,14 +1377,8 @@ Rack::Utils::KeySpaceConstrainedParams = Rack::QueryParser::Params
|
||||
Rack::Utils::NULL_BYTE = T.let(T.unsafe(nil), String)
|
||||
Rack::Utils::PATH_SEPS = T.let(T.unsafe(nil), Regexp)
|
||||
Rack::Utils::ParameterTypeError = Rack::QueryParser::ParameterTypeError
|
||||
Rack::Utils::RFC2822_DAY_NAME = T.let(T.unsafe(nil), Array)
|
||||
Rack::Utils::RFC2822_MONTH_NAME = T.let(T.unsafe(nil), Array)
|
||||
Rack::Utils::ParamsTooDeepError = Rack::QueryParser::ParamsTooDeepError
|
||||
Rack::Utils::STATUS_WITH_NO_ENTITY_BODY = T.let(T.unsafe(nil), Hash)
|
||||
Rack::Utils::SYMBOL_TO_STATUS_CODE = T.let(T.unsafe(nil), Hash)
|
||||
Rack::VERSION = T.let(T.unsafe(nil), Array)
|
||||
|
||||
class WEBrick::HTTPResponse
|
||||
def rack; end
|
||||
def rack=(_arg0); end
|
||||
def setup_header; end
|
||||
end
|
||||
Rack::VERSION_STRING = T.let(T.unsafe(nil), String)
|
||||
@ -875,6 +875,7 @@ class RSpec::Matchers::BuiltIn::ContainExactly < ::RSpec::Matchers::BuiltIn::Bas
|
||||
def description; end
|
||||
def failure_message; end
|
||||
def failure_message_when_negated; end
|
||||
def matches?(actual); end
|
||||
|
||||
private
|
||||
|
||||
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