Merge branch 'master' into ask-test
# Conflicts: # Library/Homebrew/vendor/bundle/bundler/setup.rb
This commit is contained in:
commit
f0f2e59fb7
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: New issue for Reproducible Bug
|
||||
description: "If you're sure it's reproducible and not just your machine: submit an issue so we can investigate."
|
||||
labels: [bug]
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: New issue for Feature Suggestion
|
||||
description: Request our thoughts on your suggestion for a new feature for Homebrew.
|
||||
labels: features
|
||||
type: "Feature"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
@ -14,6 +14,7 @@ updates:
|
||||
artifacts:
|
||||
patterns:
|
||||
- actions/*-artifact
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: bundler
|
||||
directory: /Library/Homebrew
|
||||
@ -25,6 +26,7 @@ updates:
|
||||
sorbet:
|
||||
patterns:
|
||||
- "sorbet*"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
@ -32,6 +34,7 @@ updates:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: all
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
@ -39,6 +42,7 @@ updates:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: all
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: devcontainers
|
||||
directory: /
|
||||
@ -46,6 +50,7 @@ updates:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: all
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /
|
||||
@ -53,6 +58,7 @@ updates:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: all
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /Library/Homebrew/formula-analytics/
|
||||
@ -60,3 +66,4 @@ updates:
|
||||
interval: daily
|
||||
allow:
|
||||
- dependency-type: all
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
6
.github/workflows/actionlint.yml
vendored
6
.github/workflows/actionlint.yml
vendored
@ -57,7 +57,7 @@ jobs:
|
||||
zizmor --format sarif . > results.sarif || true
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: results.sarif
|
||||
path: results.sarif
|
||||
@ -72,13 +72,13 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Download SARIF file
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
name: results.sarif
|
||||
path: results.sarif
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: zizmor
|
||||
|
||||
2
.github/workflows/autogenerated-files.yml
vendored
2
.github/workflows/autogenerated-files.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
test-bot: true
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
|
||||
4
.github/workflows/codeql-analysis.yml
vendored
4
.github/workflows/codeql-analysis.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||
uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
|
||||
with:
|
||||
languages: ruby
|
||||
config: |
|
||||
@ -36,4 +36,4 @@ jobs:
|
||||
- Library/Homebrew/vendor
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
||||
uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
|
||||
|
||||
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
||||
run: git fetch origin master
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
with:
|
||||
cache-binary: false
|
||||
|
||||
@ -112,7 +112,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
@ -141,7 +141,7 @@ jobs:
|
||||
|
||||
- name: Deploy the tagged Docker image
|
||||
if: steps.attributes.outputs.push == 'true'
|
||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
||||
run: vale docs/
|
||||
|
||||
- name: Install Ruby
|
||||
uses: ruby/setup-ruby@d781c1b4ed31764801bfae177617bb0446f5ef8d # v1.218.0
|
||||
uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0
|
||||
with:
|
||||
bundler-cache: true
|
||||
working-directory: docs
|
||||
|
||||
8
.github/workflows/pkg-installer.yml
vendored
8
.github/workflows/pkg-installer.yml
vendored
@ -133,12 +133,12 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Generate build provenance
|
||||
uses: actions/attest-build-provenance@520d128f165991a6c774bcb264f323e3d70747f4 # v2.2.0
|
||||
uses: actions/attest-build-provenance@bd77c077858b8d561b7a36cbe48ef4cc642ca39d # v2.2.2
|
||||
with:
|
||||
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||
|
||||
- name: Upload installer to GitHub Actions
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||
path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||
@ -160,7 +160,7 @@ jobs:
|
||||
name: macos-15-arm64
|
||||
steps:
|
||||
- name: Download installer from GitHub Actions
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
name: "${{ needs.build.outputs.installer_path }}"
|
||||
|
||||
@ -213,7 +213,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Download installer from GitHub Actions
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
name: "${{ needs.build.outputs.installer_path }}"
|
||||
|
||||
|
||||
2
.github/workflows/rubydoc.yml
vendored
2
.github/workflows/rubydoc.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Ruby
|
||||
uses: ruby/setup-ruby@d781c1b4ed31764801bfae177617bb0446f5ef8d # v1.218.0
|
||||
uses: ruby/setup-ruby@32110d4e311bd8996b2a82bf2a43b714ccc91777 # v1.221.0
|
||||
with:
|
||||
bundler-cache: true
|
||||
working-directory: rubydoc
|
||||
|
||||
@ -50,7 +50,7 @@ jobs:
|
||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
|
||||
27
.github/workflows/tests.yml
vendored
27
.github/workflows/tests.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
test-bot: false
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-syntax-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -53,7 +53,7 @@ jobs:
|
||||
run: brew install shellcheck shfmt
|
||||
|
||||
- name: Cache style cache
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ~/.cache/Homebrew/style
|
||||
key: syntax-style-cache-${{ github.sha }}
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
test-bot: true
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-tap-syntax-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -102,7 +102,7 @@ jobs:
|
||||
run: brew install-bundler-gems --groups=style
|
||||
|
||||
- name: Cache style cache
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ~/.cache/Homebrew/style
|
||||
key: tap-syntax-style-cache-${{ github.sha }}
|
||||
@ -242,6 +242,7 @@ jobs:
|
||||
name: ${{ matrix.name }}
|
||||
needs: syntax
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
container: ${{ matrix.container }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@ -259,7 +260,8 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
- name: tests (Ubuntu 20.04)
|
||||
test-flags: --coverage
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu20.04:latest
|
||||
- name: tests (macOS 13 x86_64)
|
||||
test-flags: --coverage
|
||||
runs-on: macos-13
|
||||
@ -279,7 +281,7 @@ jobs:
|
||||
test-bot: false
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ matrix.runs-on }}-tests-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -294,7 +296,7 @@ jobs:
|
||||
run: mkdir tests
|
||||
|
||||
- name: Cache parallel tests log
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: tests
|
||||
key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-${{ github.sha }}
|
||||
@ -341,14 +343,14 @@ jobs:
|
||||
filenames=$(find Library/Homebrew/test/junit -name 'rspec*.xml' -print | tr '\n' ',')
|
||||
echo "filenames=${filenames%,}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: codecov/test-results-action@44ecb3a270cd942bdf0fa8f2ce14cb32493e810a # v1.0.3
|
||||
- uses: codecov/test-results-action@5c441a7bcc06f8706cde90192857d337c5dab8a6 # v1.0.4
|
||||
with:
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
files: ${{ steps.junit_xml.outputs.filenames }}
|
||||
disable_search: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
|
||||
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
|
||||
with:
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||
files: Library/Homebrew/test/coverage/coverage.xml
|
||||
@ -364,12 +366,15 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: test default formula (Ubuntu 24.04)
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu24.04:latest
|
||||
- name: test default formula (Ubuntu 22.04)
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu22.04:master
|
||||
- name: test default formula (Ubuntu 20.04)
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/homebrew/ubuntu20.04
|
||||
container: ghcr.io/homebrew/ubuntu20.04:latest
|
||||
- name: test default formula (macOS 13 x86_64)
|
||||
runs-on: macos-13
|
||||
- name: test default formula (macOS 15 arm64)
|
||||
@ -415,7 +420,7 @@ jobs:
|
||||
|
||||
- name: Cache Homebrew Bundler RubyGems
|
||||
id: cache
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
|
||||
2
.github/workflows/vendor-gems.yml
vendored
2
.github/workflows/vendor-gems.yml
vendored
@ -92,7 +92,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Generate push token
|
||||
uses: actions/create-github-app-token@67e27a7eb7db372a1c61a7f9bdab8699e9ee57f7 # v1.11.3
|
||||
uses: actions/create-github-app-token@21cfef2b496dd8ef5b904c159339626a10ad380e # v1.11.6
|
||||
id: app-token
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -90,6 +90,7 @@
|
||||
**/vendor/bundle/ruby/*/gems/json_schemer-*/
|
||||
**/vendor/bundle/ruby/*/gems/kramdown-*/
|
||||
**/vendor/bundle/ruby/*/gems/language_server-protocol-*/
|
||||
**/vendor/bundle/ruby/*/gems/lint_roller-*/
|
||||
**/vendor/bundle/ruby/*/gems/logger-*/
|
||||
**/vendor/bundle/ruby/*/gems/method_source-*/
|
||||
**/vendor/bundle/ruby/*/gems/mini_portile2-*/
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
---
|
||||
plugins:
|
||||
- rubocop-md:
|
||||
plugin_class_name: RuboCop::Markdown::Plugin
|
||||
- rubocop-performance:
|
||||
plugin_class_name: RuboCop::Performance::Plugin
|
||||
- rubocop-rspec:
|
||||
plugin_class_name: RuboCop::RSpec::Plugin
|
||||
|
||||
require:
|
||||
- ./Homebrew/rubocops.rb
|
||||
- rubocop-md
|
||||
- rubocop-performance
|
||||
- rubocop-rspec
|
||||
- rubocop-sorbet
|
||||
|
||||
inherit_mode:
|
||||
@ -255,6 +260,11 @@ RSpec/Focus:
|
||||
RSpec/MessageSpies:
|
||||
EnforcedStyle: receive
|
||||
|
||||
# These are legacy violations that we should try to fix.
|
||||
Sorbet/AllowIncompatibleOverride:
|
||||
Exclude:
|
||||
- "Homebrew/livecheck/strategy/*.rb"
|
||||
|
||||
# Try getting rid of these.
|
||||
Sorbet/ConstantsFromStrings:
|
||||
Enabled: false
|
||||
|
||||
@ -10,13 +10,13 @@ GEM
|
||||
bindata (2.5.0)
|
||||
coderay (1.1.3)
|
||||
concurrent-ruby (1.3.5)
|
||||
diff-lcs (1.5.1)
|
||||
diff-lcs (1.6.0)
|
||||
docile (1.4.1)
|
||||
elftools (1.3.1)
|
||||
bindata (~> 2)
|
||||
erubi (1.13.1)
|
||||
hana (1.3.7)
|
||||
json (2.9.1)
|
||||
json (2.10.1)
|
||||
json_schemer (2.4.0)
|
||||
bigdecimal
|
||||
hana (~> 1.3)
|
||||
@ -25,12 +25,13 @@ GEM
|
||||
kramdown (2.5.1)
|
||||
rexml (>= 3.3.9)
|
||||
language_server-protocol (3.17.0.4)
|
||||
logger (1.6.5)
|
||||
lint_roller (1.1.0)
|
||||
logger (1.6.6)
|
||||
method_source (1.1.0)
|
||||
minitest (5.25.4)
|
||||
netrc (0.11.0)
|
||||
parallel (1.26.3)
|
||||
parallel_tests (4.9.0)
|
||||
parallel_tests (5.0.1)
|
||||
parallel
|
||||
parser (3.3.7.1)
|
||||
ast (~> 2.4.1)
|
||||
@ -51,9 +52,9 @@ GEM
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
rbs (3.8.1)
|
||||
logger
|
||||
redcarpet (3.6.0)
|
||||
redcarpet (3.6.1)
|
||||
regexp_parser (2.10.0)
|
||||
rexml (3.4.0)
|
||||
rexml (3.4.1)
|
||||
rspec (3.13.0)
|
||||
rspec-core (~> 3.13.0)
|
||||
rspec-expectations (~> 3.13.0)
|
||||
@ -75,9 +76,10 @@ GEM
|
||||
rspec-support (3.13.2)
|
||||
rspec_junit_formatter (0.6.0)
|
||||
rspec-core (>= 2, < 4, != 2.12.0)
|
||||
rubocop (1.71.2)
|
||||
rubocop (1.73.2)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
@ -85,18 +87,21 @@ GEM
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.38.0)
|
||||
rubocop-ast (1.38.1)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-md (1.2.4)
|
||||
rubocop (>= 1.45)
|
||||
rubocop-performance (1.23.1)
|
||||
rubocop (>= 1.48.1, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rspec (3.4.0)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-sorbet (0.8.7)
|
||||
rubocop-md (2.0.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (>= 1.72.1)
|
||||
rubocop-performance (1.24.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (>= 1.72.1, < 2.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-rspec (3.5.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-sorbet (0.8.9)
|
||||
rubocop (>= 1)
|
||||
ruby-lsp (0.23.9)
|
||||
ruby-lsp (0.23.11)
|
||||
language_server-protocol (~> 3.17.0)
|
||||
prism (>= 1.2, < 2.0)
|
||||
rbs (>= 3, < 4)
|
||||
@ -114,23 +119,23 @@ GEM
|
||||
simplecov-html (0.13.1)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
simpleidn (0.2.3)
|
||||
sorbet (0.5.11812)
|
||||
sorbet-static (= 0.5.11812)
|
||||
sorbet-runtime (0.5.11812)
|
||||
sorbet-static (0.5.11812-aarch64-linux)
|
||||
sorbet-static (0.5.11812-universal-darwin)
|
||||
sorbet-static (0.5.11812-x86_64-linux)
|
||||
sorbet-static-and-runtime (0.5.11812)
|
||||
sorbet (= 0.5.11812)
|
||||
sorbet-runtime (= 0.5.11812)
|
||||
spoom (1.5.3)
|
||||
sorbet (0.5.11888)
|
||||
sorbet-static (= 0.5.11888)
|
||||
sorbet-runtime (0.5.11888)
|
||||
sorbet-static (0.5.11888-aarch64-linux)
|
||||
sorbet-static (0.5.11888-universal-darwin)
|
||||
sorbet-static (0.5.11888-x86_64-linux)
|
||||
sorbet-static-and-runtime (0.5.11888)
|
||||
sorbet (= 0.5.11888)
|
||||
sorbet-runtime (= 0.5.11888)
|
||||
spoom (1.5.4)
|
||||
erubi (>= 1.10.0)
|
||||
prism (>= 0.28.0)
|
||||
rbi (>= 0.2.3)
|
||||
sorbet-static-and-runtime (>= 0.5.10187)
|
||||
thor (>= 0.19.2)
|
||||
stackprof (0.2.27)
|
||||
tapioca (0.16.9)
|
||||
tapioca (0.16.11)
|
||||
benchmark
|
||||
bundler (>= 2.2.25)
|
||||
netrc (>= 0.11.0)
|
||||
@ -153,7 +158,6 @@ GEM
|
||||
|
||||
PLATFORMS
|
||||
aarch64-linux
|
||||
arm-linux
|
||||
arm64-darwin
|
||||
x86_64-darwin
|
||||
x86_64-linux
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This module provides methods to define specialized attributes.
|
||||
# Method stubs are generated by the {Tapioca::Compilers::Attrables} compiler.
|
||||
# @note The compiler is fragile, and must be updated if the filename changes, if methods are added or removed,
|
||||
# or if a method's arity changes.
|
||||
module Attrable
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Module }
|
||||
|
||||
sig { params(attrs: Symbol).void }
|
||||
def attr_predicate(*attrs)
|
||||
attrs.each do |attr|
|
||||
define_method attr do
|
||||
instance_variable_get("@#{attr.to_s.sub(/\?$/, "")}") == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(attrs: Symbol).void }
|
||||
def attr_rw(*attrs)
|
||||
attrs.each do |attr|
|
||||
define_method attr do |val = nil|
|
||||
val.nil? ? instance_variable_get(:"@#{attr}") : instance_variable_set(:"@#{attr}", val)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -2,10 +2,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class BottleSpecification
|
||||
extend Attrable
|
||||
RELOCATABLE_CELLARS = [:any, :any_skip_relocation].freeze
|
||||
|
||||
attr_rw :rebuild
|
||||
attr_accessor :tap
|
||||
attr_reader :collector, :root_url_specs, :repository
|
||||
|
||||
@ -17,6 +15,11 @@ class BottleSpecification
|
||||
@root_url_specs = {}
|
||||
end
|
||||
|
||||
sig { params(val: Integer).returns(T.nilable(Integer)) }
|
||||
def rebuild(val = T.unsafe(nil))
|
||||
val.nil? ? @rebuild : @rebuild = val
|
||||
end
|
||||
|
||||
def root_url(var = nil, specs = {})
|
||||
if var.nil?
|
||||
@root_url ||= if (github_packages_url = GitHubPackages.root_url_if_match(Homebrew::EnvConfig.bottle_domain))
|
||||
|
||||
@ -969,13 +969,6 @@ then
|
||||
export HOMEBREW_DEVELOPER_COMMAND="1"
|
||||
fi
|
||||
|
||||
# Provide a (temporary, undocumented) way to disable Sorbet globally if needed
|
||||
# to avoid reverting the above.
|
||||
if [[ -n "${HOMEBREW_NO_SORBET_RUNTIME}" ]]
|
||||
then
|
||||
unset HOMEBREW_SORBET_RUNTIME
|
||||
fi
|
||||
|
||||
if [[ -n "${HOMEBREW_DEVELOPER_COMMAND}" && -z "${HOMEBREW_DEVELOPER}" ]]
|
||||
then
|
||||
if [[ -z "${HOMEBREW_DEV_CMD_RUN}" ]]
|
||||
@ -999,6 +992,13 @@ then
|
||||
export HOMEBREW_SORBET_RUNTIME="1"
|
||||
fi
|
||||
|
||||
# Provide a (temporary, undocumented) way to disable Sorbet globally if needed
|
||||
# to avoid reverting the above.
|
||||
if [[ -n "${HOMEBREW_NO_SORBET_RUNTIME}" ]]
|
||||
then
|
||||
unset HOMEBREW_SORBET_RUNTIME
|
||||
fi
|
||||
|
||||
if [[ -f "${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh" ]]
|
||||
then
|
||||
HOMEBREW_BASH_COMMAND="${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh"
|
||||
|
||||
@ -148,12 +148,15 @@ class Build
|
||||
# https://github.com/Homebrew/homebrew-core/pull/87470
|
||||
TZ: "UTC0",
|
||||
) do
|
||||
formula.patch
|
||||
|
||||
if args.git?
|
||||
formula.selective_patch(is_data: false)
|
||||
system "git", "init"
|
||||
system "git", "add", "-A"
|
||||
formula.selective_patch(is_data: true)
|
||||
else
|
||||
formula.patch
|
||||
end
|
||||
|
||||
if args.interactive?
|
||||
ohai "Entering interactive mode..."
|
||||
puts <<~EOS
|
||||
@ -185,6 +188,8 @@ class Build
|
||||
# Find and link metafiles
|
||||
formula.prefix.install_metafiles formula.buildpath
|
||||
formula.prefix.install_metafiles formula.libexec if formula.libexec.exist?
|
||||
|
||||
normalize_pod2man_outputs!(formula)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -214,6 +219,11 @@ class Build
|
||||
rescue
|
||||
raise "#{formula.opt_prefix} not present or broken\nPlease reinstall #{formula.full_name}. Sorry :("
|
||||
end
|
||||
|
||||
def normalize_pod2man_outputs!(formula)
|
||||
keg = Keg.new(formula.prefix)
|
||||
keg.normalize_pod2man_outputs!
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
|
||||
@ -22,6 +22,9 @@ require "cask/artifact/prefpane"
|
||||
require "cask/artifact/qlplugin"
|
||||
require "cask/artifact/mdimporter"
|
||||
require "cask/artifact/screen_saver"
|
||||
require "cask/artifact/bashcompletion"
|
||||
require "cask/artifact/fishcompletion"
|
||||
require "cask/artifact/zshcompletion"
|
||||
require "cask/artifact/service"
|
||||
require "cask/artifact/stage_only"
|
||||
require "cask/artifact/suite"
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "extend/object/deep_dup"
|
||||
|
||||
module Cask
|
||||
|
||||
@ -411,7 +411,7 @@ module Cask
|
||||
next
|
||||
end
|
||||
|
||||
if MacOS.undeletable?(resolved_path)
|
||||
if undeletable?(resolved_path)
|
||||
opoo "Skipping #{Formatter.identifier(action)} for undeletable path '#{path}'."
|
||||
next
|
||||
end
|
||||
@ -538,6 +538,10 @@ module Cask
|
||||
recursive_rmdir(*resolved_paths, **kwargs)
|
||||
end
|
||||
end
|
||||
|
||||
def undeletable?(target); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "extend/os/cask/artifact/abstract_uninstall"
|
||||
|
||||
25
Library/Homebrew/cask/artifact/bashcompletion.rb
Normal file
25
Library/Homebrew/cask/artifact/bashcompletion.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/artifact/shellcompletion"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Artifact corresponding to the `bash_completion` stanza.
|
||||
class BashCompletion < ShellCompletion
|
||||
sig { params(target: T.any(String, Pathname)).returns(Pathname) }
|
||||
def resolve_target(target)
|
||||
name = if File.extname(target).nil?
|
||||
target
|
||||
else
|
||||
new_name = File.basename(target, File.extname(target))
|
||||
odebug "Renaming completion #{target} to #{new_name}"
|
||||
|
||||
new_name
|
||||
end
|
||||
|
||||
config.bash_completion/name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
25
Library/Homebrew/cask/artifact/fishcompletion.rb
Normal file
25
Library/Homebrew/cask/artifact/fishcompletion.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/artifact/shellcompletion"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Artifact corresponding to the `fish_completion` stanza.
|
||||
class FishCompletion < ShellCompletion
|
||||
sig { params(target: T.any(String, Pathname)).returns(Pathname) }
|
||||
def resolve_target(target)
|
||||
name = if target.to_s.end_with? ".fish"
|
||||
target
|
||||
else
|
||||
new_name = "#{File.basename(target, File.extname(target))}.fish"
|
||||
odebug "Renaming completion #{target} to #{new_name}"
|
||||
|
||||
new_name
|
||||
end
|
||||
|
||||
config.fish_completion/name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -72,6 +72,7 @@ module Cask
|
||||
private
|
||||
|
||||
ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames"
|
||||
private_constant :ALT_NAME_ATTRIBUTE
|
||||
|
||||
# Try to make the asset searchable under the target name. Spotlight
|
||||
# respects this attribute for many filetypes, but ignores it for App
|
||||
|
||||
20
Library/Homebrew/cask/artifact/shellcompletion.rb
Normal file
20
Library/Homebrew/cask/artifact/shellcompletion.rb
Normal file
@ -0,0 +1,20 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/artifact/symlinked"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
class ShellCompletion < Symlinked
|
||||
sig { params(cask: Cask, source: T.any(String, Pathname)).returns(ShellCompletion) }
|
||||
def self.from_args(cask, source)
|
||||
new(cask, source)
|
||||
end
|
||||
|
||||
sig { params(_: T.any(String, Pathname)).returns(Pathname) }
|
||||
def resolve_target(_)
|
||||
raise CaskInvalidError, "Shell completion without shell info"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -62,7 +62,7 @@ module Cask
|
||||
end
|
||||
|
||||
ohai "Linking #{self.class.english_name} '#{source.basename}' to '#{target}'"
|
||||
create_filesystem_link(command:)
|
||||
create_filesystem_link(command)
|
||||
end
|
||||
|
||||
def unlink(command: nil, **)
|
||||
@ -72,14 +72,10 @@ module Cask
|
||||
Utils.gain_permissions_remove(target, command:)
|
||||
end
|
||||
|
||||
def create_filesystem_link(command: nil)
|
||||
Utils.gain_permissions_mkpath(target.dirname, command:)
|
||||
sig { params(command: T.class_of(SystemCommand)).void }
|
||||
def create_filesystem_link(command); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
command.run! "/bin/ln", args: ["-h", "-f", "-s", "--", source, target],
|
||||
sudo: !target.dirname.writable?
|
||||
|
||||
add_altname_metadata(source, target.basename, command:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
require "extend/os/cask/artifact/symlinked"
|
||||
|
||||
25
Library/Homebrew/cask/artifact/zshcompletion.rb
Normal file
25
Library/Homebrew/cask/artifact/zshcompletion.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/artifact/shellcompletion"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Artifact corresponding to the `zsh_completion` stanza.
|
||||
class ZshCompletion < ShellCompletion
|
||||
sig { params(target: T.any(String, Pathname)).returns(Pathname) }
|
||||
def resolve_target(target)
|
||||
name = if target.to_s.start_with? "_"
|
||||
target
|
||||
else
|
||||
new_name = "_#{File.basename(target, File.extname(target))}"
|
||||
odebug "Renaming completion #{target} to #{new_name}"
|
||||
|
||||
new_name
|
||||
end
|
||||
|
||||
config.zsh_completion/name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "cask/denylist"
|
||||
require "cask/download"
|
||||
require "digest"
|
||||
@ -19,7 +18,6 @@ module Cask
|
||||
class Audit
|
||||
include SystemCommand::Mixin
|
||||
include ::Utils::Curl
|
||||
extend Attrable
|
||||
|
||||
sig { returns(Cask) }
|
||||
attr_reader :cask
|
||||
@ -27,11 +25,16 @@ module Cask
|
||||
sig { returns(T.nilable(Download)) }
|
||||
attr_reader :download
|
||||
|
||||
attr_predicate :new_cask?, :strict?, :signing?, :online?, :token_conflicts?
|
||||
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, download: T::Boolean, quarantine: T::Boolean, token_conflicts: T.nilable(T::Boolean),
|
||||
online: T.nilable(T::Boolean), strict: T.nilable(T::Boolean), signing: T.nilable(T::Boolean),
|
||||
new_cask: T.nilable(T::Boolean), only: T::Array[String], except: T::Array[String]
|
||||
).void
|
||||
}
|
||||
def initialize(
|
||||
cask,
|
||||
download: nil, quarantine: nil,
|
||||
download: false, quarantine: false,
|
||||
token_conflicts: nil, online: nil, strict: nil, signing: nil,
|
||||
new_cask: nil, only: [], except: []
|
||||
)
|
||||
@ -42,7 +45,7 @@ module Cask
|
||||
token_conflicts = new_cask if token_conflicts.nil?
|
||||
|
||||
# `online` and `signing` imply `download`
|
||||
download = online || signing if download.nil?
|
||||
download ||= online || signing
|
||||
|
||||
@cask = cask
|
||||
@download = Download.new(cask, quarantine:) if download
|
||||
@ -51,18 +54,34 @@ module Cask
|
||||
@signing = signing
|
||||
@new_cask = new_cask
|
||||
@token_conflicts = token_conflicts
|
||||
@only = only || []
|
||||
@except = except || []
|
||||
@only = only
|
||||
@except = except
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def new_cask? = !!@new_cask
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def online? =!!@online
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def signing? = !!@signing
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def strict? = !!@strict
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def token_conflicts? = !!@token_conflicts
|
||||
|
||||
sig { returns(::Cask::Audit) }
|
||||
def run!
|
||||
only_audits = @only
|
||||
except_audits = @except
|
||||
|
||||
private_methods.map(&:to_s).grep(/^audit_/).each do |audit_method_name|
|
||||
name = audit_method_name.delete_prefix("audit_")
|
||||
next if !only_audits.empty? && only_audits&.exclude?(name)
|
||||
next if except_audits&.include?(name)
|
||||
next if !only_audits.empty? && only_audits.exclude?(name)
|
||||
next if except_audits.include?(name)
|
||||
|
||||
send(audit_method_name)
|
||||
end
|
||||
@ -292,6 +311,7 @@ module Cask
|
||||
end
|
||||
|
||||
LIVECHECK_REFERENCE_URL = "https://docs.brew.sh/Cask-Cookbook#stanza-livecheck"
|
||||
private_constant :LIVECHECK_REFERENCE_URL
|
||||
|
||||
sig { params(livecheck_result: T.any(NilClass, T::Boolean, Symbol)).void }
|
||||
def audit_hosting_with_livecheck(livecheck_result: audit_livecheck_version)
|
||||
@ -317,6 +337,7 @@ module Cask
|
||||
end
|
||||
|
||||
SOURCEFORGE_OSDN_REFERENCE_URL = "https://docs.brew.sh/Cask-Cookbook#sourceforgeosdn-urls"
|
||||
private_constant :SOURCEFORGE_OSDN_REFERENCE_URL
|
||||
|
||||
sig { void }
|
||||
def audit_download_url_format
|
||||
@ -339,6 +360,7 @@ module Cask
|
||||
end
|
||||
|
||||
VERIFIED_URL_REFERENCE_URL = "https://docs.brew.sh/Cask-Cookbook#when-url-and-homepage-domains-differ-add-verified"
|
||||
private_constant :VERIFIED_URL_REFERENCE_URL
|
||||
|
||||
sig { void }
|
||||
def audit_unnecessary_verified
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/audit"
|
||||
@ -6,22 +6,50 @@ require "cask/audit"
|
||||
module Cask
|
||||
# Helper class for auditing all available languages of a cask.
|
||||
class Auditor
|
||||
def self.audit(cask, **options)
|
||||
new(cask, **options).audit
|
||||
# TODO: use argument forwarding (...) when Sorbet supports it in strict mode
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
||||
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
|
||||
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||
).returns(T::Set[String])
|
||||
}
|
||||
def self.audit(
|
||||
cask, audit_download: false, audit_online: nil, audit_strict: nil, audit_signing: nil,
|
||||
audit_token_conflicts: nil, audit_new_cask: nil, quarantine: false, any_named_args: false, language: nil,
|
||||
only: [], except: []
|
||||
)
|
||||
new(
|
||||
cask, audit_download:, audit_online:, audit_strict:, audit_signing:, audit_token_conflicts:,
|
||||
audit_new_cask:, quarantine:, any_named_args:, language:, only:, except:
|
||||
).audit
|
||||
end
|
||||
|
||||
attr_reader :cask, :language
|
||||
sig { returns(::Cask::Cask) }
|
||||
attr_reader :cask
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
attr_reader :language
|
||||
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
|
||||
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
|
||||
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
|
||||
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
|
||||
).void
|
||||
}
|
||||
def initialize(
|
||||
cask,
|
||||
audit_download: nil,
|
||||
audit_download: false,
|
||||
audit_online: nil,
|
||||
audit_strict: nil,
|
||||
audit_signing: nil,
|
||||
audit_token_conflicts: nil,
|
||||
audit_new_cask: nil,
|
||||
quarantine: nil,
|
||||
any_named_args: nil,
|
||||
quarantine: false,
|
||||
any_named_args: false,
|
||||
language: nil,
|
||||
only: [],
|
||||
except: []
|
||||
@ -42,17 +70,18 @@ module Cask
|
||||
|
||||
LANGUAGE_BLOCK_LIMIT = 10
|
||||
|
||||
sig { returns(T::Set[String]) }
|
||||
def audit
|
||||
errors = Set.new
|
||||
|
||||
if !language && language_blocks
|
||||
sample_languages = if language_blocks.length > LANGUAGE_BLOCK_LIMIT && !@audit_new_cask
|
||||
sample_keys = language_blocks.keys.sample(LANGUAGE_BLOCK_LIMIT)
|
||||
if !language && (blocks = language_blocks)
|
||||
sample_languages = if blocks.length > LANGUAGE_BLOCK_LIMIT && !@audit_new_cask
|
||||
sample_keys = T.must(blocks.keys.sample(LANGUAGE_BLOCK_LIMIT))
|
||||
ohai "Auditing a sample of available languages for #{cask}: " \
|
||||
"#{sample_keys.map { |lang| lang[0].to_s }.to_sentence}"
|
||||
language_blocks.select { |k| sample_keys.include?(k) }
|
||||
blocks.select { |k| sample_keys.include?(k) }
|
||||
else
|
||||
language_blocks
|
||||
blocks
|
||||
end
|
||||
|
||||
sample_languages.each_key do |l|
|
||||
@ -74,14 +103,16 @@ module Cask
|
||||
|
||||
private
|
||||
|
||||
sig { params(audit: T.nilable(Audit)).returns(T::Boolean) }
|
||||
def output_summary?(audit = nil)
|
||||
return true if @any_named_args.present?
|
||||
return true if @audit_strict.present?
|
||||
return false if audit.blank?
|
||||
return true if @any_named_args
|
||||
return true if @audit_strict
|
||||
return false if audit.nil?
|
||||
|
||||
audit.errors?
|
||||
end
|
||||
|
||||
sig { params(languages: T::Array[String]).returns(::Cask::Audit) }
|
||||
def audit_languages(languages)
|
||||
original_config = cask.config
|
||||
localized_config = original_config.merge(Config.new(explicit: { languages: }))
|
||||
@ -92,6 +123,7 @@ module Cask
|
||||
cask.config = original_config
|
||||
end
|
||||
|
||||
sig { params(cask: ::Cask::Cask).returns(::Cask::Audit) }
|
||||
def audit_cask_instance(cask)
|
||||
audit = Audit.new(
|
||||
cask,
|
||||
@ -108,6 +140,7 @@ module Cask
|
||||
audit.run!
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(T::Hash[T::Array[String], T.proc.returns(T.untyped)])) }
|
||||
def language_blocks
|
||||
cask.instance_variable_get(:@dsl).instance_variable_get(:@language_blocks)
|
||||
end
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "bundle_version"
|
||||
require "cask/cask_loader"
|
||||
require "cask/config"
|
||||
@ -15,7 +14,6 @@ module Cask
|
||||
# An instance of a cask.
|
||||
class Cask
|
||||
extend Forwardable
|
||||
extend Attrable
|
||||
extend APIHashable
|
||||
include Metadata
|
||||
|
||||
@ -32,8 +30,6 @@ module Cask
|
||||
attr_reader :sourcefile_path, :source, :default_config, :loader
|
||||
attr_accessor :download, :allow_reassignment
|
||||
|
||||
attr_predicate :loaded_from_api?
|
||||
|
||||
def self.all(eval_all: false)
|
||||
if !eval_all && !Homebrew::EnvConfig.eval_all?
|
||||
raise ArgumentError, "Cask::Cask#all cannot be used without `--eval-all` or HOMEBREW_EVAL_ALL"
|
||||
@ -92,6 +88,9 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def loaded_from_api? = @loaded_from_api
|
||||
|
||||
# An old name for the cask.
|
||||
sig { returns(T::Array[String]) }
|
||||
def old_tokens
|
||||
@ -114,12 +113,11 @@ module Cask
|
||||
return unless @block
|
||||
|
||||
@dsl.instance_eval(&@block)
|
||||
@dsl.add_implicit_macos_dependency
|
||||
@dsl.language_eval
|
||||
end
|
||||
|
||||
::Cask::DSL::DSL_METHODS.each do |method_name|
|
||||
define_method(method_name) { |*args, &block| @dsl.send(method_name, *args, &block) }
|
||||
end
|
||||
def_delegators :@dsl, *::Cask::DSL::DSL_METHODS
|
||||
|
||||
sig { params(caskroom_path: Pathname).returns(T::Array[[String, String]]) }
|
||||
def timestamped_versions(caskroom_path: self.caskroom_path)
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
module Cask
|
||||
class Cask
|
||||
def appdir; end
|
||||
|
||||
def artifacts; end
|
||||
|
||||
def auto_updates; end
|
||||
|
||||
def caveats; end
|
||||
|
||||
def conflicts_with; end
|
||||
|
||||
def container; end
|
||||
|
||||
def depends_on; end
|
||||
|
||||
def desc; end
|
||||
|
||||
def discontinued?; end
|
||||
|
||||
def deprecated?; end
|
||||
|
||||
def deprecation_date; end
|
||||
|
||||
def deprecation_reason; end
|
||||
|
||||
def deprecation_replacement; end
|
||||
|
||||
def disabled?; end
|
||||
|
||||
def disable_date; end
|
||||
|
||||
def disable_reason; end
|
||||
|
||||
def disable_replacement; end
|
||||
|
||||
def homepage; end
|
||||
|
||||
def language; end
|
||||
|
||||
def languages; end
|
||||
|
||||
def livecheck; end
|
||||
|
||||
def livecheck_defined?; end
|
||||
|
||||
def livecheckable?; end
|
||||
|
||||
def name; end
|
||||
|
||||
def on_system_blocks_exist?; end
|
||||
|
||||
sig { returns(T.nilable(MacOSVersion)) }
|
||||
def on_system_block_min_os; end
|
||||
|
||||
def sha256; end
|
||||
|
||||
def staged_path; end
|
||||
|
||||
sig { returns(T.nilable(::Cask::URL)) }
|
||||
def url; end
|
||||
|
||||
def version; end
|
||||
end
|
||||
end
|
||||
@ -176,6 +176,21 @@ module Cask
|
||||
@manpagedir ||= T.let(HOMEBREW_PREFIX/"share/man", T.nilable(Pathname))
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def bash_completion
|
||||
@bash_completion ||= T.let(HOMEBREW_PREFIX/"etc/bash_completion.d", T.nilable(Pathname))
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def zsh_completion
|
||||
@zsh_completion ||= T.let(HOMEBREW_PREFIX/"share/zsh/site-functions", T.nilable(Pathname))
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def fish_completion
|
||||
@fish_completion ||= T.let(HOMEBREW_PREFIX/"share/fish/vendor_completions.d", T.nilable(Pathname))
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def languages
|
||||
[
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "locale"
|
||||
require "lazy_object"
|
||||
require "livecheck"
|
||||
@ -54,6 +53,9 @@ module Cask
|
||||
Artifact::Suite,
|
||||
Artifact::VstPlugin,
|
||||
Artifact::Vst3Plugin,
|
||||
Artifact::ZshCompletion,
|
||||
Artifact::FishCompletion,
|
||||
Artifact::BashCompletion,
|
||||
Artifact::Uninstall,
|
||||
Artifact::Zap,
|
||||
].freeze
|
||||
@ -105,19 +107,36 @@ module Cask
|
||||
*ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] },
|
||||
]).freeze
|
||||
|
||||
extend Attrable
|
||||
include OnSystem::MacOSOnly
|
||||
include OnSystem::MacOSAndLinux
|
||||
|
||||
attr_reader :cask, :token, :deprecation_date, :deprecation_reason, :deprecation_replacement, :disable_date,
|
||||
:disable_reason, :disable_replacement, :on_system_block_min_os
|
||||
|
||||
attr_predicate :deprecated?, :disabled?, :livecheck_defined?, :on_system_blocks_exist?, :depends_on_set_in_block?
|
||||
|
||||
def initialize(cask)
|
||||
@cask = cask
|
||||
@depends_on_set_in_block = T.let(false, T::Boolean)
|
||||
@deprecated = T.let(false, T::Boolean)
|
||||
@disabled = T.let(false, T::Boolean)
|
||||
@livecheck_defined = T.let(false, T::Boolean)
|
||||
@on_system_blocks_exist = T.let(false, T::Boolean)
|
||||
@token = cask.token
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def depends_on_set_in_block? = @depends_on_set_in_block
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def deprecated? = @deprecated
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def disabled? = @disabled
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def livecheck_defined? = @livecheck_defined
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def on_system_blocks_exist? = @on_system_blocks_exist
|
||||
|
||||
# Specifies the cask's name.
|
||||
#
|
||||
# NOTE: Multiple names can be specified.
|
||||
@ -287,6 +306,7 @@ module Cask
|
||||
#
|
||||
# @see DSL::Version
|
||||
# @api public
|
||||
sig { params(arg: T.nilable(T.any(String, Symbol))).returns(T.nilable(DSL::Version)) }
|
||||
def version(arg = nil)
|
||||
set_unique_stanza(:version, arg.nil?) do
|
||||
if !arg.is_a?(String) && arg != :latest
|
||||
@ -311,17 +331,35 @@ module Cask
|
||||
#
|
||||
# ```ruby
|
||||
# sha256 arm: "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca",
|
||||
# intel: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2"
|
||||
# x86_64: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2"
|
||||
# x86_64_linux: "1a2aee7f1ddc999993d4d7d42a150c5e602bc17281678050b8ed79a0500cc90f"
|
||||
# arm64_linux: "bd766af7e692afceb727a6f88e24e6e68d9882aeb3e8348412f6c03d96537c75"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
def sha256(arg = nil, arm: nil, intel: nil)
|
||||
should_return = arg.nil? && arm.nil? && intel.nil?
|
||||
sig {
|
||||
params(
|
||||
arg: T.nilable(T.any(String, Symbol)),
|
||||
arm: T.nilable(String),
|
||||
intel: T.nilable(String),
|
||||
x86_64: T.nilable(String),
|
||||
x86_64_linux: T.nilable(String),
|
||||
arm64_linux: T.nilable(String),
|
||||
).returns(T.nilable(T.any(Symbol, Checksum)))
|
||||
}
|
||||
def sha256(arg = nil, arm: nil, intel: nil, x86_64: nil, x86_64_linux: nil, arm64_linux: nil)
|
||||
should_return = arg.nil? && arm.nil? && (intel.nil? || x86_64.nil?) && x86_64_linux.nil? && arm64_linux.nil?
|
||||
|
||||
x86_64 ||= intel if intel.present? && x86_64.nil?
|
||||
set_unique_stanza(:sha256, should_return) do
|
||||
@on_system_blocks_exist = true if arm.present? || intel.present?
|
||||
if arm.present? || x86_64.present? || x86_64_linux.present? || arm64_linux.present?
|
||||
@on_system_blocks_exist = true
|
||||
end
|
||||
|
||||
val = arg || on_arch_conditional(arm:, intel:)
|
||||
val = arg || on_system_conditional(
|
||||
macos: on_arch_conditional(arm:, intel: x86_64),
|
||||
linux: on_arch_conditional(arm: arm64_linux, intel: x86_64_linux),
|
||||
)
|
||||
case val
|
||||
when :no_check
|
||||
val
|
||||
@ -352,6 +390,31 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the cask's os strings.
|
||||
#
|
||||
# ### Example
|
||||
#
|
||||
# ```ruby
|
||||
# os macos: "darwin", linux: "tux"
|
||||
# ```
|
||||
#
|
||||
# @api public
|
||||
sig {
|
||||
params(
|
||||
macos: T.nilable(String),
|
||||
linux: T.nilable(String),
|
||||
).returns(T.nilable(String))
|
||||
}
|
||||
def os(macos: nil, linux: nil)
|
||||
should_return = macos.nil? && linux.nil?
|
||||
|
||||
set_unique_stanza(:os, should_return) do
|
||||
@on_system_blocks_exist = true
|
||||
|
||||
on_system_conditional(macos:, linux:)
|
||||
end
|
||||
end
|
||||
|
||||
# Declare dependencies and requirements for a cask.
|
||||
#
|
||||
# NOTE: Multiple dependencies can be specified.
|
||||
@ -370,6 +433,13 @@ module Cask
|
||||
@depends_on
|
||||
end
|
||||
|
||||
# @api private
|
||||
def add_implicit_macos_dependency
|
||||
return if @depends_on.present? && @depends_on.macos.present?
|
||||
|
||||
depends_on macos: ">= :#{MacOSVersion::SYMBOLS.key MacOSVersion::SYMBOLS.values.min}"
|
||||
end
|
||||
|
||||
# Declare conflicts that keep a cask from installing or working correctly.
|
||||
#
|
||||
# @api public
|
||||
@ -382,6 +452,7 @@ module Cask
|
||||
@artifacts ||= ArtifactSet.new
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def caskroom_path
|
||||
cask.caskroom_path
|
||||
end
|
||||
@ -389,6 +460,7 @@ module Cask
|
||||
# The staged location for this cask, including version number.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Pathname) }
|
||||
def staged_path
|
||||
return @staged_path if @staged_path
|
||||
|
||||
@ -520,9 +592,15 @@ module Cask
|
||||
true
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(MacOSVersion)) }
|
||||
def os_version
|
||||
nil
|
||||
end
|
||||
|
||||
# The directory `app`s are installed into.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(T.any(Pathname, String)) }
|
||||
def appdir
|
||||
return HOMEBREW_CASK_APPDIR_PLACEHOLDER if Cask.generating_hash?
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
|
||||
module Cask
|
||||
class DSL
|
||||
# Class corresponding to the `caveats` stanza.
|
||||
@ -15,10 +13,6 @@ module Cask
|
||||
# to the output by the caller, but that feature is only for the
|
||||
# convenience of cask authors.
|
||||
class Caveats < Base
|
||||
extend Attrable
|
||||
|
||||
attr_predicate :discontinued?
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@built_in_caveats = {}
|
||||
@ -37,6 +31,9 @@ module Cask
|
||||
|
||||
private_class_method :caveat
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def discontinued? = @discontinued
|
||||
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
(@custom_caveats + @built_in_caveats.values).join("\n")
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "formula_installer"
|
||||
require "unpack_strategy"
|
||||
require "utils/topological_hash"
|
||||
@ -17,8 +16,15 @@ require "cgi"
|
||||
module Cask
|
||||
# Installer for a {Cask}.
|
||||
class Installer
|
||||
extend Attrable
|
||||
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, command: T::Class[SystemCommand], force: T::Boolean, adopt: T::Boolean,
|
||||
skip_cask_deps: T::Boolean, binaries: T::Boolean, verbose: T::Boolean, zap: T::Boolean,
|
||||
require_sha: T::Boolean, upgrade: T::Boolean, reinstall: T::Boolean, installed_as_dependency: T::Boolean,
|
||||
installed_on_request: T::Boolean, quarantine: T::Boolean, verify_download_integrity: T::Boolean,
|
||||
quiet: T::Boolean
|
||||
).void
|
||||
}
|
||||
def initialize(cask, command: SystemCommand, force: false, adopt: false,
|
||||
skip_cask_deps: false, binaries: true, verbose: false,
|
||||
zap: false, require_sha: false, upgrade: false, reinstall: false,
|
||||
@ -42,9 +48,44 @@ module Cask
|
||||
@quiet = quiet
|
||||
end
|
||||
|
||||
attr_predicate :binaries?, :force?, :adopt?, :skip_cask_deps?, :require_sha?,
|
||||
:reinstall?, :upgrade?, :verbose?, :zap?, :installed_as_dependency?, :installed_on_request?,
|
||||
:quarantine?, :quiet?
|
||||
sig { returns(T::Boolean) }
|
||||
def adopt? = @adopt
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def binaries? = @binaries
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def force? = @force
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def installed_as_dependency? = @installed_as_dependency
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def installed_on_request? = @installed_on_request
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def quarantine? = @quarantine
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def quiet? = @quiet
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def reinstall? = @reinstall
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def require_sha? = @require_sha
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def skip_cask_deps? = @skip_cask_deps
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def upgrade? = @upgrade
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def verbose? = @verbose
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def zap? = @zap
|
||||
|
||||
def self.caveats(cask)
|
||||
odebug "Printing caveats"
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module_function
|
||||
|
||||
SYSTEM_DIRS = [
|
||||
SYSTEM_DIRS = T.let([
|
||||
"/",
|
||||
"/Applications",
|
||||
"/Applications/Utilities",
|
||||
@ -234,14 +232,13 @@ module OS
|
||||
"/var/spool/mail",
|
||||
"/var/tmp",
|
||||
]
|
||||
.map(&method(:Pathname))
|
||||
.to_set
|
||||
.freeze
|
||||
.to_set { Pathname(_1) }
|
||||
.freeze, T::Set[Pathname])
|
||||
private_constant :SYSTEM_DIRS
|
||||
|
||||
# TODO: There should be a way to specify a containing
|
||||
# directory under which nothing can be deleted.
|
||||
UNDELETABLE_PATHS = [
|
||||
UNDELETABLE_PATHS = T.let([
|
||||
"~/",
|
||||
"~/Applications",
|
||||
"~/Applications/.localized",
|
||||
@ -378,14 +375,16 @@ module OS
|
||||
]
|
||||
.to_set { |path| Pathname(path.sub(%r{^~(?=(/|$))}, Dir.home)).expand_path }
|
||||
.union(SYSTEM_DIRS)
|
||||
.freeze
|
||||
.freeze, T::Set[Pathname])
|
||||
private_constant :UNDELETABLE_PATHS
|
||||
|
||||
def system_dir?(dir)
|
||||
sig { params(dir: T.any(Pathname, String)).returns(T::Boolean) }
|
||||
def self.system_dir?(dir)
|
||||
SYSTEM_DIRS.include?(Pathname.new(dir).expand_path)
|
||||
end
|
||||
|
||||
def undeletable?(path)
|
||||
sig { params(path: T.any(Pathname, String)).returns(T::Boolean) }
|
||||
def self.undeletable?(path)
|
||||
UNDELETABLE_PATHS.include?(Pathname.new(path).expand_path)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
class Reinstall
|
||||
sig {
|
||||
params(
|
||||
casks: ::Cask::Cask, verbose: T::Boolean, force: T::Boolean, skip_cask_deps: T::Boolean, binaries: T::Boolean,
|
||||
require_sha: T::Boolean, quarantine: T::Boolean, zap: T::Boolean
|
||||
).void
|
||||
}
|
||||
def self.reinstall_casks(
|
||||
*casks,
|
||||
verbose: nil,
|
||||
force: nil,
|
||||
skip_cask_deps: nil,
|
||||
binaries: nil,
|
||||
require_sha: nil,
|
||||
quarantine: nil,
|
||||
zap: nil
|
||||
verbose: false,
|
||||
force: false,
|
||||
skip_cask_deps: false,
|
||||
binaries: false,
|
||||
require_sha: false,
|
||||
quarantine: false,
|
||||
zap: false
|
||||
)
|
||||
require "cask/installer"
|
||||
|
||||
quarantine = true if quarantine.nil?
|
||||
|
||||
casks.each do |cask|
|
||||
Installer.new(cask,
|
||||
binaries:,
|
||||
verbose:,
|
||||
force:,
|
||||
skip_cask_deps:,
|
||||
require_sha:,
|
||||
reinstall: true,
|
||||
quarantine:,
|
||||
zap:).install
|
||||
Installer
|
||||
.new(cask, binaries:, verbose:, force:, skip_cask_deps:, require_sha:, reinstall: true, quarantine:, zap:)
|
||||
.install
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -8,7 +8,7 @@ module Cask
|
||||
module Staged
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Kernel }
|
||||
requires_ancestor { ::Cask::DSL::Base }
|
||||
|
||||
Paths = T.type_alias { T.any(String, Pathname, T::Array[T.any(String, Pathname)]) }
|
||||
sig { params(paths: Paths, permissions_str: String).void }
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
class Uninstall
|
||||
def self.uninstall_casks(*casks, binaries: nil, force: false, verbose: false)
|
||||
sig { params(casks: ::Cask::Cask, binaries: T::Boolean, force: T::Boolean, verbose: T::Boolean).void }
|
||||
def self.uninstall_casks(*casks, binaries: false, force: false, verbose: false)
|
||||
require "cask/installer"
|
||||
|
||||
casks.each do |cask|
|
||||
|
||||
@ -42,9 +42,16 @@ module Cask
|
||||
|
||||
greedy = true if Homebrew::EnvConfig.upgrade_greedy?
|
||||
|
||||
greedy_casks = if (upgrade_greedy_casks = Homebrew::EnvConfig.upgrade_greedy_casks.presence)
|
||||
upgrade_greedy_casks.split
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
outdated_casks = if casks.empty?
|
||||
Caskroom.casks(config: Config.from_args(args)).select do |cask|
|
||||
cask.outdated?(greedy:, greedy_latest:,
|
||||
cask_greedy = greedy || greedy_casks.include?(cask.token)
|
||||
cask.outdated?(greedy: cask_greedy, greedy_latest:,
|
||||
greedy_auto_updates:)
|
||||
end
|
||||
else
|
||||
@ -78,7 +85,7 @@ module Cask
|
||||
|
||||
return false if outdated_casks.empty?
|
||||
|
||||
if casks.empty? && !greedy
|
||||
if casks.empty? && !greedy && greedy_casks.empty?
|
||||
if !greedy_auto_updates && !greedy_latest
|
||||
ohai "Casks with 'auto_updates true' or 'version :latest' " \
|
||||
"will not be upgraded; pass `--greedy` to upgrade them."
|
||||
|
||||
@ -267,6 +267,7 @@ module Cask
|
||||
|
||||
return false unless interpolated_url
|
||||
|
||||
interpolated_url = interpolated_url.gsub(/\#{\s*arch\s*}/, "")
|
||||
interpolated_url = interpolated_url.gsub(/\#{\s*version\s*\.major\s*}/, "") if ignore_major_version
|
||||
|
||||
interpolated_url.exclude?('#{')
|
||||
|
||||
@ -19,8 +19,8 @@ class Caveats
|
||||
sig { returns(String) }
|
||||
def caveats
|
||||
caveats = []
|
||||
begin
|
||||
build = formula.build
|
||||
begin
|
||||
formula.build = Tab.for_formula(formula)
|
||||
string = formula.caveats.to_s
|
||||
caveats << "#{string.chomp}\n" unless string.empty?
|
||||
@ -29,7 +29,7 @@ class Caveats
|
||||
end
|
||||
caveats << keg_only_text
|
||||
|
||||
valid_shells = [:bash, :zsh, :fish].freeze
|
||||
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
|
||||
current_shell = Utils::Shell.preferred || Utils::Shell.parent
|
||||
shells = if current_shell.present? &&
|
||||
(shell_sym = current_shell.to_sym) &&
|
||||
@ -143,6 +143,11 @@ class Caveats
|
||||
zsh #{installed.join(" and ")} have been installed to:
|
||||
#{root_dir}/share/zsh/site-functions
|
||||
EOS
|
||||
when :pwsh
|
||||
<<~EOS
|
||||
PowerShell completion has been installed to:
|
||||
#{root_dir}/share/pwsh/completions
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -114,6 +114,7 @@ class Cleaner
|
||||
# Arch & MacPorts amongst other packagers as well. The files are
|
||||
# created as part of installing any Perl module.
|
||||
PERL_BASENAMES = T.let(Set.new(%w[perllocal.pod .packlist]).freeze, T::Set[String])
|
||||
private_constant :PERL_BASENAMES
|
||||
|
||||
# Clean a top-level (`bin`, `sbin`, `lib`) directory, recursively, by fixing file
|
||||
# permissions and removing .la files, unless the files (or parent
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
|
||||
require "utils/bottles"
|
||||
|
||||
require "attrable"
|
||||
require "formula"
|
||||
require "cask/cask_loader"
|
||||
|
||||
@ -209,11 +208,8 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
extend Attrable
|
||||
|
||||
PERIODIC_CLEAN_FILE = (HOMEBREW_CACHE/".cleaned").freeze
|
||||
|
||||
attr_predicate :dry_run?, :scrub?, :prune?
|
||||
attr_reader :args, :days, :cache, :disk_cleanup_size
|
||||
|
||||
def initialize(*args, dry_run: false, scrub: false, days: nil, cache: HOMEBREW_CACHE)
|
||||
@ -227,6 +223,15 @@ module Homebrew
|
||||
@cleaned_up_paths = Set.new
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def dry_run? = @dry_run
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def prune? = @prune
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def scrub? = @scrub
|
||||
|
||||
def self.install_formula_clean!(formula, dry_run: false)
|
||||
return if Homebrew::EnvConfig.no_install_cleanup?
|
||||
return unless formula.latest_version_installed?
|
||||
|
||||
@ -221,8 +221,8 @@ module Homebrew
|
||||
deps = dependency.runtime_dependencies if @use_runtime_dependencies
|
||||
|
||||
if recursive
|
||||
deps ||= recursive_includes(Dependency, dependency, includes, ignores)
|
||||
reqs = recursive_includes(Requirement, dependency, includes, ignores)
|
||||
deps ||= recursive_dep_includes(dependency, includes, ignores)
|
||||
reqs = recursive_req_includes(dependency, includes, ignores)
|
||||
else
|
||||
deps ||= select_includes(dependency.deps, ignores, includes)
|
||||
reqs = select_includes(dependency.requirements, ignores, includes)
|
||||
|
||||
@ -209,7 +209,8 @@ module Homebrew
|
||||
formulae.map(&:to_hash)
|
||||
end
|
||||
when :v2
|
||||
formulae, casks = if all
|
||||
formulae, casks = T.let(
|
||||
if all
|
||||
[
|
||||
Formula.all(eval_all: args.eval_all?).sort,
|
||||
Cask::Cask.all(eval_all: args.eval_all?).sort_by(&:full_name),
|
||||
@ -217,8 +218,9 @@ module Homebrew
|
||||
elsif args.installed?
|
||||
[Formula.installed.sort, Cask::Caskroom.casks.sort_by(&:full_name)]
|
||||
else
|
||||
args.named.to_formulae_to_casks
|
||||
end
|
||||
T.cast(args.named.to_formulae_to_casks, [T::Array[Formula], T::Array[Cask::Cask]])
|
||||
end, [T::Array[Formula], T::Array[Cask::Cask]]
|
||||
)
|
||||
|
||||
if args.variations?
|
||||
{
|
||||
|
||||
@ -123,7 +123,8 @@ module Homebrew
|
||||
raise UsageError, "Cannot use #{flags.join(", ")} with formula arguments." unless args.no_named?
|
||||
|
||||
formulae = if args.t?
|
||||
Formula.installed.sort_by { |formula| test("M", formula.rack) }.reverse!
|
||||
# See https://ruby-doc.org/3.2/Kernel.html#method-i-test
|
||||
Formula.installed.sort_by { |formula| T.cast(test("M", formula.rack.to_s), Time) }.reverse!
|
||||
elsif args.full_name?
|
||||
Formula.installed.sort { |a, b| tap_and_name_comparison.call(a.full_name, b.full_name) }
|
||||
else
|
||||
|
||||
@ -33,7 +33,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
ff.each do |f|
|
||||
missing = f.missing_dependencies(hide: args.hide)
|
||||
missing = f.missing_dependencies(hide: args.hide || [])
|
||||
next if missing.empty?
|
||||
|
||||
Homebrew.failed = true
|
||||
|
||||
@ -59,14 +59,14 @@ module Homebrew
|
||||
elsif args.no_named?
|
||||
puts Tap.installed.sort_by(&:name)
|
||||
else
|
||||
tap = Tap.fetch(args.named.fetch(0))
|
||||
begin
|
||||
tap = Tap.fetch(args.named.fetch(0))
|
||||
tap.install clone_target: args.named.second,
|
||||
custom_remote: args.custom_remote?,
|
||||
quiet: args.quiet?,
|
||||
verify: args.eval_all? || Homebrew::EnvConfig.eval_all?,
|
||||
force: args.force?
|
||||
rescue TapRemoteMismatchError, TapNoCustomRemoteError => e
|
||||
rescue Tap::InvalidNameError, TapRemoteMismatchError, TapNoCustomRemoteError => e
|
||||
odie e
|
||||
rescue TapAlreadyTappedError
|
||||
nil
|
||||
|
||||
@ -161,7 +161,7 @@ module Homebrew
|
||||
end
|
||||
next unless formula.any_version_installed?
|
||||
|
||||
keg = formula.installed_kegs.last
|
||||
keg = formula.installed_kegs.fetch(-1)
|
||||
tab = keg.tab
|
||||
# force a `brew upgrade` from the linuxbrew-core version to the homebrew-core version (even if lower)
|
||||
tab.source["versions"]["version_scheme"] = -1
|
||||
@ -277,7 +277,7 @@ module Homebrew
|
||||
puts
|
||||
|
||||
new_major_version, new_minor_version, new_patch_version = new_tag.split(".").map(&:to_i)
|
||||
old_major_version, old_minor_version = (old_tag.split(".")[0, 2]).map(&:to_i) if old_tag.present?
|
||||
old_major_version, old_minor_version = old_tag.split(".")[0, 2].map(&:to_i) if old_tag.present?
|
||||
if old_tag.blank? || new_major_version > old_major_version || new_minor_version > old_minor_version
|
||||
puts <<~EOS
|
||||
The #{new_major_version}.#{new_minor_version}.0 release notes are available on the Homebrew Blog:
|
||||
|
||||
@ -94,7 +94,7 @@ module Homebrew
|
||||
|
||||
sig {
|
||||
params(use_runtime_dependents: T::Boolean, used_formulae: T::Array[T.any(Formula, UnavailableFormula)])
|
||||
.returns(T::Array[Formula])
|
||||
.returns(T::Array[T.any(Formula, CaskDependent)])
|
||||
}
|
||||
def intersection_of_dependents(use_runtime_dependents, used_formulae)
|
||||
recursive = args.recursive?
|
||||
@ -106,8 +106,8 @@ module Homebrew
|
||||
# We can only get here if `used_formulae_missing` is false, thus there are no UnavailableFormula.
|
||||
used_formulae = T.cast(used_formulae, T::Array[Formula])
|
||||
if show_formulae_and_casks || args.formula?
|
||||
deps += used_formulae.map(&:runtime_installed_formula_dependents)
|
||||
.reduce(&:&)
|
||||
deps += T.must(used_formulae.map(&:runtime_installed_formula_dependents)
|
||||
.reduce(&:&))
|
||||
.select(&:any_version_installed?)
|
||||
end
|
||||
if show_formulae_and_casks || args.cask?
|
||||
@ -150,26 +150,30 @@ module Homebrew
|
||||
|
||||
sig {
|
||||
params(
|
||||
dependents: T::Array[Formula], used_formulae: T::Array[T.any(Formula, UnavailableFormula)],
|
||||
recursive: T::Boolean, includes: T::Array[Symbol], ignores: T::Array[Symbol]
|
||||
).returns(
|
||||
T::Array[Formula],
|
||||
)
|
||||
dependents: T::Array[T.any(Formula, CaskDependent)],
|
||||
used_formulae: T::Array[T.any(Formula, UnavailableFormula)],
|
||||
recursive: T::Boolean,
|
||||
includes: T::Array[Symbol],
|
||||
ignores: T::Array[Symbol],
|
||||
).returns(T::Array[T.any(Formula, CaskDependent)])
|
||||
}
|
||||
def select_used_dependents(dependents, used_formulae, recursive, includes, ignores)
|
||||
dependents.select do |d|
|
||||
deps = if recursive
|
||||
recursive_includes(Dependency, d, includes, ignores)
|
||||
recursive_dep_includes(d, includes, ignores)
|
||||
else
|
||||
select_includes(d.deps, ignores, includes)
|
||||
end
|
||||
|
||||
used_formulae.all? do |ff|
|
||||
deps.any? do |dep|
|
||||
match = begin
|
||||
match = case dep
|
||||
when Dependency
|
||||
dep.to_formula.full_name == ff.full_name if dep.name.include?("/")
|
||||
rescue
|
||||
when Requirement
|
||||
nil
|
||||
else
|
||||
T.absurd(dep)
|
||||
end
|
||||
next match unless match.nil?
|
||||
|
||||
|
||||
@ -92,6 +92,7 @@ class CompilerFailure
|
||||
create(:clang),
|
||||
],
|
||||
}.freeze
|
||||
private_constant :COLLECTIONS
|
||||
end
|
||||
|
||||
# Class for selecting a compiler for a formula.
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "attrable"
|
||||
require "mutex_m"
|
||||
require "ignorable"
|
||||
|
||||
@ -73,9 +72,10 @@ module Debrew
|
||||
@debugged_exceptions = Set.new
|
||||
|
||||
class << self
|
||||
extend Attrable
|
||||
attr_predicate :active?
|
||||
attr_reader :debugged_exceptions
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def active? = @active
|
||||
end
|
||||
|
||||
def self.debrew
|
||||
|
||||
@ -39,11 +39,6 @@ class Dependencies < SimpleDelegator
|
||||
def inspect
|
||||
"#<#{self.class.name}: #{__getobj__}>"
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Dependency]) }
|
||||
def to_a
|
||||
__getobj__.to_a
|
||||
end
|
||||
end
|
||||
|
||||
# A collection of requirements.
|
||||
|
||||
@ -1,13 +1,32 @@
|
||||
# typed: strict
|
||||
|
||||
class Dependencies < SimpleDelegator
|
||||
include Enumerable
|
||||
include Kernel
|
||||
|
||||
# This is a workaround to enable `alias eql? ==`
|
||||
# @see https://github.com/sorbet/sorbet/issues/2378#issuecomment-569474238
|
||||
sig { params(other: BasicObject).returns(T::Boolean) }
|
||||
def ==(other); end
|
||||
|
||||
sig { params(blk: T.proc.params(arg0: Dependency).void).returns(T.self_type) }
|
||||
sig { returns(T::Enumerator[Dependency]) }
|
||||
def each(&blk); end
|
||||
|
||||
sig { params(blk: T.proc.params(arg0: Dependency).returns(T::Boolean)).returns(T::Array[Dependency]) }
|
||||
sig { returns(T::Enumerator[Dependency]) }
|
||||
def select(&blk); end
|
||||
end
|
||||
|
||||
class Requirements < SimpleDelegator
|
||||
include Enumerable
|
||||
include Kernel
|
||||
|
||||
sig { params(blk: T.proc.params(arg0: Requirement).void).returns(T.self_type) }
|
||||
sig { returns(T::Enumerator[Requirement]) }
|
||||
def each(&blk); end
|
||||
|
||||
sig { params(blk: T.proc.params(arg0: Requirement).returns(T::Boolean)).returns(T::Array[Requirement]) }
|
||||
sig { returns(T::Enumerator[Requirement]) }
|
||||
def select(&blk); end
|
||||
end
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask_dependent"
|
||||
|
||||
# Helper functions for dependencies.
|
||||
module DependenciesHelpers
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Kernel }
|
||||
|
||||
def args_includes_ignores(args)
|
||||
includes = [:required?, :recommended?] # included by default
|
||||
includes << :implicit? if args.include_implicit?
|
||||
@ -23,9 +19,35 @@ module DependenciesHelpers
|
||||
[includes, ignores]
|
||||
end
|
||||
|
||||
def recursive_includes(klass, root_dependent, includes, ignores)
|
||||
raise ArgumentError, "Invalid class argument: #{klass}" if klass != Dependency && klass != Requirement
|
||||
sig {
|
||||
params(root_dependent: T.any(Formula, CaskDependent), includes: T::Array[Symbol], ignores: T::Array[Symbol])
|
||||
.returns(T::Array[Dependency])
|
||||
}
|
||||
def recursive_dep_includes(root_dependent, includes, ignores)
|
||||
# The use of T.unsafe is recommended by the Sorbet docs:
|
||||
# https://sorbet.org/docs/overloads#multiple-methods-but-sharing-a-common-implementation
|
||||
T.unsafe(recursive_includes(Dependency, root_dependent, includes, ignores))
|
||||
end
|
||||
|
||||
sig {
|
||||
params(root_dependent: T.any(Formula, CaskDependent), includes: T::Array[Symbol], ignores: T::Array[Symbol])
|
||||
.returns(Requirements)
|
||||
}
|
||||
def recursive_req_includes(root_dependent, includes, ignores)
|
||||
# The use of T.unsafe is recommended by the Sorbet docs:
|
||||
# https://sorbet.org/docs/overloads#multiple-methods-but-sharing-a-common-implementation
|
||||
T.unsafe(recursive_includes(Requirement, root_dependent, includes, ignores))
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
klass: T.any(T.class_of(Dependency), T.class_of(Requirement)),
|
||||
root_dependent: T.any(Formula, CaskDependent),
|
||||
includes: T::Array[Symbol],
|
||||
ignores: T::Array[Symbol],
|
||||
).returns(T.any(T::Array[Dependency], Requirements))
|
||||
}
|
||||
def recursive_includes(klass, root_dependent, includes, ignores)
|
||||
cache_key = "recursive_includes_#{includes}_#{ignores}"
|
||||
|
||||
klass.expand(root_dependent, cache_key:) do |dependent, dep|
|
||||
@ -43,6 +65,13 @@ module DependenciesHelpers
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
dependables: T.any(Dependencies, Requirements, T::Array[Dependency], T::Array[Requirement]),
|
||||
ignores: T::Array[Symbol],
|
||||
includes: T::Array[Symbol],
|
||||
).returns(T::Array[T.any(Dependency, Requirement)])
|
||||
}
|
||||
def select_includes(dependables, ignores, includes)
|
||||
dependables.select do |dep|
|
||||
next false if ignores.any? { |ignore| dep.public_send(ignore) }
|
||||
@ -51,14 +80,18 @@ module DependenciesHelpers
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(formulae_or_casks: T::Array[T.any(Formula, Keg, Cask::Cask)])
|
||||
.returns(T::Array[T.any(Formula, CaskDependent)])
|
||||
}
|
||||
def dependents(formulae_or_casks)
|
||||
formulae_or_casks.map do |formula_or_cask|
|
||||
if formula_or_cask.is_a?(Formula)
|
||||
formula_or_cask
|
||||
case formula_or_cask
|
||||
when Formula then formula_or_cask
|
||||
when Cask::Cask then CaskDependent.new(formula_or_cask)
|
||||
else
|
||||
CaskDependent.new(formula_or_cask)
|
||||
raise TypeError, "Unsupported type: #{formula_or_cask.class}"
|
||||
end
|
||||
end
|
||||
end
|
||||
module_function :dependents
|
||||
end
|
||||
|
||||
12
Library/Homebrew/dependencies_helpers.rbi
Normal file
12
Library/Homebrew/dependencies_helpers.rbi
Normal file
@ -0,0 +1,12 @@
|
||||
# typed: strict
|
||||
|
||||
module DependenciesHelpers
|
||||
include Kernel
|
||||
|
||||
# This sig is in an RBI to avoid both circular dependencies and unnecessary requires
|
||||
sig {
|
||||
params(args: T.any(Homebrew::Cmd::Deps::Args, Homebrew::Cmd::Uses::Args))
|
||||
.returns([T::Array[Symbol], T::Array[Symbol]])
|
||||
}
|
||||
def args_includes_ignores(args); end
|
||||
end
|
||||
@ -261,8 +261,8 @@ module Homebrew
|
||||
audit_token_conflicts: args.token_conflicts? || nil,
|
||||
quarantine: true,
|
||||
any_named_args: !no_named_args,
|
||||
only: args.only,
|
||||
except: args.except,
|
||||
only: args.only || [],
|
||||
except: args.except || [],
|
||||
).to_a
|
||||
end
|
||||
end.uniq
|
||||
|
||||
@ -559,7 +559,7 @@ module Homebrew
|
||||
|
||||
ohai "Detecting if #{local_filename} is relocatable..." if bottle_path.size > 1 * 1024 * 1024
|
||||
|
||||
prefix_check = if Homebrew.default_prefix?(prefix)
|
||||
prefix_check = if prefix == HOMEBREW_DEFAULT_PREFIX
|
||||
File.join(prefix, "opt")
|
||||
else
|
||||
prefix
|
||||
|
||||
@ -115,7 +115,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
formulae_and_casks = formulae_and_casks&.sort_by do |formula_or_cask|
|
||||
formulae_and_casks = formulae_and_casks.sort_by do |formula_or_cask|
|
||||
formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name
|
||||
end
|
||||
|
||||
|
||||
@ -40,6 +40,8 @@ module Homebrew
|
||||
description: "Create a basic template for a Ruby build."
|
||||
switch "--rust",
|
||||
description: "Create a basic template for a Rust build."
|
||||
switch "--zig",
|
||||
description: "Create a basic template for a Zig build."
|
||||
switch "--no-fetch",
|
||||
description: "Homebrew will not download <URL> to the cache and will thus not add its SHA-256 " \
|
||||
"to the formula for you, nor will it check the GitHub API for GitHub projects " \
|
||||
@ -58,7 +60,7 @@ module Homebrew
|
||||
description: "Ignore errors for disallowed formula names and names that shadow aliases."
|
||||
|
||||
conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--node",
|
||||
"--perl", "--python", "--ruby", "--rust", "--cask"
|
||||
"--perl", "--python", "--ruby", "--rust", "--zig", "--cask"
|
||||
conflicts "--cask", "--HEAD"
|
||||
conflicts "--cask", "--set-license"
|
||||
|
||||
@ -173,6 +175,8 @@ module Homebrew
|
||||
:ruby
|
||||
elsif args.rust?
|
||||
:rust
|
||||
elsif args.zig?
|
||||
:zig
|
||||
end
|
||||
|
||||
fc = FormulaCreator.new(
|
||||
@ -220,6 +224,7 @@ module Homebrew
|
||||
path = fc.write_formula!
|
||||
|
||||
formula = Homebrew.with_no_api_env do
|
||||
CoreTap.instance.clear_cache
|
||||
Formula[fc.name]
|
||||
end
|
||||
PyPI.update_python_resources! formula, ignore_non_pypi_packages: true if args.python?
|
||||
|
||||
@ -229,7 +229,7 @@ module Homebrew
|
||||
if record["prefix"] == "custom-prefix"
|
||||
"#{record["prefix"]} (#{record["os"]} #{record["arch"]})"
|
||||
else
|
||||
(record["prefix"]).to_s
|
||||
record["prefix"].to_s
|
||||
end
|
||||
when :os_versions
|
||||
format_os_version_dimension(record["os_name_and_version"])
|
||||
|
||||
@ -39,7 +39,7 @@ module Homebrew
|
||||
sig { override.void }
|
||||
def run
|
||||
args.named.to_formulae.each do |formula|
|
||||
ignore_errors = if T.must(formula.tap).name == "homebrew/core"
|
||||
ignore_errors = if formula.tap&.official?
|
||||
false
|
||||
else
|
||||
args.ignore_errors?
|
||||
|
||||
@ -16,10 +16,10 @@ require "system_command"
|
||||
module Homebrew
|
||||
# Module containing diagnostic checks.
|
||||
module Diagnostic
|
||||
def self.missing_deps(formulae, hide = nil)
|
||||
def self.missing_deps(formulae, hide = [])
|
||||
missing = {}
|
||||
formulae.each do |f|
|
||||
missing_dependencies = f.missing_dependencies(hide:)
|
||||
missing_dependencies = f.missing_dependencies(hide: hide)
|
||||
next if missing_dependencies.empty?
|
||||
|
||||
yield f.full_name, missing_dependencies if block_given?
|
||||
@ -63,7 +63,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(list: T::Array[String], string: String).returns(String) }
|
||||
sig { params(list: T::Array[T.any(Formula, Pathname, String)], string: String).returns(String) }
|
||||
def inject_file_list(list, string)
|
||||
list.reduce(string.dup) { |acc, elem| acc << " #{elem}\n" }
|
||||
.freeze
|
||||
@ -748,15 +748,13 @@ module Homebrew
|
||||
|
||||
def check_for_unlinked_but_not_keg_only
|
||||
unlinked = Formula.racks.reject do |rack|
|
||||
if (HOMEBREW_LINKED_KEGS/rack.basename).directory?
|
||||
true
|
||||
else
|
||||
next true if (HOMEBREW_LINKED_KEGS/rack.basename).directory?
|
||||
|
||||
begin
|
||||
Formulary.from_rack(rack).keg_only?
|
||||
rescue FormulaUnavailableError, TapFormulaAmbiguityError
|
||||
false
|
||||
end
|
||||
end
|
||||
end.map(&:basename)
|
||||
return if unlinked.empty?
|
||||
|
||||
@ -1040,6 +1038,64 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def non_core_taps
|
||||
@non_core_taps ||= Tap.installed.reject(&:core_tap?).reject(&:core_cask_tap?)
|
||||
end
|
||||
|
||||
def check_for_duplicate_formulae
|
||||
return if ENV["HOMEBREW_TEST_BOT"].present?
|
||||
|
||||
core_formula_names = CoreTap.instance.formula_names
|
||||
shadowed_formula_full_names = non_core_taps.flat_map do |tap|
|
||||
tap_formula_names = tap.formula_names.map { |s| s.delete_prefix("#{tap.name}/") }
|
||||
(core_formula_names & tap_formula_names).map { |f| "#{tap.name}/#{f}" }
|
||||
end.compact.sort
|
||||
return if shadowed_formula_full_names.empty?
|
||||
|
||||
installed_formula_tap_names = Formula.installed.filter_map(&:tap).uniq.reject(&:official?).map(&:name)
|
||||
shadowed_formula_tap_names = shadowed_formula_full_names.map { |s| s.rpartition("/").first }.uniq
|
||||
unused_shadowed_formula_tap_names = (shadowed_formula_tap_names - installed_formula_tap_names).sort
|
||||
|
||||
resolution = if unused_shadowed_formula_tap_names.empty?
|
||||
"Their taps are in use, so you must use these full names throughout Homebrew."
|
||||
else
|
||||
"Some of these can be resolved with:\n brew untap #{unused_shadowed_formula_tap_names.join(" ")}"
|
||||
end
|
||||
|
||||
<<~EOS
|
||||
The following formulae have the same name as core formulae:
|
||||
#{shadowed_formula_full_names.join("\n ")}
|
||||
#{resolution}
|
||||
EOS
|
||||
end
|
||||
|
||||
def check_for_duplicate_casks
|
||||
return if ENV["HOMEBREW_TEST_BOT"].present?
|
||||
|
||||
core_cask_names = CoreCaskTap.instance.cask_tokens
|
||||
shadowed_cask_full_names = non_core_taps.flat_map do |tap|
|
||||
tap_cask_names = tap.cask_tokens.map { |s| s.delete_prefix("#{tap.name}/") }
|
||||
(core_cask_names & tap_cask_names).map { |f| "#{tap.name}/#{f}" }
|
||||
end.compact.sort
|
||||
return if shadowed_cask_full_names.empty?
|
||||
|
||||
installed_cask_tap_names = Cask::Caskroom.casks.filter_map(&:tap).uniq.reject(&:official?).map(&:name)
|
||||
shadowed_cask_tap_names = shadowed_cask_full_names.map { |s| s.rpartition("/").first }.uniq
|
||||
unused_shadowed_cask_tap_names = (shadowed_cask_tap_names - installed_cask_tap_names).sort
|
||||
|
||||
resolution = if unused_shadowed_cask_tap_names.empty?
|
||||
"Their taps are in use, so you must use these full names throughout Homebrew."
|
||||
else
|
||||
"Some of these can be resolved with:\n brew untap #{unused_shadowed_cask_tap_names.join(" ")}"
|
||||
end
|
||||
|
||||
<<~EOS
|
||||
The following casks have the same name as core casks:
|
||||
#{shadowed_cask_full_names.join("\n ")}
|
||||
#{resolution}
|
||||
EOS
|
||||
end
|
||||
|
||||
def all
|
||||
methods.map(&:to_s).grep(/^check_/).sort
|
||||
end
|
||||
|
||||
@ -490,6 +490,10 @@ module Homebrew
|
||||
description: "If set, pass `--greedy` to all cask upgrade commands.",
|
||||
boolean: true,
|
||||
},
|
||||
HOMEBREW_UPGRADE_GREEDY_CASKS: {
|
||||
description: "A space-separated list of casks. Homebrew will act as " \
|
||||
"if `--greedy` was passed when upgrading any cask on this list.",
|
||||
},
|
||||
HOMEBREW_VERBOSE: {
|
||||
description: "If set, always assume `--verbose` when running commands.",
|
||||
boolean: true,
|
||||
|
||||
@ -4,3 +4,23 @@ module OnSystem::MacOSOnly
|
||||
sig { params(arm: T.nilable(String), intel: T.nilable(String)).returns(T.nilable(String)) }
|
||||
def on_arch_conditional(arm: nil, intel: nil); end
|
||||
end
|
||||
|
||||
module OnSystem::MacOSAndLinux
|
||||
sig {
|
||||
params(
|
||||
macos: T.nilable(T.any(T::Array[T.any(String, Pathname)], String, Pathname)),
|
||||
linux: T.nilable(T.any(T::Array[T.any(String, Pathname)], String, Pathname)),
|
||||
).returns(T.nilable(T.any(T::Array[T.any(String, Pathname)], String, Pathname)))
|
||||
}
|
||||
def on_system_conditional(macos: nil, linux: nil); end
|
||||
|
||||
sig {
|
||||
type_parameters(:U)
|
||||
.params(block: T.proc.returns(T.type_parameter(:U)))
|
||||
.returns(T.type_parameter(:U))
|
||||
}
|
||||
def on_macos(&block); end
|
||||
|
||||
sig { params(arm: T.nilable(String), intel: T.nilable(String)).returns(T.nilable(String)) }
|
||||
def on_arch_conditional(arm: nil, intel: nil); end
|
||||
end
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/mac/cask/artifact/abstract_uninstall" if OS.mac?
|
||||
require "extend/os/linux/cask/artifact/abstract_uninstall" if OS.linux?
|
||||
5
Library/Homebrew/extend/os/cask/artifact/symlinked.rb
Normal file
5
Library/Homebrew/extend/os/cask/artifact/symlinked.rb
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/mac/cask/artifact/symlinked" if OS.mac?
|
||||
require "extend/os/linux/cask/artifact/symlinked" if OS.linux?
|
||||
4
Library/Homebrew/extend/os/cask/dsl.rb
Normal file
4
Library/Homebrew/extend/os/cask/dsl.rb
Normal file
@ -0,0 +1,4 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/os/mac/cask/dsl" if OS.mac?
|
||||
@ -0,0 +1,23 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Linux
|
||||
module Cask
|
||||
module Artifact
|
||||
module AbstractUninstall
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::Artifact::AbstractUninstall }
|
||||
|
||||
sig { params(target: Pathname).returns(T::Boolean) }
|
||||
def undeletable?(target)
|
||||
!target.parent.writable?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Cask::Artifact::AbstractUninstall.prepend(OS::Linux::Cask::Artifact::AbstractUninstall)
|
||||
@ -20,4 +20,4 @@ module OS
|
||||
end
|
||||
end
|
||||
|
||||
Cask::Artifact::Moved.prepend(OS::Linux::Cask::Config)
|
||||
Cask::Artifact::Moved.prepend(OS::Linux::Cask::Artifact::Moved)
|
||||
|
||||
26
Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb
Normal file
26
Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb
Normal file
@ -0,0 +1,26 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OS
|
||||
module Linux
|
||||
module Cask
|
||||
module Artifact
|
||||
module Symlinked
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::Artifact::Symlinked }
|
||||
|
||||
sig { params(command: T.class_of(SystemCommand)).void }
|
||||
def create_filesystem_link(command)
|
||||
::Cask::Utils.gain_permissions_mkpath(target.dirname, command:)
|
||||
|
||||
command.run! "/bin/ln", args: ["--no-dereference", "--force", "--symbolic", source, target],
|
||||
sudo: !target.dirname.writable?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Cask::Artifact::Symlinked.prepend(OS::Linux::Cask::Artifact::Symlinked)
|
||||
@ -15,6 +15,14 @@ module OS
|
||||
def check_stanza_os_requirements
|
||||
return if artifacts.all?(::Cask::Artifact::Font)
|
||||
|
||||
install_artifacts = artifacts.reject { |artifact| artifact.instance_of?(::Cask::Artifact::Zap) }
|
||||
return if install_artifacts.all? do |artifact|
|
||||
artifact.is_a?(::Cask::Artifact::Binary) ||
|
||||
artifact.is_a?(::Cask::Artifact::ShellCompletion) ||
|
||||
artifact.is_a?(::Cask::Artifact::Artifact) ||
|
||||
artifact.is_a?(::Cask::Artifact::Manpage)
|
||||
end
|
||||
|
||||
raise ::Cask::CaskError, "macOS is required for this software."
|
||||
end
|
||||
end
|
||||
|
||||
@ -24,7 +24,7 @@ module Homebrew
|
||||
end
|
||||
next unless recursive_runtime_dependencies.map(&:name).include? "gcc"
|
||||
|
||||
keg = formula.installed_kegs.last
|
||||
keg = formula.installed_kegs.fetch(-1)
|
||||
tab = keg.tab
|
||||
# Force reinstallation upon `brew upgrade` to fix the bottle RPATH.
|
||||
tab.source["versions"]["version_scheme"] = -1
|
||||
|
||||
@ -33,6 +33,7 @@ module OS
|
||||
|
||||
GLIBC = "glibc"
|
||||
GCC = OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA
|
||||
private_constant :GLIBC, :GCC
|
||||
|
||||
sig { void }
|
||||
def init_global_dep_tree_if_needed!
|
||||
@ -47,9 +48,9 @@ module OS
|
||||
built_global_dep_tree!
|
||||
end
|
||||
|
||||
sig { params(name: String).returns(T.nilable(Formula)) }
|
||||
sig { params(name: String).returns(T.nilable(::Formula)) }
|
||||
def formula_for(name)
|
||||
@formula_for ||= T.let({}, T.nilable(T::Hash[String, Formula]))
|
||||
@formula_for ||= T.let({}, T.nilable(T::Hash[String, ::Formula]))
|
||||
@formula_for[name] ||= ::Formula[name]
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/macos"
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module Cask
|
||||
module Artifact
|
||||
module AbstractUninstall
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::Artifact::AbstractUninstall }
|
||||
|
||||
sig { params(target: Pathname).returns(T::Boolean) }
|
||||
def undeletable?(target)
|
||||
MacOS.undeletable?(target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Cask::Artifact::AbstractUninstall.prepend(OS::Mac::Cask::Artifact::AbstractUninstall)
|
||||
30
Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb
Normal file
30
Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb
Normal file
@ -0,0 +1,30 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/macos"
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module Cask
|
||||
module Artifact
|
||||
module Symlinked
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::Artifact::Symlinked }
|
||||
|
||||
sig { params(command: T.class_of(SystemCommand)).void }
|
||||
def create_filesystem_link(command)
|
||||
::Cask::Utils.gain_permissions_mkpath(target.dirname, command:)
|
||||
|
||||
command.run! "/bin/ln", args: ["-h", "-f", "-s", "--", source, target],
|
||||
sudo: !target.dirname.writable?
|
||||
|
||||
add_altname_metadata(source, target.basename, command:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Cask::Artifact::Symlinked.prepend(OS::Mac::Cask::Artifact::Symlinked)
|
||||
23
Library/Homebrew/extend/os/mac/cask/dsl.rb
Normal file
23
Library/Homebrew/extend/os/mac/cask/dsl.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/macos"
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module Cask
|
||||
module DSL
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::DSL }
|
||||
|
||||
sig { returns(T.nilable(MacOSVersion)) }
|
||||
def os_version
|
||||
MacOS.full_version
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Cask::DSL.prepend(OS::Mac::Cask::DSL)
|
||||
@ -32,6 +32,18 @@ module OS
|
||||
|
||||
args
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
prefix: T.any(String, Pathname),
|
||||
release_mode: Symbol,
|
||||
).returns(T::Array[String])
|
||||
}
|
||||
def std_zig_args(prefix: self.prefix, release_mode: :fast)
|
||||
args = super
|
||||
args << "-fno-rosetta" if ::Hardware::CPU.arm?
|
||||
args
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -240,6 +240,7 @@ module OS
|
||||
private
|
||||
|
||||
CELLAR_RX = %r{\A#{HOMEBREW_CELLAR}/(?<formula_name>[^/]+)/[^/]+}
|
||||
private_constant :CELLAR_RX
|
||||
|
||||
# Replace HOMEBREW_CELLAR references with HOMEBREW_PREFIX/opt references
|
||||
# if the Cellar reference is to a different keg.
|
||||
|
||||
@ -8,53 +8,53 @@ certifi==2025.1.31 \
|
||||
--hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \
|
||||
--hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe
|
||||
# via influxdb3-python
|
||||
influxdb3-python==0.10.0 \
|
||||
--hash=sha256:d279e5f8a597d49b44035263b1cf1472a3861ceba930fd08e1e3b1721a07d3cf \
|
||||
--hash=sha256:f3d44dff4c4bbfdcb1fa1c4013ccfa317fbbd7df5812eb46395421166ffb385a
|
||||
influxdb3-python==0.11.0 \
|
||||
--hash=sha256:07bea8e1150be9707f818cda9634600a42487ee14802208f3f0357af2847f6e3 \
|
||||
--hash=sha256:dd5a1197f776f9836935d797be2dbc9e09f75465188492409e0b5931e6a033c4
|
||||
# via -r requirements.in
|
||||
pyarrow==19.0.0 \
|
||||
--hash=sha256:239ca66d9a05844bdf5af128861af525e14df3c9591bcc05bac25918e650d3a2 \
|
||||
--hash=sha256:2795064647add0f16563e57e3d294dbfc067b723f0fd82ecd80af56dad15f503 \
|
||||
--hash=sha256:29cd86c8001a94f768f79440bf83fee23963af5e7bc68ce3a7e5f120e17edf89 \
|
||||
--hash=sha256:2a0144a712d990d60f7f42b7a31f0acaccf4c1e43e957f7b1ad58150d6f639c1 \
|
||||
--hash=sha256:2a1a109dfda558eb011e5f6385837daffd920d54ca00669f7a11132d0b1e6042 \
|
||||
--hash=sha256:2b6d3ce4288793350dc2d08d1e184fd70631ea22a4ff9ea5c4ff182130249d9b \
|
||||
--hash=sha256:2f672f5364b2d7829ef7c94be199bb88bf5661dd485e21d2d37de12ccb78a136 \
|
||||
--hash=sha256:3c1c162c4660e0978411a4761f91113dde8da3433683efa473501254563dcbe8 \
|
||||
--hash=sha256:450a7d27e840e4d9a384b5c77199d489b401529e75a3b7a3799d4cd7957f2f9c \
|
||||
--hash=sha256:4624c89d6f777c580e8732c27bb8e77fd1433b89707f17c04af7635dd9638351 \
|
||||
--hash=sha256:4d8b0c0de0a73df1f1bf439af1b60f273d719d70648e898bc077547649bb8352 \
|
||||
--hash=sha256:5418d4d0fab3a0ed497bad21d17a7973aad336d66ad4932a3f5f7480d4ca0c04 \
|
||||
--hash=sha256:597360ffc71fc8cceea1aec1fb60cb510571a744fffc87db33d551d5de919bec \
|
||||
--hash=sha256:5e8a28b918e2e878c918f6d89137386c06fe577cd08d73a6be8dafb317dc2d73 \
|
||||
--hash=sha256:62ef8360ff256e960f57ce0299090fb86423afed5e46f18f1225f960e05aae3d \
|
||||
--hash=sha256:66732e39eaa2247996a6b04c8aa33e3503d351831424cdf8d2e9a0582ac54b34 \
|
||||
--hash=sha256:718947fb6d82409013a74b176bf93e0f49ef952d8a2ecd068fecd192a97885b7 \
|
||||
--hash=sha256:8d47c691765cf497aaeed4954d226568563f1b3b74ff61139f2d77876717084b \
|
||||
--hash=sha256:8e3a839bf36ec03b4315dc924d36dcde5444a50066f1c10f8290293c0427b46a \
|
||||
--hash=sha256:9348a0137568c45601b031a8d118275069435f151cbb77e6a08a27e8125f59d4 \
|
||||
--hash=sha256:a08e2a8a039a3f72afb67a6668180f09fddaa38fe0d21f13212b4aba4b5d2451 \
|
||||
--hash=sha256:a218670b26fb1bc74796458d97bcab072765f9b524f95b2fccad70158feb8b17 \
|
||||
--hash=sha256:a22a4bc0937856263df8b94f2f2781b33dd7f876f787ed746608e06902d691a5 \
|
||||
--hash=sha256:a7bbe7109ab6198688b7079cbad5a8c22de4d47c4880d8e4847520a83b0d1b68 \
|
||||
--hash=sha256:a92aff08e23d281c69835e4a47b80569242a504095ef6a6223c1f6bb8883431d \
|
||||
--hash=sha256:b34d3bde38eba66190b215bae441646330f8e9da05c29e4b5dd3e41bde701098 \
|
||||
--hash=sha256:b903afaa5df66d50fc38672ad095806443b05f202c792694f3a604ead7c6ea6e \
|
||||
--hash=sha256:be686bf625aa7b9bada18defb3a3ea3981c1099697239788ff111d87f04cd263 \
|
||||
--hash=sha256:c0423393e4a07ff6fea08feb44153302dd261d0551cc3b538ea7a5dc853af43a \
|
||||
--hash=sha256:c318eda14f6627966997a7d8c374a87d084a94e4e38e9abbe97395c215830e0c \
|
||||
--hash=sha256:c3b78eff5968a1889a0f3bc81ca57e1e19b75f664d9c61a42a604bf9d8402aae \
|
||||
--hash=sha256:c73268cf557e688efb60f1ccbc7376f7e18cd8e2acae9e663e98b194c40c1a2d \
|
||||
--hash=sha256:c751c1c93955b7a84c06794df46f1cec93e18610dcd5ab7d08e89a81df70a849 \
|
||||
--hash=sha256:ce42275097512d9e4e4a39aade58ef2b3798a93aa3026566b7892177c266f735 \
|
||||
--hash=sha256:cf3bf0ce511b833f7bc5f5bb3127ba731e97222023a444b7359f3a22e2a3b463 \
|
||||
--hash=sha256:da410b70a7ab8eb524112f037a7a35da7128b33d484f7671a264a4c224ac131d \
|
||||
--hash=sha256:e675a3ad4732b92d72e4d24009707e923cab76b0d088e5054914f11a797ebe44 \
|
||||
--hash=sha256:e82c3d5e44e969c217827b780ed8faf7ac4c53f934ae9238872e749fa531f7c9 \
|
||||
--hash=sha256:edfe6d3916e915ada9acc4e48f6dafca7efdbad2e6283db6fd9385a1b23055f1 \
|
||||
--hash=sha256:f094742275586cdd6b1a03655ccff3b24b2610c3af76f810356c4c71d24a2a6c \
|
||||
--hash=sha256:f208c3b58a6df3b239e0bb130e13bc7487ed14f39a9ff357b6415e3f6339b560 \
|
||||
--hash=sha256:f43f5aef2a13d4d56adadae5720d1fed4c1356c993eda8b59dace4b5983843c1
|
||||
pyarrow==19.0.1 \
|
||||
--hash=sha256:008a4009efdb4ea3d2e18f05cd31f9d43c388aad29c636112c2966605ba33466 \
|
||||
--hash=sha256:0148bb4fc158bfbc3d6dfe5001d93ebeed253793fff4435167f6ce1dc4bddeae \
|
||||
--hash=sha256:1b93ef2c93e77c442c979b0d596af45e4665d8b96da598db145b0fec014b9136 \
|
||||
--hash=sha256:1c7556165bd38cf0cd992df2636f8bcdd2d4b26916c6b7e646101aff3c16f76f \
|
||||
--hash=sha256:335d170e050bcc7da867a1ed8ffb8b44c57aaa6e0843b156a501298657b1e972 \
|
||||
--hash=sha256:3bf266b485df66a400f282ac0b6d1b500b9d2ae73314a153dbe97d6d5cc8a99e \
|
||||
--hash=sha256:41f9706fbe505e0abc10e84bf3a906a1338905cbbcf1177b71486b03e6ea6608 \
|
||||
--hash=sha256:4982f8e2b7afd6dae8608d70ba5bd91699077323f812a0448d8b7abdff6cb5d3 \
|
||||
--hash=sha256:49a3aecb62c1be1d822f8bf629226d4a96418228a42f5b40835c1f10d42e4db6 \
|
||||
--hash=sha256:4d5d1ec7ec5324b98887bdc006f4d2ce534e10e60f7ad995e7875ffa0ff9cb14 \
|
||||
--hash=sha256:58d9397b2e273ef76264b45531e9d552d8ec8a6688b7390b5be44c02a37aade8 \
|
||||
--hash=sha256:5a9137cf7e1640dce4c190551ee69d478f7121b5c6f323553b319cac936395f6 \
|
||||
--hash=sha256:5bd1618ae5e5476b7654c7b55a6364ae87686d4724538c24185bbb2952679960 \
|
||||
--hash=sha256:65cf9feebab489b19cdfcfe4aa82f62147218558d8d3f0fc1e9dea0ab8e7905a \
|
||||
--hash=sha256:699799f9c80bebcf1da0983ba86d7f289c5a2a5c04b945e2f2bcf7e874a91911 \
|
||||
--hash=sha256:6c5941c1aac89a6c2f2b16cd64fe76bcdb94b2b1e99ca6459de4e6f07638d755 \
|
||||
--hash=sha256:6ebfb5171bb5f4a52319344ebbbecc731af3f021e49318c74f33d520d31ae0c4 \
|
||||
--hash=sha256:7a544ec12de66769612b2d6988c36adc96fb9767ecc8ee0a4d270b10b1c51e00 \
|
||||
--hash=sha256:7c1bca1897c28013db5e4c83944a2ab53231f541b9e0c3f4791206d0c0de389a \
|
||||
--hash=sha256:80b2ad2b193e7d19e81008a96e313fbd53157945c7be9ac65f44f8937a55427b \
|
||||
--hash=sha256:8464c9fbe6d94a7fe1599e7e8965f350fd233532868232ab2596a71586c5a429 \
|
||||
--hash=sha256:8f04d49a6b64cf24719c080b3c2029a3a5b16417fd5fd7c4041f94233af732f3 \
|
||||
--hash=sha256:96606c3ba57944d128e8a8399da4812f56c7f61de8c647e3470b417f795d0ef9 \
|
||||
--hash=sha256:99bc1bec6d234359743b01e70d4310d0ab240c3d6b0da7e2a93663b0158616f6 \
|
||||
--hash=sha256:ad76aef7f5f7e4a757fddcdcf010a8290958f09e3470ea458c80d26f4316ae89 \
|
||||
--hash=sha256:b4c4156a625f1e35d6c0b2132635a237708944eb41df5fbe7d50f20d20c17832 \
|
||||
--hash=sha256:b9766a47a9cb56fefe95cb27f535038b5a195707a08bf61b180e642324963b46 \
|
||||
--hash=sha256:c0fe3dbbf054a00d1f162fda94ce236a899ca01123a798c561ba307ca38af5f0 \
|
||||
--hash=sha256:c6cb2335a411b713fdf1e82a752162f72d4a7b5dbc588e32aa18383318b05866 \
|
||||
--hash=sha256:cc55d71898ea30dc95900297d191377caba257612f384207fe9f8293b5850f90 \
|
||||
--hash=sha256:d03c9d6f2a3dffbd62671ca070f13fc527bb1867b4ec2b98c7eeed381d4f389a \
|
||||
--hash=sha256:d383591f3dcbe545f6cc62daaef9c7cdfe0dff0fb9e1c8121101cabe9098cfa6 \
|
||||
--hash=sha256:d9d46e06846a41ba906ab25302cf0fd522f81aa2a85a71021826f34639ad31ef \
|
||||
--hash=sha256:d9dedeaf19097a143ed6da37f04f4051aba353c95ef507764d344229b2b740ae \
|
||||
--hash=sha256:e45274b20e524ae5c39d7fc1ca2aa923aab494776d2d4b316b49ec7572ca324c \
|
||||
--hash=sha256:ee8dec072569f43835932a3b10c55973593abc00936c202707a4ad06af7cb294 \
|
||||
--hash=sha256:f24faab6ed18f216a37870d8c5623f9c044566d75ec586ef884e13a02a9d62c5 \
|
||||
--hash=sha256:f2a21d39fbdb948857f67eacb5bbaaf36802de044ec36fbef7a1c8f0dd3a4ab2 \
|
||||
--hash=sha256:f3ad4c0eb4e2a9aeb990af6c09e6fa0b195c8c0e7b272ecc8d4d2b6574809d34 \
|
||||
--hash=sha256:fc28912a2dc924dddc2087679cc8b7263accc71b9ff025a1362b004711661a69 \
|
||||
--hash=sha256:fca15aabbe9b8355800d923cc2e82c8ef514af321e18b437c3d782aa884eaeec \
|
||||
--hash=sha256:fd44d66093a239358d07c42a91eebf5015aa54fccba959db899f932218ac9cc8
|
||||
# via influxdb3-python
|
||||
python-dateutil==2.9.0.post0 \
|
||||
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
|
||||
@ -78,7 +78,7 @@ urllib3==2.3.0 \
|
||||
# via influxdb3-python
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
setuptools==75.8.0 \
|
||||
--hash=sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6 \
|
||||
--hash=sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3
|
||||
setuptools==75.8.2 \
|
||||
--hash=sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2 \
|
||||
--hash=sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f
|
||||
# via influxdb3-python
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
class Formula
|
||||
# This method is included by `OnSystem`
|
||||
def self.on_macos(&block); end
|
||||
end
|
||||
@ -307,7 +307,7 @@ module FormulaCellarChecks
|
||||
return unless formula.service?
|
||||
return unless formula.service.command?
|
||||
|
||||
"Service command does not exist" unless File.exist?(formula.service.command.first)
|
||||
"Service command does not exist" unless File.exist?(T.must(formula.service.command).first)
|
||||
end
|
||||
|
||||
sig { params(formula: Formula).returns(T.nilable(String)) }
|
||||
|
||||
@ -100,7 +100,7 @@ module Homebrew
|
||||
sig { params(name: String).returns(String) }
|
||||
def latest_versioned_formula(name)
|
||||
name_prefix = "#{name}@"
|
||||
Tap.fetch("homebrew/core").formula_names
|
||||
CoreTap.instance.formula_names
|
||||
.select { |f| f.start_with?(name_prefix) }
|
||||
.max_by { |v| Gem::Version.new(v.sub(name_prefix, "")) } || "python"
|
||||
end
|
||||
@ -151,6 +151,8 @@ module Homebrew
|
||||
uses_from_macos "ruby"
|
||||
<% elsif @mode == :rust %>
|
||||
depends_on "rust" => :build
|
||||
<% elsif @mode == :zig %>
|
||||
depends_on "zig" => :build
|
||||
<% elsif @mode.nil? %>
|
||||
# depends_on "cmake" => :build
|
||||
<% end %>
|
||||
@ -217,6 +219,8 @@ module Homebrew
|
||||
bin.env_script_all_files(libexec/"bin", GEM_HOME: ENV["GEM_HOME"])
|
||||
<% elsif @mode == :rust %>
|
||||
system "cargo", "install", *std_cargo_args
|
||||
<% elsif @mode == :zig %>
|
||||
system "zig", "build", *std_zig_args
|
||||
<% else %>
|
||||
# Remove unrecognized options if they cause configure to fail
|
||||
# https://rubydoc.brew.sh/Formula.html#std_configure_args-instance_method
|
||||
|
||||
@ -29,7 +29,6 @@ require "utils/fork"
|
||||
# Installer for a formula.
|
||||
class FormulaInstaller
|
||||
include FormulaCellarChecks
|
||||
extend Attrable
|
||||
|
||||
ETC_VAR_DIRS = T.let([HOMEBREW_PREFIX/"etc", HOMEBREW_PREFIX/"var"].freeze, T::Array[Pathname])
|
||||
|
||||
@ -45,12 +44,6 @@ class FormulaInstaller
|
||||
sig { returns(T::Boolean) }
|
||||
attr_accessor :link_keg
|
||||
|
||||
attr_predicate :installed_as_dependency?, :installed_on_request?
|
||||
attr_predicate :show_summary_heading?, :show_header?
|
||||
attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp?
|
||||
attr_predicate :debug_symbols?
|
||||
attr_predicate :verbose?, :debug?, :quiet?
|
||||
|
||||
sig {
|
||||
params(
|
||||
formula: Formula,
|
||||
@ -148,6 +141,54 @@ class FormulaInstaller
|
||||
@formula = T.let(T.must(previously_fetched_formula), Formula) if previously_fetched_formula
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def debug? = @debug
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def debug_symbols? = @debug_symbols
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def force? = @force
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def force_bottle? = @force_bottle
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def git? = @git
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def ignore_deps? = @ignore_deps
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def installed_as_dependency? = @installed_as_dependency
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def installed_on_request? = @installed_on_request
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def interactive? = @interactive
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def keep_tmp? = @keep_tmp
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def only_deps? = @only_deps
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def overwrite? = @overwrite
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def quiet? = @quiet
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def show_header? = @show_header
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def show_summary_heading? = @show_summary_heading
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def verbose? = @verbose
|
||||
|
||||
sig { returns(T::Set[Formula]) }
|
||||
def self.attempted
|
||||
@attempted ||= T.let(Set.new, T.nilable(T::Set[Formula]))
|
||||
@ -809,11 +850,8 @@ on_request: installed_on_request?, options:)
|
||||
options |= inherited_options
|
||||
options &= df.options
|
||||
|
||||
installed_on_request = if df.any_version_installed? && tab.present? && tab.installed_on_request
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
installed_on_request = df.any_version_installed? && tab.present? && tab.installed_on_request
|
||||
installed_on_request ||= false
|
||||
|
||||
fi = FormulaInstaller.new(
|
||||
df,
|
||||
@ -1230,7 +1268,7 @@ on_request: installed_on_request?, options:)
|
||||
return keg_formula_path if formula.loaded_from_api?
|
||||
return keg_formula_path if formula.local_bottle_path.present?
|
||||
|
||||
tap_formula_path = formula.specified_path
|
||||
tap_formula_path = T.must(formula.specified_path)
|
||||
return keg_formula_path unless tap_formula_path.exist?
|
||||
|
||||
begin
|
||||
|
||||
@ -136,6 +136,8 @@ class GitHubPackages
|
||||
IMAGE_MANIFEST_SCHEMA_URI = "https://opencontainers.org/schema/image/manifest"
|
||||
|
||||
GITHUB_PACKAGE_TYPE = "homebrew_bottle"
|
||||
private_constant :IMAGE_CONFIG_SCHEMA_URI, :IMAGE_INDEX_SCHEMA_URI, :IMAGE_LAYOUT_SCHEMA_URI,
|
||||
:IMAGE_MANIFEST_SCHEMA_URI, :GITHUB_PACKAGE_TYPE
|
||||
|
||||
def load_schemas!
|
||||
schema_uri("content-descriptor",
|
||||
|
||||
@ -5,6 +5,10 @@ require "test_runner_formula"
|
||||
require "github_runner"
|
||||
|
||||
class GitHubRunnerMatrix
|
||||
NEWEST_HOMEBREW_CORE_MACOS_RUNNER = :sequoia
|
||||
OLDEST_HOMEBREW_CORE_MACOS_RUNNER = :ventura
|
||||
NEWEST_HOMEBREW_CORE_INTEL_MACOS_RUNNER = :sonoma
|
||||
|
||||
RunnerSpec = T.type_alias { T.any(LinuxRunnerSpec, MacOSRunnerSpec) }
|
||||
private_constant :RunnerSpec
|
||||
|
||||
@ -77,6 +81,7 @@ class GitHubRunnerMatrix
|
||||
# https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#usage-limits
|
||||
GITHUB_ACTIONS_LONG_TIMEOUT = 2160 # 36 hours
|
||||
GITHUB_ACTIONS_SHORT_TIMEOUT = 60
|
||||
private_constant :SELF_HOSTED_LINUX_RUNNER, :GITHUB_ACTIONS_LONG_TIMEOUT, :GITHUB_ACTIONS_SHORT_TIMEOUT
|
||||
|
||||
sig { returns(LinuxRunnerSpec) }
|
||||
def linux_runner_spec
|
||||
@ -97,6 +102,7 @@ class GitHubRunnerMatrix
|
||||
|
||||
VALID_PLATFORMS = T.let([:macos, :linux].freeze, T::Array[Symbol])
|
||||
VALID_ARCHES = T.let([:arm64, :x86_64].freeze, T::Array[Symbol])
|
||||
private_constant :VALID_PLATFORMS, :VALID_ARCHES
|
||||
|
||||
sig {
|
||||
params(
|
||||
@ -116,10 +122,6 @@ class GitHubRunnerMatrix
|
||||
runner.freeze
|
||||
end
|
||||
|
||||
NEWEST_HOMEBREW_CORE_MACOS_RUNNER = :sequoia
|
||||
OLDEST_HOMEBREW_CORE_MACOS_RUNNER = :ventura
|
||||
NEWEST_HOMEBREW_CORE_INTEL_MACOS_RUNNER = :sonoma
|
||||
|
||||
sig { params(macos_version: MacOSVersion).returns(T::Boolean) }
|
||||
def runner_enabled?(macos_version)
|
||||
macos_version <= NEWEST_HOMEBREW_CORE_MACOS_RUNNER && macos_version >= OLDEST_HOMEBREW_CORE_MACOS_RUNNER
|
||||
@ -130,6 +132,9 @@ class GitHubRunnerMatrix
|
||||
NEWEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER = :sequoia
|
||||
OLDEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER = :sonoma
|
||||
GITHUB_ACTIONS_RUNNER_TIMEOUT = 360
|
||||
private_constant :NEWEST_GITHUB_ACTIONS_INTEL_MACOS_RUNNER, :OLDEST_GITHUB_ACTIONS_INTEL_MACOS_RUNNER,
|
||||
:NEWEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER, :OLDEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER,
|
||||
:GITHUB_ACTIONS_RUNNER_TIMEOUT
|
||||
|
||||
sig { void }
|
||||
def generate_runners!
|
||||
|
||||
@ -147,6 +147,7 @@ class Keg
|
||||
share/man/man1 share/man/man2 share/man/man3 share/man/man4
|
||||
share/man/man5 share/man/man6 share/man/man7 share/man/man8
|
||||
share/zsh share/zsh/site-functions
|
||||
share/pwsh share/pwsh/completions
|
||||
var/log
|
||||
].map { |dir| HOMEBREW_PREFIX/dir } + must_exist_subdirectories + [
|
||||
HOMEBREW_CACHE,
|
||||
@ -354,6 +355,7 @@ class Keg
|
||||
when :zsh
|
||||
dir = path/"share/zsh/site-functions"
|
||||
dir if dir.directory? && dir.children.any? { |f| f.basename.to_s.start_with?("_") }
|
||||
when :pwsh then path/"share/pwsh/completions"
|
||||
end
|
||||
dir&.directory? && !dir.children.empty?
|
||||
end
|
||||
@ -388,6 +390,7 @@ class Keg
|
||||
(path/"share/emacs/site-lisp"/name).children.any? { |f| ELISP_EXTENSIONS.include? f.extname }
|
||||
end
|
||||
|
||||
sig { returns(PkgVersion) }
|
||||
def version
|
||||
require "pkg_version"
|
||||
PkgVersion.parse(path.basename.to_s)
|
||||
@ -554,6 +557,32 @@ class Keg
|
||||
path.find { |pn| FileUtils.rm_rf pn if pn.basename.to_s == "__pycache__" }
|
||||
end
|
||||
|
||||
def normalize_pod2man_outputs!
|
||||
# Only process uncompressed manpages, which end in a digit
|
||||
manpages = Dir[path/"share/man/*/*.[1-9]"]
|
||||
generated_regex = /^\.\\"\s*Automatically generated by .*\n/
|
||||
manpages.each do |f|
|
||||
manpage = Pathname.new(f)
|
||||
next unless manpage.file?
|
||||
|
||||
content = manpage.read
|
||||
content = content.gsub(generated_regex, "")
|
||||
content = content.lines.map do |line|
|
||||
next line unless line.start_with?(".TH")
|
||||
|
||||
# Split the line by spaces, but preserve quoted strings
|
||||
parts = line.split(/\s(?=(?:[^"]|"[^"]*")*$)/)
|
||||
next line if parts.length != 6
|
||||
|
||||
# pod2man embeds the perl version used into the 5th field of the footer
|
||||
T.must(parts[4]).gsub!(/^"perl v.*"$/, "\"\"")
|
||||
"#{parts.join(" ")}\n"
|
||||
end.join
|
||||
|
||||
manpage.atomic_write(content)
|
||||
end
|
||||
end
|
||||
|
||||
def binary_executable_or_library_files
|
||||
[]
|
||||
end
|
||||
|
||||
@ -16,7 +16,7 @@ module Language
|
||||
next false unless f.any_version_installed?
|
||||
|
||||
unless version.zero?
|
||||
major = f.any_installed_version.major
|
||||
major = T.must(f.any_installed_version).major
|
||||
next false if major < version
|
||||
next false if major > version && !can_be_newer
|
||||
end
|
||||
|
||||
@ -340,7 +340,10 @@ module Language
|
||||
version = rp.match %r{^#{HOMEBREW_CELLAR}/python@(.*?)/}o
|
||||
version = "@#{version.captures.first}" unless version.nil?
|
||||
|
||||
new_target = rp.sub %r{#{HOMEBREW_CELLAR}/python#{version}/[^/]+}, Formula["python#{version}"].opt_prefix
|
||||
new_target = rp.sub(
|
||||
%r{#{HOMEBREW_CELLAR}/python#{version}/[^/]+},
|
||||
Formula["python#{version}"].opt_prefix.to_s,
|
||||
)
|
||||
f.unlink
|
||||
f.make_symlink new_target
|
||||
end
|
||||
@ -351,7 +354,10 @@ module Language
|
||||
version = prefix_path.match %r{^#{HOMEBREW_CELLAR}/python@(.*?)/}o
|
||||
version = "@#{version.captures.first}" unless version.nil?
|
||||
|
||||
prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/python#{version}/[^/]+}, Formula["python#{version}"].opt_prefix
|
||||
prefix_path.sub!(
|
||||
%r{^#{HOMEBREW_CELLAR}/python#{version}/[^/]+},
|
||||
Formula["python#{version}"].opt_prefix.to_s,
|
||||
)
|
||||
prefix_file.atomic_write prefix_path
|
||||
end
|
||||
|
||||
@ -362,7 +368,7 @@ module Language
|
||||
cfg = cfg_file.read
|
||||
framework = "Frameworks/Python.framework/Versions"
|
||||
cfg.match(%r{= *(#{HOMEBREW_CELLAR}/(python@[\d.]+)/[^/]+(?:/#{framework}/[\d.]+)?/bin)}) do |match|
|
||||
cfg.sub! match[1].to_s, Formula[match[2]].opt_bin
|
||||
cfg.sub! match[1].to_s, Formula[T.must(match[2])].opt_bin.to_s
|
||||
cfg_file.atomic_write cfg
|
||||
end
|
||||
end
|
||||
|
||||
@ -65,6 +65,7 @@ class LinkageCacheStore < CacheStore
|
||||
private
|
||||
|
||||
HASH_LINKAGE_TYPES = [:keg_files_dylibs].freeze
|
||||
private_constant :HASH_LINKAGE_TYPES
|
||||
|
||||
# @param type [Symbol]
|
||||
# @return [Hash]
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "livecheck/constants"
|
||||
require "livecheck/options"
|
||||
require "cask/cask"
|
||||
|
||||
# The {Livecheck} class implements the DSL methods used in a formula's, cask's
|
||||
@ -15,6 +16,10 @@ require "cask/cask"
|
||||
class Livecheck
|
||||
extend Forwardable
|
||||
|
||||
# Options to modify livecheck's behavior.
|
||||
sig { returns(Homebrew::Livecheck::Options) }
|
||||
attr_reader :options
|
||||
|
||||
# A very brief description of why the formula/cask/resource is skipped (e.g.
|
||||
# `No longer developed or maintained`).
|
||||
sig { returns(T.nilable(String)) }
|
||||
@ -24,13 +29,10 @@ class Livecheck
|
||||
sig { returns(T.nilable(Proc)) }
|
||||
attr_reader :strategy_block
|
||||
|
||||
# Options used by `Strategy` methods to modify `curl` behavior.
|
||||
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
||||
attr_reader :url_options
|
||||
|
||||
sig { params(package_or_resource: T.any(Cask::Cask, T.class_of(Formula), Resource)).void }
|
||||
def initialize(package_or_resource)
|
||||
@package_or_resource = package_or_resource
|
||||
@options = T.let(Homebrew::Livecheck::Options.new, Homebrew::Livecheck::Options)
|
||||
@referenced_cask_name = T.let(nil, T.nilable(String))
|
||||
@referenced_formula_name = T.let(nil, T.nilable(String))
|
||||
@regex = T.let(nil, T.nilable(Regexp))
|
||||
@ -40,7 +42,6 @@ class Livecheck
|
||||
@strategy_block = T.let(nil, T.nilable(Proc))
|
||||
@throttle = T.let(nil, T.nilable(Integer))
|
||||
@url = T.let(nil, T.any(NilClass, String, Symbol))
|
||||
@url_options = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
||||
end
|
||||
|
||||
# Sets the `@referenced_cask_name` instance variable to the provided `String`
|
||||
@ -170,15 +171,17 @@ class Livecheck
|
||||
params(
|
||||
# URL to check for version information.
|
||||
url: T.any(String, Symbol),
|
||||
post_form: T.nilable(T::Hash[T.any(String, Symbol), String]),
|
||||
post_json: T.nilable(T::Hash[T.any(String, Symbol), String]),
|
||||
homebrew_curl: T.nilable(T::Boolean),
|
||||
post_form: T.nilable(T::Hash[Symbol, String]),
|
||||
post_json: T.nilable(T::Hash[Symbol, String]),
|
||||
).returns(T.nilable(T.any(String, Symbol)))
|
||||
}
|
||||
def url(url = T.unsafe(nil), post_form: nil, post_json: nil)
|
||||
def url(url = T.unsafe(nil), homebrew_curl: nil, post_form: nil, post_json: nil)
|
||||
raise ArgumentError, "Only use `post_form` or `post_json`, not both" if post_form && post_json
|
||||
|
||||
options = { post_form:, post_json: }.compact
|
||||
@url_options = options if options.present?
|
||||
@options.homebrew_curl = homebrew_curl unless homebrew_curl.nil?
|
||||
@options.post_form = post_form unless post_form.nil?
|
||||
@options.post_json = post_json unless post_json.nil?
|
||||
|
||||
case url
|
||||
when nil
|
||||
@ -190,6 +193,7 @@ class Livecheck
|
||||
end
|
||||
end
|
||||
|
||||
delegate url_options: :@options
|
||||
delegate version: :@package_or_resource
|
||||
delegate arch: :@package_or_resource
|
||||
private :version, :arch
|
||||
@ -198,6 +202,7 @@ class Livecheck
|
||||
sig { returns(T::Hash[String, T.untyped]) }
|
||||
def to_hash
|
||||
{
|
||||
"options" => @options.to_hash,
|
||||
"cask" => @referenced_cask_name,
|
||||
"formula" => @referenced_formula_name,
|
||||
"regex" => @regex,
|
||||
@ -206,7 +211,6 @@ class Livecheck
|
||||
"strategy" => @strategy,
|
||||
"throttle" => @throttle,
|
||||
"url" => @url,
|
||||
"url_options" => @url_options,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,6 +13,9 @@ module Homebrew
|
||||
# command. These methods print the requested livecheck information
|
||||
# for formulae.
|
||||
module Livecheck
|
||||
NO_CURRENT_VERSION_MSG = "Unable to identify current version"
|
||||
NO_VERSIONS_MSG = "Unable to get versions"
|
||||
|
||||
UNSTABLE_VERSION_KEYWORDS = T.let(%w[
|
||||
alpha
|
||||
beta
|
||||
@ -25,19 +28,17 @@ module Homebrew
|
||||
].freeze, T::Array[String])
|
||||
private_constant :UNSTABLE_VERSION_KEYWORDS
|
||||
|
||||
sig { returns(T::Hash[T::Class[T.anything], String]) }
|
||||
private_class_method def self.livecheck_strategy_names
|
||||
return T.must(@livecheck_strategy_names) if defined?(@livecheck_strategy_names)
|
||||
|
||||
# Cache demodulized strategy names, to avoid repeating this work
|
||||
@livecheck_strategy_names = T.let({}, T.nilable(T::Hash[T::Class[T.anything], String]))
|
||||
Strategy.constants.sort.each do |const_symbol|
|
||||
constant = Strategy.const_get(const_symbol)
|
||||
next unless constant.is_a?(Class)
|
||||
|
||||
T.must(@livecheck_strategy_names)[constant] = Utils.demodulize(T.must(constant.name))
|
||||
sig { params(strategy_class: T::Class[Strategic]).returns(String) }
|
||||
private_class_method def self.livecheck_strategy_names(strategy_class)
|
||||
@livecheck_strategy_names ||= T.let({}, T.nilable(T::Hash[T::Class[Strategic], String]))
|
||||
@livecheck_strategy_names[strategy_class] ||= Utils.demodulize(strategy_class.name)
|
||||
end
|
||||
T.must(@livecheck_strategy_names).freeze
|
||||
|
||||
sig { params(strategy_class: T::Class[Strategic]).returns(T::Array[Symbol]) }
|
||||
private_class_method def self.livecheck_find_versions_parameters(strategy_class)
|
||||
@livecheck_find_versions_parameters ||= T.let({}, T.nilable(T::Hash[T::Class[Strategic], T::Array[Symbol]]))
|
||||
@livecheck_find_versions_parameters[strategy_class] ||=
|
||||
T::Utils.signature_for_method(strategy_class.method(:find_versions)).parameters.map(&:second)
|
||||
end
|
||||
|
||||
# Uses `formulae_and_casks_to_check` to identify taps in use other than
|
||||
@ -249,13 +250,20 @@ module Homebrew
|
||||
# comparison.
|
||||
current = if formula
|
||||
if formula.head_only?
|
||||
Version.new(formula.any_installed_version.version.commit)
|
||||
else
|
||||
T.must(formula.stable).version
|
||||
formula_commit = formula.any_installed_version&.version&.commit
|
||||
Version.new(formula_commit) if formula_commit
|
||||
elsif (stable = formula.stable)
|
||||
stable.version
|
||||
end
|
||||
else
|
||||
Version.new(formula_or_cask.version)
|
||||
end
|
||||
unless current
|
||||
raise Livecheck::Error, NO_CURRENT_VERSION_MSG unless json
|
||||
next if quiet
|
||||
|
||||
next status_hash(formula_or_cask, "error", [NO_CURRENT_VERSION_MSG], full_name: use_full_name, verbose:)
|
||||
end
|
||||
|
||||
current_str = current.to_s
|
||||
current = LivecheckVersion.create(formula_or_cask, current)
|
||||
@ -289,7 +297,7 @@ module Homebrew
|
||||
verbose:,
|
||||
)
|
||||
if res_version_info.empty?
|
||||
status_hash(resource, "error", ["Unable to get versions"], verbose:)
|
||||
status_hash(resource, "error", [NO_VERSIONS_MSG], verbose:)
|
||||
else
|
||||
res_version_info
|
||||
end
|
||||
@ -299,13 +307,12 @@ module Homebrew
|
||||
end
|
||||
|
||||
if latest.blank?
|
||||
no_versions_msg = "Unable to get versions"
|
||||
raise Livecheck::Error, no_versions_msg unless json
|
||||
raise Livecheck::Error, NO_VERSIONS_MSG unless json
|
||||
next if quiet
|
||||
|
||||
next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages]
|
||||
|
||||
latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name,
|
||||
latest_info = status_hash(formula_or_cask, "error", [NO_VERSIONS_MSG], full_name: use_full_name,
|
||||
verbose:)
|
||||
if check_for_resources
|
||||
unless verbose
|
||||
@ -613,8 +620,9 @@ module Homebrew
|
||||
livecheck = formula_or_cask.livecheck
|
||||
referenced_livecheck = referenced_formula_or_cask&.livecheck
|
||||
|
||||
livecheck_options = livecheck.options || referenced_livecheck&.options
|
||||
livecheck_url_options = livecheck_options.url_options.compact
|
||||
livecheck_url = livecheck.url || referenced_livecheck&.url
|
||||
livecheck_url_options = livecheck.url_options || referenced_livecheck&.url_options
|
||||
livecheck_regex = livecheck.regex || referenced_livecheck&.regex
|
||||
livecheck_strategy = livecheck.strategy || referenced_livecheck&.strategy
|
||||
livecheck_strategy_block = livecheck.strategy_block || referenced_livecheck&.strategy_block
|
||||
@ -659,7 +667,9 @@ module Homebrew
|
||||
block_provided: livecheck_strategy_block.present?,
|
||||
)
|
||||
strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first
|
||||
strategy_name = livecheck_strategy_names[strategy]
|
||||
next unless strategy
|
||||
|
||||
strategy_name = livecheck_strategy_names(strategy)
|
||||
|
||||
if strategy.respond_to?(:preprocess_url)
|
||||
url = strategy.preprocess_url(url)
|
||||
@ -674,10 +684,10 @@ module Homebrew
|
||||
elsif original_url.present? && original_url != "None"
|
||||
puts "URL: #{original_url}"
|
||||
end
|
||||
puts "URL Options: #{livecheck_url_options}" if livecheck_url_options.present?
|
||||
puts "URL (processed): #{url}" if url != original_url
|
||||
puts "URL Options: #{livecheck_url_options}" if livecheck_url_options.present?
|
||||
if strategies.present? && verbose
|
||||
puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}"
|
||||
puts "Strategies: #{strategies.map { |s| livecheck_strategy_names(s) }.join(", ")}"
|
||||
end
|
||||
puts "Strategy: #{strategy_name}" if strategy.present?
|
||||
puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present?
|
||||
@ -695,23 +705,25 @@ module Homebrew
|
||||
|
||||
next if strategy.blank?
|
||||
|
||||
homebrew_curl = case strategy_name
|
||||
if (livecheck_homebrew_curl = livecheck_options.homebrew_curl).nil?
|
||||
case strategy_name
|
||||
when "PageMatch", "HeaderMatch"
|
||||
use_homebrew_curl?(referenced_package, url)
|
||||
if (homebrew_curl = use_homebrew_curl?(referenced_package, url))
|
||||
livecheck_options = livecheck_options.merge({ homebrew_curl: })
|
||||
livecheck_homebrew_curl = homebrew_curl
|
||||
end
|
||||
puts "Homebrew curl?: Yes" if debug && homebrew_curl.present?
|
||||
end
|
||||
end
|
||||
puts "Homebrew curl?: #{livecheck_homebrew_curl ? "Yes" : "No"}" if debug && !livecheck_homebrew_curl.nil?
|
||||
|
||||
strategy_args = {
|
||||
regex: livecheck_regex,
|
||||
url_options: livecheck_url_options,
|
||||
homebrew_curl:,
|
||||
}
|
||||
# TODO: Set `cask`/`url` args based on the presence of the keyword arg
|
||||
# in the strategy's `#find_versions` method once we figure out why
|
||||
# `strategy.method(:find_versions).parameters` isn't working as
|
||||
# expected.
|
||||
strategy_args[:cask] = cask if strategy_name == "ExtractPlist" && cask.present?
|
||||
strategy_args[:url] = url
|
||||
# Only use arguments that the strategy's `#find_versions` method
|
||||
# supports
|
||||
find_versions_parameters = livecheck_find_versions_parameters(strategy)
|
||||
strategy_args = {}
|
||||
strategy_args[:cask] = cask if find_versions_parameters.include?(:cask)
|
||||
strategy_args[:url] = url if find_versions_parameters.include?(:url)
|
||||
strategy_args[:regex] = livecheck_regex if find_versions_parameters.include?(:regex)
|
||||
strategy_args[:options] = livecheck_options if find_versions_parameters.include?(:options)
|
||||
strategy_args.compact!
|
||||
|
||||
strategy_data = strategy.find_versions(**strategy_args, &livecheck_strategy_block)
|
||||
@ -811,10 +823,9 @@ module Homebrew
|
||||
end
|
||||
version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url]
|
||||
version_info[:meta][:url][:options] = livecheck_url_options if livecheck_url_options.present?
|
||||
version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present?
|
||||
end
|
||||
version_info[:meta][:strategy] = strategy_name if strategy.present?
|
||||
version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present?
|
||||
version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names(s) } if strategies.present?
|
||||
version_info[:meta][:regex] = regex.inspect if regex.present?
|
||||
version_info[:meta][:cached] = true if strategy_data[:cached] == true
|
||||
version_info[:meta][:throttle] = livecheck_throttle if livecheck_throttle
|
||||
@ -858,9 +869,10 @@ module Homebrew
|
||||
resource_version_info = {}
|
||||
|
||||
livecheck = resource.livecheck
|
||||
livecheck_options = livecheck.options
|
||||
livecheck_url_options = livecheck_options.url_options.compact
|
||||
livecheck_reference = livecheck.formula
|
||||
livecheck_url = livecheck.url
|
||||
livecheck_url_options = livecheck.url_options
|
||||
livecheck_regex = livecheck.regex
|
||||
livecheck_strategy = livecheck.strategy
|
||||
livecheck_strategy_block = livecheck.strategy_block
|
||||
@ -883,7 +895,9 @@ module Homebrew
|
||||
block_provided: livecheck_strategy_block.present?,
|
||||
)
|
||||
strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first
|
||||
strategy_name = livecheck_strategy_names[strategy]
|
||||
next unless strategy
|
||||
|
||||
strategy_name = livecheck_strategy_names(strategy)
|
||||
|
||||
if strategy.respond_to?(:preprocess_url)
|
||||
url = strategy.preprocess_url(url)
|
||||
@ -898,10 +912,10 @@ module Homebrew
|
||||
elsif original_url.present? && original_url != "None"
|
||||
puts "URL: #{original_url}"
|
||||
end
|
||||
puts "URL Options: #{livecheck_url_options}" if livecheck_url_options.present?
|
||||
puts "URL (processed): #{url}" if url != original_url
|
||||
puts "URL Options: #{livecheck_url_options}" if livecheck_url_options.present?
|
||||
if strategies.present? && verbose
|
||||
puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}"
|
||||
puts "Strategies: #{strategies.map { |s| livecheck_strategy_names(s) }.join(", ")}"
|
||||
end
|
||||
puts "Strategy: #{strategy_name}" if strategy.present?
|
||||
puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present?
|
||||
@ -922,16 +936,22 @@ module Homebrew
|
||||
puts if debug && strategy.blank? && livecheck_reference != :parent
|
||||
next if strategy.blank? && livecheck_reference != :parent
|
||||
|
||||
if debug && !(livecheck_homebrew_curl = livecheck_options.homebrew_curl).nil?
|
||||
puts "Homebrew curl?: #{livecheck_homebrew_curl ? "Yes" : "No"}"
|
||||
end
|
||||
|
||||
if livecheck_reference == :parent
|
||||
match_version_map = { formula_latest => Version.new(formula_latest) }
|
||||
cached = true
|
||||
else
|
||||
strategy_args = {
|
||||
url:,
|
||||
regex: livecheck_regex,
|
||||
url_options: livecheck_url_options,
|
||||
homebrew_curl: false,
|
||||
}.compact
|
||||
# Only use arguments that the strategy's `#find_versions` method
|
||||
# supports
|
||||
find_versions_parameters = livecheck_find_versions_parameters(strategy)
|
||||
strategy_args = {}
|
||||
strategy_args[:url] = url if find_versions_parameters.include?(:url)
|
||||
strategy_args[:regex] = livecheck_regex if find_versions_parameters.include?(:regex)
|
||||
strategy_args[:options] = livecheck_options if find_versions_parameters.include?(:options)
|
||||
strategy_args.compact!
|
||||
|
||||
strategy_data = strategy.find_versions(**strategy_args, &livecheck_strategy_block)
|
||||
match_version_map = strategy_data[:matches]
|
||||
@ -986,7 +1006,7 @@ module Homebrew
|
||||
res_current = T.must(resource.version)
|
||||
res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) })
|
||||
|
||||
return status_hash(resource, "error", ["Unable to get versions"], verbose:) if res_latest.blank?
|
||||
return status_hash(resource, "error", [NO_VERSIONS_MSG], verbose:) if res_latest.blank?
|
||||
|
||||
is_outdated = res_current < res_latest
|
||||
is_newer_than_upstream = res_current > res_latest
|
||||
@ -1023,7 +1043,7 @@ module Homebrew
|
||||
end
|
||||
resource_version_info[:meta][:strategy] = strategy_name if strategy.present?
|
||||
if strategies.present?
|
||||
resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] }
|
||||
resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names(s) }
|
||||
end
|
||||
resource_version_info[:meta][:regex] = regex.inspect if regex.present?
|
||||
resource_version_info[:meta][:cached] = true if cached == true
|
||||
|
||||
105
Library/Homebrew/livecheck/options.rb
Normal file
105
Library/Homebrew/livecheck/options.rb
Normal file
@ -0,0 +1,105 @@
|
||||
# typed: strong
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
# Options to modify livecheck's behavior. These primarily come from
|
||||
# `livecheck` blocks but they can also be set by livecheck at runtime.
|
||||
#
|
||||
# Option values use a `nil` default to indicate that the value has not been
|
||||
# set.
|
||||
class Options < T::Struct
|
||||
# Whether to use brewed curl.
|
||||
prop :homebrew_curl, T.nilable(T::Boolean)
|
||||
|
||||
# Form data to use when making a `POST` request.
|
||||
prop :post_form, T.nilable(T::Hash[Symbol, String])
|
||||
|
||||
# JSON data to use when making a `POST` request.
|
||||
prop :post_json, T.nilable(T::Hash[Symbol, String])
|
||||
|
||||
# Returns a `Hash` of options that are provided as arguments to `url`.
|
||||
sig { returns(T::Hash[Symbol, T.untyped]) }
|
||||
def url_options
|
||||
{
|
||||
homebrew_curl:,
|
||||
post_form:,
|
||||
post_json:,
|
||||
}
|
||||
end
|
||||
|
||||
# Returns a `Hash` of all instance variables, using `String` keys.
|
||||
sig { returns(T::Hash[String, T.untyped]) }
|
||||
def to_hash
|
||||
T.let(serialize, T::Hash[String, T.untyped])
|
||||
end
|
||||
|
||||
# Returns a `Hash` of all instance variables, using `Symbol` keys.
|
||||
sig { returns(T::Hash[Symbol, T.untyped]) }
|
||||
def to_h = to_hash.transform_keys(&:to_sym)
|
||||
|
||||
# Returns a new object formed by merging `other` values with a copy of
|
||||
# `self`.
|
||||
#
|
||||
# `nil` values are removed from `other` before merging if it is an
|
||||
# `Options` object, as these are unitiailized values. This ensures that
|
||||
# existing values in `self` aren't unexpectedly overwritten with defaults.
|
||||
sig { params(other: T.any(Options, T::Hash[Symbol, T.untyped])).returns(Options) }
|
||||
def merge(other)
|
||||
return dup if other.empty?
|
||||
|
||||
this_hash = to_h
|
||||
other_hash = other.is_a?(Options) ? other.to_h : other
|
||||
return dup if this_hash == other_hash
|
||||
|
||||
new_options = this_hash.merge(other_hash)
|
||||
Options.new(**new_options)
|
||||
end
|
||||
|
||||
# Merges values from `other` into `self` and returns `self`.
|
||||
#
|
||||
# `nil` values are removed from `other` before merging if it is an
|
||||
# `Options` object, as these are unitiailized values. This ensures that
|
||||
# existing values in `self` aren't unexpectedly overwritten with defaults.
|
||||
sig { params(other: T.any(Options, T::Hash[Symbol, T.untyped])).returns(Options) }
|
||||
def merge!(other)
|
||||
return self if other.empty?
|
||||
|
||||
if other.is_a?(Options)
|
||||
return self if self == other
|
||||
|
||||
other.instance_variables.each do |ivar|
|
||||
next if (v = T.let(other.instance_variable_get(ivar), Object)).nil?
|
||||
|
||||
instance_variable_set(ivar, v)
|
||||
end
|
||||
else
|
||||
other.each do |k, v|
|
||||
cmd = :"#{k}="
|
||||
send(cmd, v) if respond_to?(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
sig { params(other: Object).returns(T::Boolean) }
|
||||
def ==(other)
|
||||
return false unless other.is_a?(Options)
|
||||
|
||||
@homebrew_curl == other.homebrew_curl &&
|
||||
@post_form == other.post_form &&
|
||||
@post_json == other.post_json
|
||||
end
|
||||
alias eql? ==
|
||||
|
||||
# Whether the object has only default values.
|
||||
sig { returns(T::Boolean) }
|
||||
def empty? = to_hash.empty?
|
||||
|
||||
# Whether the object has any non-default values.
|
||||
sig { returns(T::Boolean) }
|
||||
def present? = !empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
40
Library/Homebrew/livecheck/strategic.rb
Normal file
40
Library/Homebrew/livecheck/strategic.rb
Normal file
@ -0,0 +1,40 @@
|
||||
# typed: strong
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
# The interface for livecheck strategies. Because third-party strategies
|
||||
# are not required to extend this module, we do not provide any default
|
||||
# method implementations here.
|
||||
module Strategic
|
||||
extend T::Helpers
|
||||
interface!
|
||||
|
||||
# Whether the strategy can be applied to the provided URL.
|
||||
#
|
||||
# @param url [String] the URL to match against
|
||||
sig { abstract.params(url: String).returns(T::Boolean) }
|
||||
def match?(url); end
|
||||
|
||||
# Checks the content at the URL for new versions. Implementations may not
|
||||
# support all options.
|
||||
#
|
||||
# @param url the URL of the content to check
|
||||
# @param regex a regex for matching versions in content
|
||||
# @param provided_content content to check instead of
|
||||
# fetching
|
||||
# @param options options to modify behavior
|
||||
# @param block a block to match the content
|
||||
sig {
|
||||
abstract.params(
|
||||
url: String,
|
||||
regex: T.nilable(Regexp),
|
||||
provided_content: T.nilable(String),
|
||||
options: Options,
|
||||
block: T.nilable(Proc),
|
||||
).returns(T::Hash[Symbol, T.anything])
|
||||
}
|
||||
def find_versions(url:, regex: nil, provided_content: nil, options: Options.new, &block); end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -2,6 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/curl"
|
||||
require "livecheck/options"
|
||||
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
@ -172,8 +173,8 @@ module Homebrew
|
||||
# @return [Array]
|
||||
sig {
|
||||
params(
|
||||
post_form: T.nilable(T::Hash[T.any(String, Symbol), String]),
|
||||
post_json: T.nilable(T::Hash[T.any(String, Symbol), String]),
|
||||
post_form: T.nilable(T::Hash[Symbol, String]),
|
||||
post_json: T.nilable(T::Hash[Symbol, String]),
|
||||
).returns(T::Array[String])
|
||||
}
|
||||
def self.post_args(post_form: nil, post_json: nil)
|
||||
@ -193,23 +194,16 @@ module Homebrew
|
||||
# collected into an array of hashes.
|
||||
#
|
||||
# @param url [String] the URL to fetch
|
||||
# @param url_options [Hash] options to modify curl behavior
|
||||
# @param homebrew_curl [Boolean] whether to use brewed curl with the URL
|
||||
# @param options [Options] options to modify behavior
|
||||
# @return [Array]
|
||||
sig {
|
||||
params(
|
||||
url: String,
|
||||
url_options: T::Hash[Symbol, T.untyped],
|
||||
homebrew_curl: T::Boolean,
|
||||
).returns(T::Array[T::Hash[String, String]])
|
||||
}
|
||||
def self.page_headers(url, url_options: {}, homebrew_curl: false)
|
||||
sig { params(url: String, options: Options).returns(T::Array[T::Hash[String, String]]) }
|
||||
def self.page_headers(url, options: Options.new)
|
||||
headers = []
|
||||
|
||||
if url_options[:post_form].present? || url_options[:post_json].present?
|
||||
if options.post_form || options.post_json
|
||||
curl_post_args = ["--request", "POST", *post_args(
|
||||
post_form: url_options[:post_form],
|
||||
post_json: url_options[:post_json],
|
||||
post_form: options.post_form,
|
||||
post_json: options.post_json,
|
||||
)]
|
||||
end
|
||||
|
||||
@ -221,7 +215,7 @@ module Homebrew
|
||||
MAX_REDIRECTIONS.to_s,
|
||||
url,
|
||||
wanted_headers: ["location", "content-disposition"],
|
||||
use_homebrew_curl: homebrew_curl,
|
||||
use_homebrew_curl: options.homebrew_curl || false,
|
||||
user_agent:,
|
||||
**DEFAULT_CURL_OPTIONS,
|
||||
)
|
||||
@ -242,21 +236,14 @@ module Homebrew
|
||||
# array with the error message instead.
|
||||
#
|
||||
# @param url [String] the URL of the content to check
|
||||
# @param url_options [Hash] options to modify curl behavior
|
||||
# @param homebrew_curl [Boolean] whether to use brewed curl with the URL
|
||||
# @param options [Options] options to modify behavior
|
||||
# @return [Hash]
|
||||
sig {
|
||||
params(
|
||||
url: String,
|
||||
url_options: T::Hash[Symbol, T.untyped],
|
||||
homebrew_curl: T::Boolean,
|
||||
).returns(T::Hash[Symbol, T.untyped])
|
||||
}
|
||||
def self.page_content(url, url_options: {}, homebrew_curl: false)
|
||||
if url_options[:post_form].present? || url_options[:post_json].present?
|
||||
sig { params(url: String, options: Options).returns(T::Hash[Symbol, T.untyped]) }
|
||||
def self.page_content(url, options: Options.new)
|
||||
if options.post_form || options.post_json
|
||||
curl_post_args = ["--request", "POST", *post_args(
|
||||
post_form: url_options[:post_form],
|
||||
post_json: url_options[:post_json],
|
||||
post_form: options.post_form,
|
||||
post_json: options.post_json,
|
||||
)]
|
||||
end
|
||||
|
||||
@ -266,7 +253,9 @@ module Homebrew
|
||||
*curl_post_args,
|
||||
*PAGE_CONTENT_CURL_ARGS, url,
|
||||
**DEFAULT_CURL_OPTIONS,
|
||||
use_homebrew_curl: homebrew_curl || !curl_supports_fail_with_body?,
|
||||
use_homebrew_curl: options.homebrew_curl ||
|
||||
!curl_supports_fail_with_body? ||
|
||||
false,
|
||||
user_agent:
|
||||
)
|
||||
next unless status.success?
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
module Strategy
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user