mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
27a040cc32
7
.github/codeql/extensions/homebrew-actions.yml
vendored
Normal file
7
.github/codeql/extensions/homebrew-actions.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is synced from the `.github` repository, do not modify it directly.
|
||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/actions-all
|
||||||
|
extensible: trustedActionsOwnerDataModel
|
||||||
|
data:
|
||||||
|
- ["Homebrew"]
|
63
.github/workflows/actionlint.yml
vendored
63
.github/workflows/actionlint.yml
vendored
@ -1,18 +1,19 @@
|
|||||||
name: actionlint
|
# This file is synced from the `.github` repository, do not modify it directly.
|
||||||
|
name: Actionlint
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/*.ya?ml'
|
||||||
|
- 'Formula/a/actionlint.rb'
|
||||||
|
- 'Formula/s/shellcheck.rb'
|
||||||
|
- 'Formula/z/zizmor.rb'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/*.ya?ml'
|
- '.github/workflows/*.ya?ml'
|
||||||
- '.github/actionlint.yaml'
|
|
||||||
|
|
||||||
env:
|
|
||||||
HOMEBREW_DEVELOPER: 1
|
|
||||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
|
||||||
HOMEBREW_NO_ENV_HINTS: 1
|
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@ -22,16 +23,23 @@ concurrency:
|
|||||||
group: "actionlint-${{ github.ref }}"
|
group: "actionlint-${{ github.ref }}"
|
||||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
env:
|
||||||
|
HOMEBREW_DEVELOPER: 1
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
HOMEBREW_NO_ENV_HINTS: 1
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
workflow_syntax:
|
workflow_syntax:
|
||||||
if: github.repository_owner == 'Homebrew'
|
if: github.repository_owner == 'Homebrew'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: setup-homebrew
|
id: setup-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -40,31 +48,42 @@ jobs:
|
|||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: brew install actionlint shellcheck zizmor
|
run: brew install actionlint shellcheck zizmor
|
||||||
|
|
||||||
- name: Set up GITHUB_WORKSPACE
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
env:
|
with:
|
||||||
HOMEBREW_REPOSITORY: ${{ steps.setup-homebrew.outputs.repository-path }}
|
persist-credentials: false
|
||||||
run: |
|
|
||||||
# Annotations work only relative to GITHUB_WORKSPACE
|
|
||||||
(shopt -s dotglob; rm -rf "${GITHUB_WORKSPACE:?}"/*; mv "${HOMEBREW_REPOSITORY:?}"/* "$GITHUB_WORKSPACE")
|
|
||||||
rmdir "$HOMEBREW_REPOSITORY"
|
|
||||||
ln -vs "$GITHUB_WORKSPACE" "$HOMEBREW_REPOSITORY"
|
|
||||||
|
|
||||||
echo "::add-matcher::.github/actionlint-matcher.json"
|
- run: zizmor --format sarif . > results.sarif
|
||||||
|
|
||||||
- run: |
|
|
||||||
# NOTE: exit code intentionally suppressed here
|
|
||||||
zizmor --format sarif . > results.sarif || true
|
|
||||||
|
|
||||||
- name: Upload SARIF file
|
- name: Upload SARIF file
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
|
# We can't use the SARIF file when triggered by `merge_group` so we don't upload it.
|
||||||
|
if: always() && github.event_name != 'merge_group'
|
||||||
with:
|
with:
|
||||||
name: results.sarif
|
name: results.sarif
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|
||||||
|
- name: Set up actionlint
|
||||||
|
run: |
|
||||||
|
# In homebrew-core, setting `shell: /bin/bash` prevents shellcheck from running on
|
||||||
|
# those steps, so let's change them to `shell: bash` temporarily for better linting.
|
||||||
|
sed -i 's|shell: /bin/bash -x|shell: bash -x|' .github/workflows/*.y*ml
|
||||||
|
|
||||||
|
# In homebrew-core, the JSON matcher needs to be accessible to the container host.
|
||||||
|
cp "$(brew --repository)/.github/actionlint-matcher.json" "$HOME"
|
||||||
|
|
||||||
|
echo "::add-matcher::$HOME/actionlint-matcher.json"
|
||||||
|
|
||||||
- run: actionlint
|
- run: actionlint
|
||||||
|
|
||||||
upload_sarif:
|
upload_sarif:
|
||||||
needs: workflow_syntax
|
needs: workflow_syntax
|
||||||
|
# We want to always upload this even if `actionlint` failed.
|
||||||
|
# This is only available on public repositories.
|
||||||
|
if: >
|
||||||
|
always() &&
|
||||||
|
!contains(fromJSON('["cancelled", "skipped"]'), needs.workflow_syntax.result) &&
|
||||||
|
!github.event.repository.private &&
|
||||||
|
github.event_name != 'merge_group'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@ -77,7 +96,7 @@ jobs:
|
|||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|
||||||
- name: Upload SARIF file
|
- name: Upload SARIF file
|
||||||
uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
category: zizmor
|
category: zizmor
|
||||||
|
2
.github/workflows/autogenerated-files.yml
vendored
2
.github/workflows/autogenerated-files.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
|
7
.github/workflows/codeql-analysis.yml
vendored
7
.github/workflows/codeql-analysis.yml
vendored
@ -3,10 +3,9 @@ name: "CodeQL"
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@ -28,7 +27,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
|
||||||
with:
|
with:
|
||||||
languages: ruby
|
languages: ruby
|
||||||
config: |
|
config: |
|
||||||
@ -36,4 +35,4 @@ jobs:
|
|||||||
- Library/Homebrew/vendor
|
- Library/Homebrew/vendor
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
|
||||||
|
15
.github/workflows/docker.yml
vendored
15
.github/workflows/docker.yml
vendored
@ -4,6 +4,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
merge_group:
|
merge_group:
|
||||||
release:
|
release:
|
||||||
@ -38,8 +39,8 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Fetch origin/master from Git
|
- name: Fetch origin/HEAD from Git
|
||||||
run: git fetch origin master
|
run: git fetch origin HEAD
|
||||||
|
|
||||||
- name: Determine build attributes
|
- name: Determine build attributes
|
||||||
id: attributes
|
id: attributes
|
||||||
@ -83,12 +84,16 @@ jobs:
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
elif [[ "${GITHUB_EVENT_NAME}" == "push" &&
|
elif [[ "${GITHUB_EVENT_NAME}" == "push" &&
|
||||||
"${GITHUB_REF}" == "refs/heads/master" &&
|
("${GITHUB_REF}" == "refs/heads/master" || "${GITHUB_REF}" == "refs/heads/main") &&
|
||||||
"${version}" == "22.04" ]]; then
|
"${version}" == "22.04" ]]; then
|
||||||
tags+=(
|
tags+=(
|
||||||
|
"ghcr.io/homebrew/brew:main"
|
||||||
"ghcr.io/homebrew/brew:master"
|
"ghcr.io/homebrew/brew:master"
|
||||||
|
"ghcr.io/homebrew/ubuntu${version}:main"
|
||||||
"ghcr.io/homebrew/ubuntu${version}:master"
|
"ghcr.io/homebrew/ubuntu${version}:master"
|
||||||
|
"homebrew/brew:main"
|
||||||
"homebrew/brew:master"
|
"homebrew/brew:master"
|
||||||
|
"homebrew/ubuntu${version}:main"
|
||||||
"homebrew/ubuntu${version}:master"
|
"homebrew/ubuntu${version}:master"
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
@ -160,8 +165,8 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Fetch origin/master from Git
|
- name: Fetch origin/HEAD from Git
|
||||||
run: git fetch origin master
|
run: git fetch origin HEAD
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||||
|
6
.github/workflows/docs.yml
vendored
6
.github/workflows/docs.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
run: vale docs/
|
run: vale docs/
|
||||||
|
|
||||||
- name: Install Ruby
|
- name: Install Ruby
|
||||||
uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
|
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||||
with:
|
with:
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
@ -67,7 +67,7 @@ jobs:
|
|||||||
- name: Generate formulae.brew.sh API samples
|
- name: Generate formulae.brew.sh API samples
|
||||||
if: github.repository == 'Homebrew/formulae.brew.sh'
|
if: github.repository == 'Homebrew/formulae.brew.sh'
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
run: ../script/generate-api-samples.rb
|
run: ../script/generate-api-samples.rb --template
|
||||||
|
|
||||||
- name: Build the site and check for broken links
|
- name: Build the site and check for broken links
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
|
4
.github/workflows/doctor.yml
vendored
4
.github/workflows/doctor.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -55,7 +55,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
|
8
.github/workflows/pkg-installer.yml
vendored
8
.github/workflows/pkg-installer.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -135,7 +135,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Generate build provenance
|
- name: Generate build provenance
|
||||||
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
|
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||||
with:
|
with:
|
||||||
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
subject-path: Homebrew-${{ steps.homebrew-version.outputs.version }}.pkg
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
steps:
|
steps:
|
||||||
- name: Open, update, or close pkg installer issue
|
- name: Open, update, or close pkg installer issue
|
||||||
uses: Homebrew/actions/create-or-update-issue@master
|
uses: Homebrew/actions/create-or-update-issue@main
|
||||||
with:
|
with:
|
||||||
title: Failed to publish pkg installer
|
title: Failed to publish pkg installer
|
||||||
body: >
|
body: >
|
||||||
@ -259,7 +259,7 @@ jobs:
|
|||||||
${{ github.ref_name }}. No pkg installer was uploaded to the GitHub
|
${{ github.ref_name }}. No pkg installer was uploaded to the GitHub
|
||||||
release.
|
release.
|
||||||
labels: bug,release blocker
|
labels: bug,release blocker
|
||||||
update-existing: ${{ contains(needs.*.result, 'failure') }}
|
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||||
close-existing: ${{ needs.upload.result == 'success' }}
|
close-existing: ${{ needs.upload.result == 'success' }}
|
||||||
close-from-author: github-actions[bot]
|
close-from-author: github-actions[bot]
|
||||||
close-comment: >
|
close-comment: >
|
||||||
|
5
.github/workflows/rubydoc.yml
vendored
5
.github/workflows/rubydoc.yml
vendored
@ -3,6 +3,7 @@ name: Ruby Documentation CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -42,7 +43,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Install Ruby
|
- name: Install Ruby
|
||||||
uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
|
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
||||||
with:
|
with:
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
working-directory: rubydoc
|
working-directory: rubydoc
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
name: Update schema data
|
name: Update SBOM schema
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/schemas.yml
|
- .github/workflows/sbom.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -17,25 +18,25 @@ defaults:
|
|||||||
shell: bash -xeuo pipefail {0}
|
shell: bash -xeuo pipefail {0}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spdx:
|
sbom:
|
||||||
if: github.repository == 'Homebrew/brew'
|
if: github.repository == 'Homebrew/brew'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/data/schemas"
|
git checkout "Library/Homebrew/data/schemas"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Intentionally tracking 2.3.x to match what we output in sbom.rb. 3.0 also doesn't have a JSON Schema.
|
# Intentionally tracking 2.3.x to match what we output in sbom.rb. 3.0 also doesn't have a JSON Schema.
|
||||||
@ -67,9 +68,10 @@ jobs:
|
|||||||
if ! git diff --exit-code Library/Homebrew/data/schemas
|
if ! git diff --exit-code Library/Homebrew/data/schemas
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/data/schemas"
|
git add "Library/Homebrew/data/schemas"
|
||||||
git commit -m "data/schemas: update schema data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/master/.github/workflows/schemas.yml)."
|
git commit -m "data/schemas: update schema data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/schemas.yml)."
|
||||||
|
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -78,13 +80,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.update.outputs.pull_request == 'true'
|
if: steps.update.outputs.pull_request == 'true'
|
||||||
@ -92,3 +94,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
|
|
||||||
|
issue:
|
||||||
|
needs: sbom
|
||||||
|
if: always() && github.event_name == 'schedule'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
permissions:
|
||||||
|
# To create or update issues
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- name: Open, update, or close schema issue
|
||||||
|
uses: Homebrew/actions/create-or-update-issue@main
|
||||||
|
with:
|
||||||
|
title: Failed to update SBOM schema
|
||||||
|
body: >
|
||||||
|
The SBOM schema workflow [failed](${{ env.RUN_URL }}). No SBOM schema was updated.
|
||||||
|
labels: bug
|
||||||
|
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||||
|
close-existing: ${{ needs.sbom.result == 'success' }}
|
||||||
|
close-from-author: github-actions[bot]
|
||||||
|
close-comment: >
|
||||||
|
The SBOM schema workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
42
.github/workflows/sorbet.yml
vendored
42
.github/workflows/sorbet.yml
vendored
@ -10,6 +10,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- .github/workflows/sorbet.yml
|
- .github/workflows/sorbet.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -29,7 +30,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -37,13 +38,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/sorbet"
|
git checkout "Library/Homebrew/sorbet"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -80,17 +81,17 @@ jobs:
|
|||||||
then
|
then
|
||||||
git add "Library/Homebrew/sorbet"
|
git add "Library/Homebrew/sorbet"
|
||||||
git commit -m "sorbet: Update RBI files." \
|
git commit -m "sorbet: Update RBI files." \
|
||||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow."
|
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sorbet.yml) workflow."
|
||||||
|
|
||||||
if ! git diff --stat --exit-code "Library/Homebrew"
|
if ! git diff --stat --exit-code "Library/Homebrew"
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/"
|
git add "Library/Homebrew/"
|
||||||
git commit -m "sorbet: Autobump sigils via Spoom" \
|
git commit -m "sorbet: Autobump sigils via Spoom" \
|
||||||
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/master/.github/workflows/sorbet.yml) workflow."
|
-m "Autogenerated by the [sorbet](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sorbet.yml) workflow."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -99,13 +100,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.commit.outputs.committed == 'true'
|
if: steps.commit.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.commit.outputs.pull_request == 'true'
|
if: steps.commit.outputs.pull_request == 'true'
|
||||||
@ -113,3 +114,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
|
|
||||||
|
issue:
|
||||||
|
needs: tapioca
|
||||||
|
if: always() && github.event_name == 'schedule'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
permissions:
|
||||||
|
# To create or update issues
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- name: Open, update, or close Sorbet issue
|
||||||
|
uses: Homebrew/actions/create-or-update-issue@main
|
||||||
|
with:
|
||||||
|
title: Failed to update RBI files
|
||||||
|
body: >
|
||||||
|
The Sorbet workflow [failed](${{ env.RUN_URL }}). No RBI files were updated.
|
||||||
|
labels: bug
|
||||||
|
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||||
|
close-existing: ${{ needs.tapioca.result == 'success' }}
|
||||||
|
close-from-author: github-actions[bot]
|
||||||
|
close-comment: >
|
||||||
|
The Sorbet workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||||
|
41
.github/workflows/spdx.yml
vendored
41
.github/workflows/spdx.yml
vendored
@ -4,6 +4,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- .github/workflows/spdx.yml
|
- .github/workflows/spdx.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
@ -23,19 +24,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -55,15 +56,16 @@ jobs:
|
|||||||
git checkout "${BRANCH}"
|
git checkout "${BRANCH}"
|
||||||
git checkout "Library/Homebrew/data/spdx"
|
git checkout "Library/Homebrew/data/spdx"
|
||||||
else
|
else
|
||||||
git checkout --no-track -B "${BRANCH}" origin/master
|
git checkout --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if brew update-license-data
|
if brew update-license-data
|
||||||
then
|
then
|
||||||
git add "Library/Homebrew/data/spdx"
|
git add "Library/Homebrew/data/spdx"
|
||||||
git commit -m "spdx: update license data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/master/.github/workflows/spdx.yml)."
|
git commit -m "spdx: update license data." -m "Autogenerated by [a scheduled GitHub Action](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/spdx.yml)."
|
||||||
|
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -72,13 +74,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
branch: ${{ steps.update.outputs.branch }}
|
branch: ${{ steps.update.outputs.branch }}
|
||||||
force: true
|
force: true
|
||||||
origin_branch: "master"
|
origin_branch: "HEAD"
|
||||||
|
|
||||||
- name: Open a pull request
|
- name: Open a pull request
|
||||||
if: steps.update.outputs.pull_request == 'true'
|
if: steps.update.outputs.pull_request == 'true'
|
||||||
@ -86,3 +88,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
|
|
||||||
|
issue:
|
||||||
|
needs: spdx
|
||||||
|
if: always() && github.event_name == 'schedule'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
permissions:
|
||||||
|
# To create or update issues
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- name: Open, update, or close SPDX issue
|
||||||
|
uses: Homebrew/actions/create-or-update-issue@main
|
||||||
|
with:
|
||||||
|
title: Failed to update SPDX license data
|
||||||
|
body: >
|
||||||
|
The SPDX license data workflow [failed](${{ env.RUN_URL }}). No SPDX license data was updated.
|
||||||
|
labels: bug
|
||||||
|
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||||
|
close-existing: ${{ needs.spdx.result == 'success' }}
|
||||||
|
close-from-author: github-actions[bot]
|
||||||
|
close-comment: >
|
||||||
|
The SPDX license data workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||||
|
@ -3,6 +3,7 @@ name: Update sponsors, maintainers, manpage and completions
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/sponsors-maintainers-man-completions.yml
|
- .github/workflows/sponsors-maintainers-man-completions.yml
|
||||||
@ -32,19 +33,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Setup Homebrew
|
- name: Setup Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git fetch origin
|
git fetch origin
|
||||||
|
|
||||||
if [[ -n "$GITHUB_REF_NAME" && "$GITHUB_REF_NAME" != "master" ]]
|
if [[ -n "$GITHUB_REF_NAME" && "$GITHUB_REF_NAME" != "master" && "$GITHUB_REF_NAME" != "main" ]]
|
||||||
then
|
then
|
||||||
BRANCH="$GITHUB_REF_NAME"
|
BRANCH="$GITHUB_REF_NAME"
|
||||||
else
|
else
|
||||||
@ -76,7 +77,7 @@ jobs:
|
|||||||
"manpages/brew.1" \
|
"manpages/brew.1" \
|
||||||
"completions"
|
"completions"
|
||||||
else
|
else
|
||||||
git checkout --force --no-track -B "${BRANCH}" origin/master
|
git checkout --force --no-track -B "${BRANCH}" origin/HEAD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if brew update-sponsors
|
if brew update-sponsors
|
||||||
@ -111,7 +112,7 @@ jobs:
|
|||||||
if [[ -n "${COMMITTED-}" ]]
|
if [[ -n "${COMMITTED-}" ]]
|
||||||
then
|
then
|
||||||
echo "committed=true" >> "$GITHUB_OUTPUT"
|
echo "committed=true" >> "$GITHUB_OUTPUT"
|
||||||
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state")"
|
PULL_REQUEST_STATE="$(gh pr view --json=state | jq -r ".state" || true)"
|
||||||
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
if [[ "${PULL_REQUEST_STATE}" != "OPEN" ]]
|
||||||
then
|
then
|
||||||
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
echo "pull_request=true" >> "$GITHUB_OUTPUT"
|
||||||
@ -124,7 +125,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
if: steps.update.outputs.committed == 'true'
|
if: steps.update.outputs.committed == 'true'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
@ -137,3 +138,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
|
|
||||||
|
issue:
|
||||||
|
needs: updates
|
||||||
|
if: always() && github.event_name == 'schedule'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
permissions:
|
||||||
|
# To create or update issues
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- name: Open, update, or close sponsors, maintainers, manpage and completions issue
|
||||||
|
uses: Homebrew/actions/create-or-update-issue@main
|
||||||
|
with:
|
||||||
|
title: Failed to update sponsors, maintainers, manpage and completions
|
||||||
|
body: >
|
||||||
|
The sponsors, maintainers, manpage and completions workflow [failed](${{ env.RUN_URL }}). No sponsors, maintainers, manpage and completions were updated.
|
||||||
|
labels: bug
|
||||||
|
update-existing: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
|
||||||
|
close-existing: ${{ needs.updates.result == 'success' }}
|
||||||
|
close-from-author: github-actions[bot]
|
||||||
|
close-comment: >
|
||||||
|
The sponsors, maintainers, manpage and completions workflow [succeeded](${{ env.RUN_URL }}). Closing this issue.
|
||||||
|
63
.github/workflows/sync-default-branches.yml
vendored
Normal file
63
.github/workflows/sync-default-branches.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
name: Sync default branches
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- .github/workflows/sync-default-branches.yml
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash -xeuo pipefail {0}
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: "sync-default-branches-${{ github.ref }}"
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- name: Configure Git user
|
||||||
|
uses: Homebrew/actions/git-user-config@main
|
||||||
|
with:
|
||||||
|
username: github-actions[bot]
|
||||||
|
|
||||||
|
- name: Determine source and target branches
|
||||||
|
id: branches
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||||
|
target="master"
|
||||||
|
source="main"
|
||||||
|
else
|
||||||
|
target="main"
|
||||||
|
source="master"
|
||||||
|
fi
|
||||||
|
echo "target=${target}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "source=${source}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: true
|
||||||
|
|
||||||
|
- name: Setup target branch
|
||||||
|
run: |
|
||||||
|
git checkout "${TARGET_BRANCH}" || git checkout -b "${TARGET_BRANCH}"
|
||||||
|
git reset --hard "origin/${SOURCE_BRANCH}"
|
||||||
|
env:
|
||||||
|
SOURCE_BRANCH: ${{ steps.branches.outputs.source }}
|
||||||
|
TARGET_BRANCH: ${{ steps.branches.outputs.target }}
|
||||||
|
|
||||||
|
- name: Push target branch
|
||||||
|
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
|
||||||
|
run: git push origin "${TARGET_BRANCH}" --force-with-lease
|
||||||
|
env:
|
||||||
|
TARGET_BRANCH: ${{ steps.branches.outputs.target }}
|
25
.github/workflows/tests.yml
vendored
25
.github/workflows/tests.yml
vendored
@ -3,6 +3,7 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
merge_group:
|
merge_group:
|
||||||
@ -32,7 +33,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -84,7 +85,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: true
|
core: true
|
||||||
cask: true
|
cask: true
|
||||||
@ -135,11 +136,12 @@ jobs:
|
|||||||
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
if: github.repository_owner == 'Homebrew' && github.event_name != 'push'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
|
# TODO: switch to main when we're pushing those images
|
||||||
image: ghcr.io/homebrew/brew:master
|
image: ghcr.io/homebrew/brew:master
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -162,7 +164,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: true
|
cask: true
|
||||||
@ -185,14 +187,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
test-bot: false
|
test-bot: false
|
||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
@ -220,7 +222,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -255,7 +257,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
# We only test needs_homebrew_core tests on macOS because
|
# We only test needs_homebrew_core tests on macOS because
|
||||||
# homebrew/core is not available by default on GitHub-hosted Ubuntu
|
# homebrew/core is not available by default on GitHub-hosted Ubuntu
|
||||||
@ -355,6 +357,7 @@ jobs:
|
|||||||
container: ghcr.io/homebrew/ubuntu24.04:latest
|
container: ghcr.io/homebrew/ubuntu24.04:latest
|
||||||
- name: test-bot (Linux x86_64)
|
- name: test-bot (Linux x86_64)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# TODO: switch to main when we've migrated to it
|
||||||
container: ghcr.io/homebrew/ubuntu22.04:master
|
container: ghcr.io/homebrew/ubuntu22.04:master
|
||||||
# Use Debian Old Stable for testing Homebrew's glibc support.
|
# Use Debian Old Stable for testing Homebrew's glibc support.
|
||||||
- name: test-bot (Linux Homebrew glibc)
|
- name: test-bot (Linux Homebrew glibc)
|
||||||
@ -402,7 +405,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -442,7 +445,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -496,7 +499,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
|
9
.github/workflows/vendor-gems.yml
vendored
9
.github/workflows/vendor-gems.yml
vendored
@ -9,6 +9,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- .github/workflows/vendor-gems.yml
|
- .github/workflows/vendor-gems.yml
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
|
- main
|
||||||
- master
|
- master
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
@ -31,7 +32,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
@ -39,13 +40,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure Git user
|
- name: Configure Git user
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
with:
|
with:
|
||||||
username: BrewTestBot
|
username: BrewTestBot
|
||||||
|
|
||||||
- name: Set up commit signing
|
- name: Set up commit signing
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/setup-commit-signing@master
|
uses: Homebrew/actions/setup-commit-signing@main
|
||||||
with:
|
with:
|
||||||
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
signing_key: ${{ secrets.BREWTESTBOT_SSH_SIGNING_KEY }}
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push to pull request
|
- name: Push to pull request
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
token: ${{ steps.app-token.outputs.token }}
|
||||||
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
directory: ${{ steps.set-up-homebrew.outputs.repository-path }}
|
||||||
|
2
.github/workflows/vendor-version.yml
vendored
2
.github/workflows/vendor-version.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
core: false
|
core: false
|
||||||
cask: false
|
cask: false
|
||||||
|
1
.github/zizmor.yml
vendored
1
.github/zizmor.yml
vendored
@ -1,3 +1,4 @@
|
|||||||
|
# This file is synced from the `.github` repository, do not modify it directly.
|
||||||
rules:
|
rules:
|
||||||
unpinned-uses:
|
unpinned-uses:
|
||||||
config:
|
config:
|
||||||
|
11
.vscode/mcp.json
vendored
Normal file
11
.vscode/mcp.json
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"servers": {
|
||||||
|
"Homebrew": {
|
||||||
|
"type": "stdio",
|
||||||
|
"command": "brew",
|
||||||
|
"args": [
|
||||||
|
"mcp-server"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
.vscode/ruby-lsp-activate.sh
vendored
9
.vscode/ruby-lsp-activate.sh
vendored
@ -1,5 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
HOMEBREW_PREFIX="$(cd "$(dirname "$0")"/../ && pwd)"
|
if [[ -n "${BASH_SOURCE[0]}" ]]; then
|
||||||
|
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
||||||
|
elif [[ -n "${ZSH_VERSION}" ]]; then
|
||||||
|
SCRIPT_PATH="${(%):-%x}"
|
||||||
|
else
|
||||||
|
SCRIPT_PATH="$0"
|
||||||
|
fi
|
||||||
|
HOMEBREW_PREFIX="$(cd "$(dirname "${SCRIPT_PATH}")"/../ && pwd)"
|
||||||
|
|
||||||
"${HOMEBREW_PREFIX}/bin/brew" install-bundler-gems --add-groups=style,typecheck,vscode >/dev/null 2>&1
|
"${HOMEBREW_PREFIX}/bin/brew" install-bundler-gems --add-groups=style,typecheck,vscode >/dev/null 2>&1
|
||||||
|
|
||||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -40,7 +40,6 @@
|
|||||||
"id": "default",
|
"id": "default",
|
||||||
"name": "Brew Typecheck",
|
"name": "Brew Typecheck",
|
||||||
"description": "Default configuration",
|
"description": "Default configuration",
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"command": [
|
"command": [
|
||||||
"./bin/brew",
|
"./bin/brew",
|
||||||
"typecheck",
|
"typecheck",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "api/analytics"
|
require "api/analytics"
|
||||||
@ -11,10 +11,10 @@ module Homebrew
|
|||||||
module API
|
module API
|
||||||
extend Cachable
|
extend Cachable
|
||||||
|
|
||||||
HOMEBREW_CACHE_API = (HOMEBREW_CACHE/"api").freeze
|
HOMEBREW_CACHE_API = T.let((HOMEBREW_CACHE/"api").freeze, Pathname)
|
||||||
HOMEBREW_CACHE_API_SOURCE = (HOMEBREW_CACHE/"api-source").freeze
|
HOMEBREW_CACHE_API_SOURCE = T.let((HOMEBREW_CACHE/"api-source").freeze, Pathname)
|
||||||
|
|
||||||
sig { params(endpoint: String).returns(Hash) }
|
sig { params(endpoint: String).returns(T::Hash[String, T.untyped]) }
|
||||||
def self.fetch(endpoint)
|
def self.fetch(endpoint)
|
||||||
return cache[endpoint] if cache.present? && cache.key?(endpoint)
|
return cache[endpoint] if cache.present? && cache.key?(endpoint)
|
||||||
|
|
||||||
@ -33,7 +33,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
params(endpoint: String, target: Pathname, stale_seconds: Integer).returns([T.any(Array, Hash), T::Boolean])
|
params(endpoint: String, target: Pathname,
|
||||||
|
stale_seconds: Integer).returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
|
||||||
}
|
}
|
||||||
def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
|
def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
|
||||||
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i)
|
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i)
|
||||||
@ -96,7 +97,8 @@ module Homebrew
|
|||||||
|
|
||||||
mtime = insecure_download ? Time.new(1970, 1, 1) : Time.now
|
mtime = insecure_download ? Time.new(1970, 1, 1) : Time.now
|
||||||
FileUtils.touch(target, mtime:) unless skip_download
|
FileUtils.touch(target, mtime:) unless skip_download
|
||||||
JSON.parse(target.read(encoding: Encoding::UTF_8), freeze: true)
|
# Can use `target.read` again when/if https://github.com/sorbet/sorbet/pull/8999 is merged/released.
|
||||||
|
JSON.parse(File.read(target, encoding: Encoding::UTF_8), freeze: true)
|
||||||
rescue JSON::ParserError
|
rescue JSON::ParserError
|
||||||
target.unlink
|
target.unlink
|
||||||
retry_count += 1
|
retry_count += 1
|
||||||
@ -122,8 +124,11 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(json: Hash, bottle_tag: T.nilable(::Utils::Bottles::Tag)).returns(Hash) }
|
sig {
|
||||||
def self.merge_variations(json, bottle_tag: nil)
|
params(json: T::Hash[String, T.untyped],
|
||||||
|
bottle_tag: ::Utils::Bottles::Tag).returns(T::Hash[String, T.untyped])
|
||||||
|
}
|
||||||
|
def self.merge_variations(json, bottle_tag: T.unsafe(nil))
|
||||||
return json unless json.key?("variations")
|
return json unless json.key?("variations")
|
||||||
|
|
||||||
bottle_tag ||= Homebrew::SimulateSystem.current_tag
|
bottle_tag ||= Homebrew::SimulateSystem.current_tag
|
||||||
@ -147,7 +152,10 @@ module Homebrew
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(json_data: Hash).returns([T::Boolean, T.any(String, Array, Hash)]) }
|
sig {
|
||||||
|
params(json_data: T::Hash[String, T.untyped])
|
||||||
|
.returns([T::Boolean, T.any(String, T::Array[T.untyped], T::Hash[String, T.untyped])])
|
||||||
|
}
|
||||||
private_class_method def self.verify_and_parse_jws(json_data)
|
private_class_method def self.verify_and_parse_jws(json_data)
|
||||||
signatures = json_data["signatures"]
|
signatures = json_data["signatures"]
|
||||||
homebrew_signature = signatures&.find { |sig| sig.dig("header", "kid") == "homebrew-1" }
|
homebrew_signature = signatures&.find { |sig| sig.dig("header", "kid") == "homebrew-1" }
|
||||||
|
@ -10,7 +10,6 @@ module Homebrew
|
|||||||
def analytics_api_path
|
def analytics_api_path
|
||||||
"analytics"
|
"analytics"
|
||||||
end
|
end
|
||||||
alias generic_analytics_api_path analytics_api_path
|
|
||||||
|
|
||||||
sig { params(category: String, days: T.any(Integer, String)).returns(T::Hash[String, T.untyped]) }
|
sig { params(category: String, days: T.any(Integer, String)).returns(T::Hash[String, T.untyped]) }
|
||||||
def fetch(category, days)
|
def fetch(category, days)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "cachable"
|
require "cachable"
|
||||||
@ -21,7 +21,7 @@ module Homebrew
|
|||||||
|
|
||||||
private_class_method :cache
|
private_class_method :cache
|
||||||
|
|
||||||
sig { params(token: String).returns(Hash) }
|
sig { params(token: String).returns(T::Hash[String, T.untyped]) }
|
||||||
def self.fetch(token)
|
def self.fetch(token)
|
||||||
Homebrew::API.fetch "cask/#{token}.json"
|
Homebrew::API.fetch "cask/#{token}.json"
|
||||||
end
|
end
|
||||||
@ -47,6 +47,7 @@ module Homebrew
|
|||||||
.load(config: cask.config)
|
.load(config: cask.config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Pathname) }
|
||||||
def self.cached_json_file_path
|
def self.cached_json_file_path
|
||||||
HOMEBREW_CACHE_API/api_filename
|
HOMEBREW_CACHE_API/api_filename
|
||||||
end
|
end
|
||||||
@ -70,7 +71,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
private_class_method :download_and_cache_data!
|
private_class_method :download_and_cache_data!
|
||||||
|
|
||||||
sig { returns(T::Hash[String, Hash]) }
|
sig { returns(T::Hash[String, T::Hash[String, T.untyped]]) }
|
||||||
def self.all_casks
|
def self.all_casks
|
||||||
unless cache.key?("casks")
|
unless cache.key?("casks")
|
||||||
json_updated = download_and_cache_data!
|
json_updated = download_and_cache_data!
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Used to substitute common paths with generic placeholders when generating JSON for the API.
|
# Used to substitute common paths with generic placeholders when generating JSON for the API.
|
||||||
module APIHashable
|
module APIHashable
|
||||||
|
sig { void }
|
||||||
def generating_hash!
|
def generating_hash!
|
||||||
return if generating_hash?
|
return if generating_hash?
|
||||||
|
|
||||||
# Apply monkeypatches for API generation
|
# Apply monkeypatches for API generation
|
||||||
@old_homebrew_prefix = HOMEBREW_PREFIX
|
@old_homebrew_prefix = T.let(HOMEBREW_PREFIX, T.nilable(Pathname))
|
||||||
@old_homebrew_cellar = HOMEBREW_CELLAR
|
@old_homebrew_cellar = T.let(HOMEBREW_CELLAR, T.nilable(Pathname))
|
||||||
@old_home = Dir.home
|
@old_home = T.let(Dir.home, T.nilable(String))
|
||||||
|
@old_git_config_global = T.let(ENV.fetch("GIT_CONFIG_GLOBAL", nil), T.nilable(String))
|
||||||
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
||||||
Object.const_set(:HOMEBREW_PREFIX, Pathname.new(HOMEBREW_PREFIX_PLACEHOLDER))
|
Object.const_set(:HOMEBREW_PREFIX, Pathname.new(HOMEBREW_PREFIX_PLACEHOLDER))
|
||||||
ENV["HOME"] = HOMEBREW_HOME_PLACEHOLDER
|
ENV["HOME"] = HOMEBREW_HOME_PLACEHOLDER
|
||||||
|
ENV["GIT_CONFIG_GLOBAL"] = File.join(@old_home, ".gitconfig")
|
||||||
|
|
||||||
@generating_hash = true
|
@generating_hash = T.let(true, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def generated_hash!
|
def generated_hash!
|
||||||
return unless generating_hash?
|
return unless generating_hash?
|
||||||
|
|
||||||
@ -24,10 +28,12 @@ module APIHashable
|
|||||||
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
Object.send(:remove_const, :HOMEBREW_PREFIX)
|
||||||
Object.const_set(:HOMEBREW_PREFIX, @old_homebrew_prefix)
|
Object.const_set(:HOMEBREW_PREFIX, @old_homebrew_prefix)
|
||||||
ENV["HOME"] = @old_home
|
ENV["HOME"] = @old_home
|
||||||
|
ENV["GIT_CONFIG_GLOBAL"] = @old_git_config_global
|
||||||
|
|
||||||
@generating_hash = false
|
@generating_hash = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def generating_hash?
|
def generating_hash?
|
||||||
@generating_hash ||= false
|
@generating_hash ||= false
|
||||||
@generating_hash == true
|
@generating_hash == true
|
||||||
|
@ -52,4 +52,4 @@ FORMULA_COMPONENT_PRECEDENCE_LIST = T.let([
|
|||||||
[{ name: :caveats, type: :method_definition }],
|
[{ name: :caveats, type: :method_definition }],
|
||||||
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
||||||
[{ name: :test, type: :block_call }],
|
[{ name: :test, type: :block_call }],
|
||||||
].freeze, T::Array[[{ name: Symbol, type: Symbol }]])
|
].freeze, T::Array[T::Array[{ name: Symbol, type: Symbol }]])
|
||||||
|
@ -614,6 +614,8 @@ esac
|
|||||||
# and, if needed:
|
# and, if needed:
|
||||||
# - MacOSVersion::SYMBOLS
|
# - MacOSVersion::SYMBOLS
|
||||||
HOMEBREW_MACOS_NEWEST_UNSUPPORTED="16"
|
HOMEBREW_MACOS_NEWEST_UNSUPPORTED="16"
|
||||||
|
# TODO: bump version when new macOS is released
|
||||||
|
HOMEBREW_MACOS_NEWEST_SUPPORTED="15"
|
||||||
# TODO: bump version when new macOS is released and update references in:
|
# TODO: bump version when new macOS is released and update references in:
|
||||||
# - docs/Installation.md
|
# - docs/Installation.md
|
||||||
# - HOMEBREW_MACOS_OLDEST_SUPPORTED in .github/workflows/pkg-installer.yml
|
# - HOMEBREW_MACOS_OLDEST_SUPPORTED in .github/workflows/pkg-installer.yml
|
||||||
@ -841,6 +843,7 @@ export HOMEBREW_OS_VERSION
|
|||||||
export HOMEBREW_MACOS_VERSION
|
export HOMEBREW_MACOS_VERSION
|
||||||
export HOMEBREW_MACOS_VERSION_NUMERIC
|
export HOMEBREW_MACOS_VERSION_NUMERIC
|
||||||
export HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
export HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
||||||
|
export HOMEBREW_MACOS_NEWEST_SUPPORTED
|
||||||
export HOMEBREW_MACOS_OLDEST_SUPPORTED
|
export HOMEBREW_MACOS_OLDEST_SUPPORTED
|
||||||
export HOMEBREW_MACOS_OLDEST_ALLOWED
|
export HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
export HOMEBREW_USER_AGENT
|
export HOMEBREW_USER_AGENT
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "bundle/adder"
|
require "bundle/adder"
|
||||||
@ -7,6 +7,7 @@ module Homebrew
|
|||||||
module Bundle
|
module Bundle
|
||||||
module Commands
|
module Commands
|
||||||
module Add
|
module Add
|
||||||
|
sig { params(args: String, type: Symbol, global: T::Boolean, file: T.nilable(String)).void }
|
||||||
def self.run(*args, type:, global:, file:)
|
def self.run(*args, type:, global:, file:)
|
||||||
Homebrew::Bundle::Adder.add(*args, type:, global:, file:)
|
Homebrew::Bundle::Adder.add(*args, type:, global:, file:)
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,6 @@ module Homebrew
|
|||||||
puts "Installing #{name} tap. It is not currently installed." if verbose
|
puts "Installing #{name} tap. It is not currently installed." if verbose
|
||||||
args = []
|
args = []
|
||||||
args << "--force" if force
|
args << "--force" if force
|
||||||
args.append("--force-auto-update") if options[:force_auto_update]
|
|
||||||
|
|
||||||
success = if options[:clone_target]
|
success = if options[:clone_target]
|
||||||
Bundle.brew("tap", name, options[:clone_target], *args, verbose:)
|
Bundle.brew("tap", name, options[:clone_target], *args, verbose:)
|
||||||
|
@ -139,7 +139,11 @@ module Cask
|
|||||||
|
|
||||||
def initialize(cask, *dsl_args)
|
def initialize(cask, *dsl_args)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
|
@dirmethod = nil
|
||||||
@dsl_args = dsl_args.deep_dup
|
@dsl_args = dsl_args.deep_dup
|
||||||
|
@dsl_key = nil
|
||||||
|
@english_article = nil
|
||||||
|
@english_name = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def config
|
def config
|
||||||
|
@ -41,7 +41,9 @@ module Cask
|
|||||||
super
|
super
|
||||||
|
|
||||||
target = target_hash[:target]
|
target = target_hash[:target]
|
||||||
|
@source = nil
|
||||||
@source_string = source.to_s
|
@source_string = source.to_s
|
||||||
|
@target = nil
|
||||||
@target_string = target.to_s
|
@target_string = target.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Sorted set containing all cask artifacts.
|
# Sorted set containing all cask artifacts.
|
||||||
class ArtifactSet < ::Set
|
class ArtifactSet < ::Set
|
||||||
|
extend T::Generic
|
||||||
|
|
||||||
|
Elem = type_member(:out) { { fixed: Artifact::AbstractArtifact } }
|
||||||
|
|
||||||
|
sig { params(block: T.nilable(T.proc.params(arg0: Elem).returns(T.untyped))).void }
|
||||||
def each(&block)
|
def each(&block)
|
||||||
return enum_for(T.must(__method__)) { size } unless block
|
return enum_for(T.must(__method__)) { size } unless block
|
||||||
|
|
||||||
@ -11,6 +16,7 @@ module Cask
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Array[Artifact::AbstractArtifact]) }
|
||||||
def to_a
|
def to_a
|
||||||
super.sort
|
super.sort
|
||||||
end
|
end
|
||||||
|
@ -653,11 +653,12 @@ module Cask
|
|||||||
|
|
||||||
supports_arm = result.merged_output.include?("arm64")
|
supports_arm = result.merged_output.include?("arm64")
|
||||||
mentions_rosetta = cask.caveats.include?("requires Rosetta 2")
|
mentions_rosetta = cask.caveats.include?("requires Rosetta 2")
|
||||||
|
requires_intel = cask.depends_on.arch&.any? { |arch| arch[:type] == :intel }
|
||||||
|
|
||||||
if supports_arm && mentions_rosetta
|
if supports_arm && mentions_rosetta
|
||||||
add_error "Artifacts do not require Rosetta 2 but the caveats say otherwise!",
|
add_error "Artifacts do not require Rosetta 2 but the caveats say otherwise!",
|
||||||
location: url.location
|
location: url.location
|
||||||
elsif !supports_arm && !mentions_rosetta
|
elsif !supports_arm && !mentions_rosetta && !requires_intel
|
||||||
add_error "Artifacts require Rosetta 2 but this is not indicated by the caveats!",
|
add_error "Artifacts require Rosetta 2 but this is not indicated by the caveats!",
|
||||||
location: url.location
|
location: url.location
|
||||||
end
|
end
|
||||||
@ -701,45 +702,53 @@ module Cask
|
|||||||
return unless online?
|
return unless online?
|
||||||
return unless strict?
|
return unless strict?
|
||||||
|
|
||||||
odebug "Auditing minimum OS version"
|
odebug "Auditing minimum macOS version"
|
||||||
|
|
||||||
plist_min_os = cask_plist_min_os
|
bundle_min_os = cask_bundle_min_os
|
||||||
sparkle_min_os = livecheck_min_os
|
sparkle_min_os = cask_sparkle_min_os
|
||||||
|
|
||||||
|
app_min_os = [bundle_min_os, sparkle_min_os].compact.max
|
||||||
debug_messages = []
|
debug_messages = []
|
||||||
debug_messages << "Plist #{plist_min_os}" if plist_min_os
|
debug_messages << "from artifact: #{bundle_min_os.to_sym}" if bundle_min_os
|
||||||
debug_messages << "Sparkle #{sparkle_min_os}" if sparkle_min_os
|
debug_messages << "from upstream: #{sparkle_min_os.to_sym}" if sparkle_min_os
|
||||||
odebug "Detected minimum OS version: #{debug_messages.join(" | ")}" unless debug_messages.empty?
|
odebug "Detected minimum macOS: #{app_min_os.to_sym} (#{debug_messages.join(" | ")})" if app_min_os
|
||||||
min_os = [plist_min_os, sparkle_min_os].compact.max
|
return if app_min_os.nil? || app_min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
|
|
||||||
return if min_os.nil? || min_os <= HOMEBREW_MACOS_OLDEST_ALLOWED
|
|
||||||
|
|
||||||
on_system_block_min_os = cask.on_system_block_min_os
|
on_system_block_min_os = cask.on_system_block_min_os
|
||||||
cask_min_os = [on_system_block_min_os, cask.depends_on.macos&.minimum_version].compact.max
|
depends_on_min_os = cask.depends_on.macos&.minimum_version
|
||||||
odebug "Declared minimum OS version: #{cask_min_os&.to_sym}"
|
|
||||||
return if cask_min_os&.to_sym == min_os.to_sym
|
cask_min_os = [on_system_block_min_os, depends_on_min_os].compact.max
|
||||||
return if cask.on_system_blocks_exist? &&
|
debug_messages = []
|
||||||
OnSystem.arch_condition_met?(:arm) &&
|
debug_messages << "from on_system block: #{on_system_block_min_os.to_sym}" if on_system_block_min_os
|
||||||
|
if depends_on_min_os > HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
|
debug_messages << "from depends_on stanza: #{depends_on_min_os.to_sym}"
|
||||||
|
end
|
||||||
|
odebug "Declared minimum macOS: #{cask_min_os.to_sym} (#{debug_messages.join(" | ").presence || "default"})"
|
||||||
|
return if cask_min_os.to_sym == app_min_os.to_sym
|
||||||
|
# ignore declared minimum OS < 11.x when auditing as ARM a cask with arch-specific artifacts
|
||||||
|
return if OnSystem.arch_condition_met?(:arm) &&
|
||||||
|
cask.on_system_blocks_exist? &&
|
||||||
cask_min_os.present? &&
|
cask_min_os.present? &&
|
||||||
cask_min_os < MacOSVersion.new("11")
|
cask_min_os < MacOSVersion.new("11")
|
||||||
|
|
||||||
min_os_definition = if cask_min_os.present?
|
min_os_definition = if cask_min_os > HOMEBREW_MACOS_OLDEST_ALLOWED
|
||||||
if on_system_block_min_os.present? &&
|
definition = if T.must(on_system_block_min_os.to_s <=> depends_on_min_os.to_s).positive?
|
||||||
on_system_block_min_os > cask.depends_on.macos&.minimum_version
|
"an on_system block"
|
||||||
"a block with a minimum OS version of #{cask_min_os.to_sym.inspect}"
|
|
||||||
else
|
else
|
||||||
cask_min_os.to_sym.inspect
|
"a depends_on stanza"
|
||||||
end
|
end
|
||||||
|
"#{definition} with a minimum macOS version of #{cask_min_os.to_sym.inspect}"
|
||||||
else
|
else
|
||||||
"no minimum OS version"
|
"no minimum macOS version"
|
||||||
end
|
end
|
||||||
add_error "Upstream defined #{min_os.to_sym.inspect} as the minimum OS version " \
|
source = T.must(bundle_min_os.to_s <=> sparkle_min_os.to_s).positive? ? "Artifact" : "Upstream"
|
||||||
|
add_error "#{source} defined #{app_min_os.to_sym.inspect} as the minimum macOS version " \
|
||||||
"but the cask declared #{min_os_definition}",
|
"but the cask declared #{min_os_definition}",
|
||||||
strict_only: true
|
strict_only: true
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T.nilable(MacOSVersion)) }
|
sig { returns(T.nilable(MacOSVersion)) }
|
||||||
def livecheck_min_os
|
def cask_sparkle_min_os
|
||||||
return unless online?
|
return unless online?
|
||||||
return unless cask.livecheck_defined?
|
return unless cask.livecheck_defined?
|
||||||
return if cask.livecheck.strategy != :sparkle
|
return if cask.livecheck.strategy != :sparkle
|
||||||
@ -772,10 +781,10 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T.nilable(MacOSVersion)) }
|
sig { returns(T.nilable(MacOSVersion)) }
|
||||||
def cask_plist_min_os
|
def cask_bundle_min_os
|
||||||
return unless online?
|
return unless online?
|
||||||
|
|
||||||
plist_min_os = T.let(nil, T.untyped)
|
min_os = T.let(nil, T.untyped)
|
||||||
@staged_path ||= cask.staged_path
|
@staged_path ||= cask.staged_path
|
||||||
|
|
||||||
extract_artifacts do |artifacts, tmpdir|
|
extract_artifacts do |artifacts, tmpdir|
|
||||||
@ -786,13 +795,33 @@ module Cask
|
|||||||
next unless File.exist?(plist_path)
|
next unless File.exist?(plist_path)
|
||||||
|
|
||||||
plist = system_command!("plutil", args: ["-convert", "xml1", "-o", "-", plist_path]).plist
|
plist = system_command!("plutil", args: ["-convert", "xml1", "-o", "-", plist_path]).plist
|
||||||
plist_min_os = plist["LSMinimumSystemVersion"].presence
|
min_os = plist["LSMinimumSystemVersion"].presence
|
||||||
break if plist_min_os
|
break if min_os
|
||||||
|
|
||||||
|
next unless (main_binary = get_plist_main_binary(path))
|
||||||
|
next if !File.exist?(main_binary) || File.open(main_binary, "rb") { |f| f.read(2) == "#!" }
|
||||||
|
|
||||||
|
macho = MachO.open(main_binary)
|
||||||
|
min_os = case macho
|
||||||
|
when MachO::MachOFile
|
||||||
|
[
|
||||||
|
macho[:LC_VERSION_MIN_MACOSX].first&.version_string,
|
||||||
|
macho[:LC_BUILD_VERSION].first&.minos_string,
|
||||||
|
]
|
||||||
|
when MachO::FatFile
|
||||||
|
macho.machos.map do |slice|
|
||||||
|
[
|
||||||
|
slice[:LC_VERSION_MIN_MACOSX].first&.version_string,
|
||||||
|
slice[:LC_BUILD_VERSION].first&.minos_string,
|
||||||
|
]
|
||||||
|
end.flatten
|
||||||
|
end.compact.min
|
||||||
|
break if min_os
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
MacOSVersion.new(plist_min_os).strip_patch
|
MacOSVersion.new(min_os).strip_patch
|
||||||
rescue MacOSVersion::Error
|
rescue MacOSVersion::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -295,7 +295,7 @@ module Cask
|
|||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.anything])) }
|
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
||||||
attr_reader :from_json
|
attr_reader :from_json
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
@ -320,7 +320,7 @@ module Cask
|
|||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
token: String,
|
token: String,
|
||||||
from_json: T.nilable(T::Hash[T.any(String, Symbol), T.anything]),
|
from_json: T.nilable(T::Hash[String, T.untyped]),
|
||||||
path: T.nilable(Pathname),
|
path: T.nilable(Pathname),
|
||||||
).void
|
).void
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,6 @@ module Cask
|
|||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
DSL_METHODS = Set.new([
|
DSL_METHODS = Set.new([
|
||||||
:appcast,
|
|
||||||
:arch,
|
:arch,
|
||||||
:artifacts,
|
:artifacts,
|
||||||
:auto_updates,
|
:auto_updates,
|
||||||
@ -123,15 +122,21 @@ module Cask
|
|||||||
|
|
||||||
sig { params(cask: Cask).void }
|
sig { params(cask: Cask).void }
|
||||||
def initialize(cask)
|
def initialize(cask)
|
||||||
# NOTE: Variables set by `set_unique_stanza` must be initialized to `nil`.
|
# NOTE: `:"@#{stanza}"` variables set by `set_unique_stanza` must be
|
||||||
@auto_updates = T.let(nil, T.nilable(T::Boolean))
|
# initialized to `nil`.
|
||||||
@arch = T.let(nil, T.nilable(String))
|
@arch = T.let(nil, T.nilable(String))
|
||||||
|
@arch_set_in_block = T.let(false, T::Boolean)
|
||||||
@artifacts = T.let(ArtifactSet.new, ArtifactSet)
|
@artifacts = T.let(ArtifactSet.new, ArtifactSet)
|
||||||
|
@auto_updates = T.let(nil, T.nilable(T::Boolean))
|
||||||
|
@auto_updates_set_in_block = T.let(false, T::Boolean)
|
||||||
|
@autobump = T.let(true, T::Boolean)
|
||||||
@called_in_on_system_block = T.let(false, T::Boolean)
|
@called_in_on_system_block = T.let(false, T::Boolean)
|
||||||
@cask = T.let(cask, Cask)
|
@cask = T.let(cask, Cask)
|
||||||
@caveats = T.let(DSL::Caveats.new(cask), DSL::Caveats)
|
@caveats = T.let(DSL::Caveats.new(cask), DSL::Caveats)
|
||||||
@conflicts_with = T.let(nil, T.nilable(DSL::ConflictsWith))
|
@conflicts_with = T.let(nil, T.nilable(DSL::ConflictsWith))
|
||||||
|
@conflicts_with_set_in_block = T.let(false, T::Boolean)
|
||||||
@container = T.let(nil, T.nilable(DSL::Container))
|
@container = T.let(nil, T.nilable(DSL::Container))
|
||||||
|
@container_set_in_block = T.let(false, T::Boolean)
|
||||||
@depends_on = T.let(DSL::DependsOn.new, DSL::DependsOn)
|
@depends_on = T.let(DSL::DependsOn.new, DSL::DependsOn)
|
||||||
@depends_on_set_in_block = T.let(false, T::Boolean)
|
@depends_on_set_in_block = T.let(false, T::Boolean)
|
||||||
@deprecated = T.let(false, T::Boolean)
|
@deprecated = T.let(false, T::Boolean)
|
||||||
@ -140,27 +145,32 @@ module Cask
|
|||||||
@deprecation_replacement_cask = T.let(nil, T.nilable(String))
|
@deprecation_replacement_cask = T.let(nil, T.nilable(String))
|
||||||
@deprecation_replacement_formula = T.let(nil, T.nilable(String))
|
@deprecation_replacement_formula = T.let(nil, T.nilable(String))
|
||||||
@desc = T.let(nil, T.nilable(String))
|
@desc = T.let(nil, T.nilable(String))
|
||||||
|
@desc_set_in_block = T.let(false, T::Boolean)
|
||||||
@disable_date = T.let(nil, T.nilable(Date))
|
@disable_date = T.let(nil, T.nilable(Date))
|
||||||
@disable_reason = T.let(nil, T.nilable(T.any(String, Symbol)))
|
@disable_reason = T.let(nil, T.nilable(T.any(String, Symbol)))
|
||||||
@disable_replacement_cask = T.let(nil, T.nilable(String))
|
@disable_replacement_cask = T.let(nil, T.nilable(String))
|
||||||
@disable_replacement_formula = T.let(nil, T.nilable(String))
|
@disable_replacement_formula = T.let(nil, T.nilable(String))
|
||||||
@disabled = T.let(false, T::Boolean)
|
@disabled = T.let(false, T::Boolean)
|
||||||
@homepage = T.let(nil, T.nilable(String))
|
@homepage = T.let(nil, T.nilable(String))
|
||||||
|
@homepage_set_in_block = T.let(false, T::Boolean)
|
||||||
@language_blocks = T.let({}, T::Hash[T::Array[String], Proc])
|
@language_blocks = T.let({}, T::Hash[T::Array[String], Proc])
|
||||||
@language_eval = T.let(nil, T.nilable(String))
|
@language_eval = T.let(nil, T.nilable(String))
|
||||||
@livecheck = T.let(Livecheck.new(cask), Livecheck)
|
@livecheck = T.let(Livecheck.new(cask), Livecheck)
|
||||||
@livecheck_defined = T.let(false, T::Boolean)
|
@livecheck_defined = T.let(false, T::Boolean)
|
||||||
@name = T.let([], T::Array[String])
|
@name = T.let([], T::Array[String])
|
||||||
@autobump = T.let(true, T::Boolean)
|
|
||||||
@no_autobump_defined = T.let(false, T::Boolean)
|
@no_autobump_defined = T.let(false, T::Boolean)
|
||||||
@on_system_blocks_exist = T.let(false, T::Boolean)
|
@on_system_blocks_exist = T.let(false, T::Boolean)
|
||||||
@os = T.let(nil, T.nilable(String))
|
|
||||||
@on_system_block_min_os = T.let(nil, T.nilable(MacOSVersion))
|
@on_system_block_min_os = T.let(nil, T.nilable(MacOSVersion))
|
||||||
|
@os = T.let(nil, T.nilable(String))
|
||||||
|
@os_set_in_block = T.let(false, T::Boolean)
|
||||||
@sha256 = T.let(nil, T.nilable(T.any(Checksum, Symbol)))
|
@sha256 = T.let(nil, T.nilable(T.any(Checksum, Symbol)))
|
||||||
|
@sha256_set_in_block = T.let(false, T::Boolean)
|
||||||
@staged_path = T.let(nil, T.nilable(Pathname))
|
@staged_path = T.let(nil, T.nilable(Pathname))
|
||||||
@token = T.let(cask.token, String)
|
@token = T.let(cask.token, String)
|
||||||
@url = T.let(nil, T.nilable(URL))
|
@url = T.let(nil, T.nilable(URL))
|
||||||
|
@url_set_in_block = T.let(false, T::Boolean)
|
||||||
@version = T.let(nil, T.nilable(DSL::Version))
|
@version = T.let(nil, T.nilable(DSL::Version))
|
||||||
|
@version_set_in_block = T.let(false, T::Boolean)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
@ -216,7 +226,7 @@ module Cask
|
|||||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
|
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
|
||||||
end
|
end
|
||||||
|
|
||||||
if instance_variable_defined?(:"@#{stanza}_set_in_block") && @called_in_on_system_block
|
if instance_variable_get(:"@#{stanza}_set_in_block") && @called_in_on_system_block
|
||||||
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only be overridden once.")
|
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only be overridden once.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -476,7 +486,7 @@ module Cask
|
|||||||
def add_implicit_macos_dependency
|
def add_implicit_macos_dependency
|
||||||
return if (cask_depends_on = @depends_on).present? && cask_depends_on.macos.present?
|
return if (cask_depends_on = @depends_on).present? && cask_depends_on.macos.present?
|
||||||
|
|
||||||
depends_on macos: ">= :#{MacOSVersion::SYMBOLS.key MacOSVersion::SYMBOLS.values.min}"
|
depends_on macos: ">= #{MacOSVersion.new(HOMEBREW_MACOS_OLDEST_ALLOWED).to_sym.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Declare conflicts that keep a cask from installing or working correctly.
|
# Declare conflicts that keep a cask from installing or working correctly.
|
||||||
|
@ -52,16 +52,17 @@ module Cask
|
|||||||
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
||||||
|
|
||||||
# workaround for https://github.com/sorbet/sorbet/issues/6860
|
# workaround for https://github.com/sorbet/sorbet/issues/6860
|
||||||
first_arg = args.first&.to_s
|
first_arg = args.first
|
||||||
|
first_arg_s = first_arg&.to_s
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@macos = if args.count > 1
|
@macos = if args.count > 1
|
||||||
MacOSRequirement.new([args], comparator: "==")
|
MacOSRequirement.new([args], comparator: "==")
|
||||||
elsif MacOSVersion::SYMBOLS.key?(args.first)
|
elsif first_arg.is_a?(Symbol) && MacOSVersion::SYMBOLS.key?(first_arg)
|
||||||
MacOSRequirement.new([args.first], comparator: "==")
|
MacOSRequirement.new([args.first], comparator: "==")
|
||||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg))
|
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg_s))
|
||||||
MacOSRequirement.new([T.must(md[:version]).to_sym], comparator: md[:comparator])
|
MacOSRequirement.new([T.must(md[:version]).to_sym], comparator: md[:comparator])
|
||||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg))
|
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg_s))
|
||||||
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
||||||
# This is not duplicate of the first case: see `args.first` and a different comparator.
|
# This is not duplicate of the first case: see `args.first` and a different comparator.
|
||||||
else # rubocop:disable Lint/DuplicateBranch
|
else # rubocop:disable Lint/DuplicateBranch
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
require "formula_installer"
|
require "formula_installer"
|
||||||
require "unpack_strategy"
|
require "unpack_strategy"
|
||||||
require "utils/topological_hash"
|
require "utils/topological_hash"
|
||||||
|
require "utils/analytics"
|
||||||
|
|
||||||
require "cask/config"
|
require "cask/config"
|
||||||
require "cask/download"
|
require "cask/download"
|
||||||
@ -303,6 +304,20 @@ on_request: true)
|
|||||||
|
|
||||||
next if artifact.is_a?(Artifact::Binary) && !binaries?
|
next if artifact.is_a?(Artifact::Binary) && !binaries?
|
||||||
|
|
||||||
|
artifact = T.cast(
|
||||||
|
artifact,
|
||||||
|
T.any(
|
||||||
|
Artifact::AbstractFlightBlock,
|
||||||
|
Artifact::Installer,
|
||||||
|
Artifact::KeyboardLayout,
|
||||||
|
Artifact::Mdimporter,
|
||||||
|
Artifact::Moved,
|
||||||
|
Artifact::Pkg,
|
||||||
|
Artifact::Qlplugin,
|
||||||
|
Artifact::Symlinked,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
artifact.install_phase(
|
artifact.install_phase(
|
||||||
command: @command, verbose: verbose?, adopt: adopt?, auto_updates: @cask.auto_updates,
|
command: @command, verbose: verbose?, adopt: adopt?, auto_updates: @cask.auto_updates,
|
||||||
force: force?, predecessor:
|
force: force?, predecessor:
|
||||||
@ -548,6 +563,18 @@ on_request: true)
|
|||||||
|
|
||||||
artifacts.each do |artifact|
|
artifacts.each do |artifact|
|
||||||
if artifact.respond_to?(:uninstall_phase)
|
if artifact.respond_to?(:uninstall_phase)
|
||||||
|
artifact = T.cast(
|
||||||
|
artifact,
|
||||||
|
T.any(
|
||||||
|
Artifact::AbstractFlightBlock,
|
||||||
|
Artifact::KeyboardLayout,
|
||||||
|
Artifact::Moved,
|
||||||
|
Artifact::Qlplugin,
|
||||||
|
Artifact::Symlinked,
|
||||||
|
Artifact::Uninstall,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
odebug "Uninstalling artifact of class #{artifact.class}"
|
odebug "Uninstalling artifact of class #{artifact.class}"
|
||||||
artifact.uninstall_phase(
|
artifact.uninstall_phase(
|
||||||
command: @command,
|
command: @command,
|
||||||
@ -562,6 +589,8 @@ on_request: true)
|
|||||||
|
|
||||||
next unless artifact.respond_to?(:post_uninstall_phase)
|
next unless artifact.respond_to?(:post_uninstall_phase)
|
||||||
|
|
||||||
|
artifact = T.cast(artifact, Artifact::Uninstall)
|
||||||
|
|
||||||
odebug "Post-uninstalling artifact of class #{artifact.class}"
|
odebug "Post-uninstalling artifact of class #{artifact.class}"
|
||||||
artifact.post_uninstall_phase(
|
artifact.post_uninstall_phase(
|
||||||
command: @command,
|
command: @command,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -6,6 +6,7 @@ require "formula"
|
|||||||
require "fetch"
|
require "fetch"
|
||||||
require "cask/download"
|
require "cask/download"
|
||||||
require "retryable_download"
|
require "retryable_download"
|
||||||
|
require "download_queue"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module Cmd
|
module Cmd
|
||||||
@ -69,15 +70,16 @@ module Homebrew
|
|||||||
named_args [:formula, :cask], min: 1
|
named_args [:formula, :cask], min: 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Integer) }
|
||||||
def concurrency
|
def concurrency
|
||||||
@concurrency ||= args.concurrency&.to_i || 1
|
@concurrency ||= T.let(args.concurrency&.to_i || 1, T.nilable(Integer))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(DownloadQueue) }
|
||||||
def download_queue
|
def download_queue
|
||||||
@download_queue ||= begin
|
@download_queue ||= T.let(begin
|
||||||
require "download_queue"
|
|
||||||
DownloadQueue.new(concurrency)
|
DownloadQueue.new(concurrency)
|
||||||
end
|
end, T.nilable(DownloadQueue))
|
||||||
end
|
end
|
||||||
|
|
||||||
class Spinner
|
class Spinner
|
||||||
@ -96,8 +98,8 @@ module Homebrew
|
|||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def initialize
|
def initialize
|
||||||
@start = Time.now
|
@start = T.let(Time.now, Time)
|
||||||
@i = 0
|
@i = T.let(0, Integer)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
@ -136,7 +138,7 @@ module Homebrew
|
|||||||
bucket.each do |formula_or_cask|
|
bucket.each do |formula_or_cask|
|
||||||
case formula_or_cask
|
case formula_or_cask
|
||||||
when Formula
|
when Formula
|
||||||
formula = T.cast(formula_or_cask, Formula)
|
formula = formula_or_cask
|
||||||
ref = formula.loaded_from_api? ? formula.full_name : formula.path
|
ref = formula.loaded_from_api? ? formula.full_name : formula.path
|
||||||
|
|
||||||
os_arch_combinations.each do |os, arch|
|
os_arch_combinations.each do |os, arch|
|
||||||
@ -189,7 +191,9 @@ module Homebrew
|
|||||||
|
|
||||||
next if fetched_bottle
|
next if fetched_bottle
|
||||||
|
|
||||||
fetch_downloadable(formula.resource)
|
if (resource = formula.resource)
|
||||||
|
fetch_downloadable(resource)
|
||||||
|
end
|
||||||
|
|
||||||
formula.resources.each do |r|
|
formula.resources.each do |r|
|
||||||
fetch_downloadable(r)
|
fetch_downloadable(r)
|
||||||
@ -231,7 +235,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
spinner = Spinner.new
|
spinner = Spinner.new
|
||||||
remaining_downloads = downloads.dup
|
remaining_downloads = downloads.dup.to_a
|
||||||
previous_pending_line_count = 0
|
previous_pending_line_count = 0
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -332,10 +336,13 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { returns(T::Hash[T.any(Resource, Bottle, Cask::Download), Concurrent::Promises::Future]) }
|
||||||
def downloads
|
def downloads
|
||||||
@downloads ||= {}
|
@downloads ||= T.let({}, T.nilable(T::Hash[T.any(Resource, Bottle, Cask::Download),
|
||||||
|
Concurrent::Promises::Future]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(downloadable: T.any(Resource, Bottle, Cask::Download)).void }
|
||||||
def fetch_downloadable(downloadable)
|
def fetch_downloadable(downloadable)
|
||||||
downloads[downloadable] ||= begin
|
downloads[downloadable] ||= begin
|
||||||
tries = args.retry? ? {} : { tries: 1 }
|
tries = args.retry? ? {} : { tries: 1 }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -18,7 +18,7 @@ module Homebrew
|
|||||||
class Info < AbstractCommand
|
class Info < AbstractCommand
|
||||||
VALID_DAYS = %w[30 90 365].freeze
|
VALID_DAYS = %w[30 90 365].freeze
|
||||||
VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze
|
VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze
|
||||||
VALID_CATEGORIES = (VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze
|
VALID_CATEGORIES = T.let((VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze, T::Array[String])
|
||||||
|
|
||||||
cmd_args do
|
cmd_args do
|
||||||
description <<~EOS
|
description <<~EOS
|
||||||
@ -96,14 +96,17 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
print_analytics
|
print_analytics
|
||||||
elsif args.json
|
elsif (json = args.json)
|
||||||
all = args.eval_all?
|
all = args.eval_all?
|
||||||
|
|
||||||
print_json(all)
|
print_json(json, all)
|
||||||
elsif args.github?
|
elsif args.github?
|
||||||
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
||||||
|
|
||||||
exec_browser(*args.named.to_formulae_and_casks.map { |f| github_info(f) })
|
exec_browser(*args.named.to_formulae_and_casks.map do |formula_keg_or_cask|
|
||||||
|
formula_or_cask = T.cast(formula_keg_or_cask, T.any(Formula, Cask::Cask))
|
||||||
|
github_info(formula_or_cask)
|
||||||
|
end)
|
||||||
elsif args.no_named?
|
elsif args.no_named?
|
||||||
print_statistics
|
print_statistics
|
||||||
else
|
else
|
||||||
@ -111,6 +114,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(remote: String, path: String).returns(String) }
|
||||||
def github_remote_path(remote, path)
|
def github_remote_path(remote, path)
|
||||||
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
|
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
|
||||||
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
|
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
|
||||||
@ -175,6 +179,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(version: T.any(T::Boolean, String)).returns(Symbol) }
|
||||||
def json_version(version)
|
def json_version(version)
|
||||||
version_hash = {
|
version_hash = {
|
||||||
true => :default,
|
true => :default,
|
||||||
@ -187,11 +192,11 @@ module Homebrew
|
|||||||
version_hash[version]
|
version_hash[version]
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(all: T::Boolean).void }
|
sig { params(json: T.any(T::Boolean, String), all: T::Boolean).void }
|
||||||
def print_json(all)
|
def print_json(json, all)
|
||||||
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?
|
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?
|
||||||
|
|
||||||
json = case json_version(args.json)
|
json = case json_version(json)
|
||||||
when :v1, :default
|
when :v1, :default
|
||||||
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?
|
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?
|
||||||
|
|
||||||
@ -240,25 +245,31 @@ module Homebrew
|
|||||||
puts JSON.pretty_generate(json)
|
puts JSON.pretty_generate(json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(String) }
|
||||||
def github_info(formula_or_cask)
|
def github_info(formula_or_cask)
|
||||||
return formula_or_cask.path if formula_or_cask.tap.blank? || formula_or_cask.tap.remote.blank?
|
|
||||||
|
|
||||||
path = case formula_or_cask
|
path = case formula_or_cask
|
||||||
when Formula
|
when Formula
|
||||||
formula = formula_or_cask
|
formula = formula_or_cask
|
||||||
formula.path.relative_path_from(T.must(formula.tap).path)
|
tap = formula.tap
|
||||||
|
return formula.path.to_s if tap.blank? || tap.remote.blank?
|
||||||
|
|
||||||
|
formula.path.relative_path_from(tap.path)
|
||||||
when Cask::Cask
|
when Cask::Cask
|
||||||
cask = formula_or_cask
|
cask = formula_or_cask
|
||||||
|
tap = cask.tap
|
||||||
|
return cask.sourcefile_path.to_s if tap.blank? || tap.remote.blank?
|
||||||
|
|
||||||
if cask.sourcefile_path.blank? || cask.sourcefile_path.extname != ".rb"
|
if cask.sourcefile_path.blank? || cask.sourcefile_path.extname != ".rb"
|
||||||
return "#{cask.tap.default_remote}/blob/HEAD/#{cask.tap.relative_cask_path(cask.token)}"
|
return "#{tap.default_remote}/blob/HEAD/#{tap.relative_cask_path(cask.token)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
cask.sourcefile_path.relative_path_from(cask.tap.path)
|
cask.sourcefile_path.relative_path_from(tap.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
github_remote_path(formula_or_cask.tap.remote, path)
|
github_remote_path(tap.remote, path.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: Formula).void }
|
||||||
def info_formula(formula)
|
def info_formula(formula)
|
||||||
specs = []
|
specs = []
|
||||||
|
|
||||||
@ -356,6 +367,7 @@ module Homebrew
|
|||||||
Utils::Analytics.formula_output(formula, args:)
|
Utils::Analytics.formula_output(formula, args:)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(dependencies: T::Array[Dependency]).returns(String) }
|
||||||
def decorate_dependencies(dependencies)
|
def decorate_dependencies(dependencies)
|
||||||
deps_status = dependencies.map do |dep|
|
deps_status = dependencies.map do |dep|
|
||||||
if dep.satisfied?([])
|
if dep.satisfied?([])
|
||||||
@ -367,6 +379,7 @@ module Homebrew
|
|||||||
deps_status.join(", ")
|
deps_status.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(requirements: T::Array[Requirement]).returns(String) }
|
||||||
def decorate_requirements(requirements)
|
def decorate_requirements(requirements)
|
||||||
req_status = requirements.map do |req|
|
req_status = requirements.map do |req|
|
||||||
req_s = req.display_s
|
req_s = req.display_s
|
||||||
@ -375,12 +388,14 @@ module Homebrew
|
|||||||
req_status.join(", ")
|
req_status.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(dep: Dependency).returns(String) }
|
||||||
def dep_display_s(dep)
|
def dep_display_s(dep)
|
||||||
return dep.name if dep.option_tags.empty?
|
return dep.name if dep.option_tags.empty?
|
||||||
|
|
||||||
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
|
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: Cask::Cask).void }
|
||||||
def info_cask(cask)
|
def info_cask(cask)
|
||||||
require "cask/info"
|
require "cask/info"
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ module Homebrew
|
|||||||
puts info
|
puts info
|
||||||
else
|
else
|
||||||
info = ""
|
info = ""
|
||||||
|
default_branches = %w[main master].freeze
|
||||||
|
|
||||||
taps.each_with_index do |tap, i|
|
taps.each_with_index do |tap, i|
|
||||||
puts unless i.zero?
|
puts unless i.zero?
|
||||||
info = "#{tap}: "
|
info = "#{tap}: "
|
||||||
@ -79,7 +81,7 @@ module Homebrew
|
|||||||
info += "\norigin: #{tap.remote}" if tap.remote != tap.default_remote
|
info += "\norigin: #{tap.remote}" if tap.remote != tap.default_remote
|
||||||
info += "\nHEAD: #{tap.git_head || "(none)"}"
|
info += "\nHEAD: #{tap.git_head || "(none)"}"
|
||||||
info += "\nlast commit: #{tap.git_last_commit || "never"}"
|
info += "\nlast commit: #{tap.git_last_commit || "never"}"
|
||||||
info += "\nbranch: #{tap.git_branch || "(none)"}" if tap.git_branch != "master"
|
info += "\nbranch: #{tap.git_branch || "(none)"}" if default_branches.exclude?(tap.git_branch)
|
||||||
else
|
else
|
||||||
info += "Not installed"
|
info += "Not installed"
|
||||||
end
|
end
|
||||||
|
@ -33,8 +33,6 @@ module Homebrew
|
|||||||
"integration.",
|
"integration.",
|
||||||
replacement: false,
|
replacement: false,
|
||||||
disable: true
|
disable: true
|
||||||
switch "--[no-]force-auto-update",
|
|
||||||
hidden: true
|
|
||||||
switch "--custom-remote",
|
switch "--custom-remote",
|
||||||
description: "Install or change a tap with a custom remote. Useful for mirrors."
|
description: "Install or change a tap with a custom remote. Useful for mirrors."
|
||||||
switch "--repair",
|
switch "--repair",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -39,13 +39,15 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def auto_update_header
|
def auto_update_header
|
||||||
@auto_update_header ||= begin
|
@auto_update_header ||= T.let(begin
|
||||||
ohai "Auto-updated Homebrew!" if args.auto_update?
|
ohai "Auto-updated Homebrew!" if args.auto_update?
|
||||||
true
|
true
|
||||||
end
|
end, T.nilable(T::Boolean))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def output_update_report
|
def output_update_report
|
||||||
# Run `brew update` (again) if we've got a linuxbrew-core CoreTap
|
# Run `brew update` (again) if we've got a linuxbrew-core CoreTap
|
||||||
if CoreTap.instance.installed? && CoreTap.instance.linuxbrew_core? &&
|
if CoreTap.instance.installed? && CoreTap.instance.linuxbrew_core? &&
|
||||||
@ -293,14 +295,17 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def no_changes_message
|
def no_changes_message
|
||||||
"No changes to formulae or casks."
|
"No changes to formulae or casks."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(revision: String).returns(String) }
|
||||||
def shorten_revision(revision)
|
def shorten_revision(revision)
|
||||||
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def tap_or_untap_core_taps_if_necessary
|
def tap_or_untap_core_taps_if_necessary
|
||||||
return if ENV["HOMEBREW_UPDATE_TEST"]
|
return if ENV["HOMEBREW_UPDATE_TEST"]
|
||||||
|
|
||||||
@ -320,10 +325,11 @@ module Homebrew
|
|||||||
return if (HOMEBREW_PREFIX/".homebrewdocker").exist?
|
return if (HOMEBREW_PREFIX/".homebrewdocker").exist?
|
||||||
|
|
||||||
tap_output_header_printed = T.let(false, T::Boolean)
|
tap_output_header_printed = T.let(false, T::Boolean)
|
||||||
|
default_branches = %w[main master].freeze
|
||||||
[CoreTap.instance, CoreCaskTap.instance].each do |tap|
|
[CoreTap.instance, CoreCaskTap.instance].each do |tap|
|
||||||
next unless tap.installed?
|
next unless tap.installed?
|
||||||
|
|
||||||
if tap.git_branch == "master" &&
|
if default_branches.include?(tap.git_branch) &&
|
||||||
(Date.parse(T.must(tap.git_repository.last_commit_date)) <= Date.today.prev_month)
|
(Date.parse(T.must(tap.git_repository.last_commit_date)) <= Date.today.prev_month)
|
||||||
ohai "#{tap.name} is old and unneeded, untapping to save space..."
|
ohai "#{tap.name} is old and unneeded, untapping to save space..."
|
||||||
tap.uninstall
|
tap.uninstall
|
||||||
@ -339,6 +345,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(repository: Pathname).void }
|
||||||
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
|
def link_completions_manpages_and_docs(repository = HOMEBREW_REPOSITORY)
|
||||||
command = "brew update"
|
command = "brew update"
|
||||||
Utils::Link.link_completions(repository, command)
|
Utils::Link.link_completions(repository, command)
|
||||||
@ -351,10 +358,12 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_gcc_dependents_if_needed
|
def migrate_gcc_dependents_if_needed
|
||||||
# do nothing
|
# do nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def analytics_message
|
def analytics_message
|
||||||
return if Utils::Analytics.messages_displayed?
|
return if Utils::Analytics.messages_displayed?
|
||||||
return if Utils::Analytics.no_message_output?
|
return if Utils::Analytics.no_message_output?
|
||||||
@ -384,6 +393,7 @@ module Homebrew
|
|||||||
Utils::Analytics.messages_displayed! if $stdout.tty?
|
Utils::Analytics.messages_displayed! if $stdout.tty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def donation_message
|
def donation_message
|
||||||
return if Settings.read("donationmessage") == "true"
|
return if Settings.read("donationmessage") == "true"
|
||||||
|
|
||||||
@ -394,6 +404,7 @@ module Homebrew
|
|||||||
Settings.write "donationmessage", true if $stdout.tty?
|
Settings.write "donationmessage", true if $stdout.tty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def install_from_api_message
|
def install_from_api_message
|
||||||
return if Settings.read("installfromapimessage") == "true"
|
return if Settings.read("installfromapimessage") == "true"
|
||||||
|
|
||||||
@ -418,30 +429,38 @@ require "extend/os/cmd/update-report"
|
|||||||
|
|
||||||
class Reporter
|
class Reporter
|
||||||
class ReporterRevisionUnsetError < RuntimeError
|
class ReporterRevisionUnsetError < RuntimeError
|
||||||
|
sig { params(var_name: String).void }
|
||||||
def initialize(var_name)
|
def initialize(var_name)
|
||||||
super "#{var_name} is unset!"
|
super "#{var_name} is unset!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(tap: Tap, api_names_txt: T.nilable(Pathname), api_names_before_txt: T.nilable(Pathname),
|
||||||
|
api_dir_prefix: T.nilable(Pathname)).void
|
||||||
|
}
|
||||||
def initialize(tap, api_names_txt: nil, api_names_before_txt: nil, api_dir_prefix: nil)
|
def initialize(tap, api_names_txt: nil, api_names_before_txt: nil, api_dir_prefix: nil)
|
||||||
@tap = tap
|
@tap = tap
|
||||||
|
|
||||||
# This is slightly involved/weird but all the #report logic is shared so it's worth it.
|
# This is slightly involved/weird but all the #report logic is shared so it's worth it.
|
||||||
if installed_from_api?(api_names_txt, api_names_before_txt, api_dir_prefix)
|
if installed_from_api?(api_names_txt, api_names_before_txt, api_dir_prefix)
|
||||||
@api_names_txt = api_names_txt
|
@api_names_txt = T.let(api_names_txt, T.nilable(Pathname))
|
||||||
@api_names_before_txt = api_names_before_txt
|
@api_names_before_txt = T.let(api_names_before_txt, T.nilable(Pathname))
|
||||||
@api_dir_prefix = api_dir_prefix
|
@api_dir_prefix = T.let(api_dir_prefix, T.nilable(Pathname))
|
||||||
else
|
else
|
||||||
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repository_var_suffix}"
|
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{tap.repository_var_suffix}"
|
||||||
@initial_revision = ENV[initial_revision_var].to_s
|
@initial_revision = T.let(ENV[initial_revision_var].to_s, String)
|
||||||
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
|
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
|
||||||
|
|
||||||
current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repository_var_suffix}"
|
current_revision_var = "HOMEBREW_UPDATE_AFTER#{tap.repository_var_suffix}"
|
||||||
@current_revision = ENV[current_revision_var].to_s
|
@current_revision = T.let(ENV[current_revision_var].to_s, String)
|
||||||
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@report = T.let(nil, T.nilable(T::Hash[Symbol, T::Array[String]]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(auto_update: T::Boolean).returns(T::Hash[Symbol, T::Array[String]]) }
|
||||||
def report(auto_update: false)
|
def report(auto_update: false)
|
||||||
return @report if @report
|
return @report if @report
|
||||||
|
|
||||||
@ -482,9 +501,9 @@ class Reporter
|
|||||||
case status
|
case status
|
||||||
when "A", "D"
|
when "A", "D"
|
||||||
full_name = tap.formula_file_to_name(src)
|
full_name = tap.formula_file_to_name(src)
|
||||||
name = full_name.split("/").last
|
name = T.must(full_name.split("/").last)
|
||||||
new_tap = tap.tap_migrations[name]
|
new_tap = tap.tap_migrations[name]
|
||||||
@report[status.to_sym] << full_name unless new_tap
|
@report[T.must(status).to_sym] << full_name unless new_tap
|
||||||
when "M"
|
when "M"
|
||||||
name = tap.formula_file_to_name(src)
|
name = tap.formula_file_to_name(src)
|
||||||
|
|
||||||
@ -584,6 +603,7 @@ class Reporter
|
|||||||
@report
|
@report
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def updated?
|
def updated?
|
||||||
if installed_from_api?
|
if installed_from_api?
|
||||||
diff.present?
|
diff.present?
|
||||||
@ -592,9 +612,10 @@ class Reporter
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_tap_migration
|
def migrate_tap_migration
|
||||||
(report[:D] + report[:DC]).each do |full_name|
|
(Array(report[:D]) + Array(report[:DC])).each do |full_name|
|
||||||
name = full_name.split("/").last
|
name = T.must(full_name.split("/").last)
|
||||||
new_tap_name = tap.tap_migrations[name]
|
new_tap_name = tap.tap_migrations[name]
|
||||||
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
||||||
|
|
||||||
@ -609,7 +630,7 @@ class Reporter
|
|||||||
end
|
end
|
||||||
|
|
||||||
# This means it is a cask
|
# This means it is a cask
|
||||||
if report[:DC].include? full_name
|
if Array(report[:DC]).include? full_name
|
||||||
next unless (HOMEBREW_PREFIX/"Caskroom"/new_name).exist?
|
next unless (HOMEBREW_PREFIX/"Caskroom"/new_name).exist?
|
||||||
|
|
||||||
new_tap = Tap.fetch(new_tap_name)
|
new_tap = Tap.fetch(new_tap_name)
|
||||||
@ -675,12 +696,14 @@ class Reporter
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def migrate_cask_rename
|
def migrate_cask_rename
|
||||||
Cask::Caskroom.casks.each do |cask|
|
Cask::Caskroom.casks.each do |cask|
|
||||||
Cask::Migrator.migrate_if_needed(cask)
|
Cask::Migrator.migrate_if_needed(cask)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(force: T::Boolean, verbose: T::Boolean).void }
|
||||||
def migrate_formula_rename(force:, verbose:)
|
def migrate_formula_rename(force:, verbose:)
|
||||||
Formula.installed.each do |formula|
|
Formula.installed.each do |formula|
|
||||||
next unless Migrator.needs_migration?(formula)
|
next unless Migrator.needs_migration?(formula)
|
||||||
@ -704,14 +727,36 @@ class Reporter
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :tap, :initial_revision, :current_revision, :api_names_txt, :api_names_before_txt, :api_dir_prefix
|
sig { returns(Tap) }
|
||||||
|
attr_reader :tap
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
attr_reader :initial_revision
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
attr_reader :current_revision
|
||||||
|
|
||||||
|
sig { returns(T.nilable(Pathname)) }
|
||||||
|
attr_reader :api_names_txt
|
||||||
|
|
||||||
|
sig { returns(T.nilable(Pathname)) }
|
||||||
|
attr_reader :api_names_before_txt
|
||||||
|
|
||||||
|
sig { returns(T.nilable(Pathname)) }
|
||||||
|
attr_reader :api_dir_prefix
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(api_names_txt: T.nilable(Pathname), api_names_before_txt: T.nilable(Pathname),
|
||||||
|
api_dir_prefix: T.nilable(Pathname)).returns(T::Boolean)
|
||||||
|
}
|
||||||
def installed_from_api?(api_names_txt = @api_names_txt, api_names_before_txt = @api_names_before_txt,
|
def installed_from_api?(api_names_txt = @api_names_txt, api_names_before_txt = @api_names_before_txt,
|
||||||
api_dir_prefix = @api_dir_prefix)
|
api_dir_prefix = @api_dir_prefix)
|
||||||
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
|
!api_names_txt.nil? && !api_names_before_txt.nil? && !api_dir_prefix.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def diff
|
def diff
|
||||||
|
@diff ||= T.let(nil, T.nilable(String))
|
||||||
@diff ||= if installed_from_api?
|
@diff ||= if installed_from_api?
|
||||||
# Hack `git diff` output with regexes to look like `git diff-tree` output.
|
# Hack `git diff` output with regexes to look like `git diff-tree` output.
|
||||||
# Yes, I know this is a bit filthy but it saves duplicating the #report logic.
|
# Yes, I know this is a bit filthy but it saves duplicating the #report logic.
|
||||||
@ -719,12 +764,14 @@ class Reporter
|
|||||||
header_regex = /^(---|\+\+\+) /
|
header_regex = /^(---|\+\+\+) /
|
||||||
add_delete_characters = ["+", "-"].freeze
|
add_delete_characters = ["+", "-"].freeze
|
||||||
|
|
||||||
|
api_dir_prefix_basename = T.must(api_dir_prefix).basename
|
||||||
|
|
||||||
diff_output.lines.filter_map do |line|
|
diff_output.lines.filter_map do |line|
|
||||||
next if line.match?(header_regex)
|
next if line.match?(header_regex)
|
||||||
next unless add_delete_characters.include?(line[0])
|
next unless add_delete_characters.include?(line[0])
|
||||||
|
|
||||||
line.sub(/^\+/, "A #{api_dir_prefix.basename}/")
|
line.sub(/^\+/, "A #{api_dir_prefix_basename}/")
|
||||||
.sub(/^-/, "D #{api_dir_prefix.basename}/")
|
.sub(/^-/, "D #{api_dir_prefix_basename}/")
|
||||||
.sub(/$/, ".rb")
|
.sub(/$/, ".rb")
|
||||||
.chomp
|
.chomp
|
||||||
end.join("\n")
|
end.join("\n")
|
||||||
@ -738,28 +785,33 @@ class Reporter
|
|||||||
end
|
end
|
||||||
|
|
||||||
class ReporterHub
|
class ReporterHub
|
||||||
|
sig { returns(T::Array[Reporter]) }
|
||||||
attr_reader :reporters
|
attr_reader :reporters
|
||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def initialize
|
def initialize
|
||||||
@hash = {}
|
@hash = T.let({}, T::Hash[Symbol, T::Array[String]])
|
||||||
@reporters = []
|
@reporters = T.let([], T::Array[Reporter])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(key: Symbol).returns(T::Array[String]) }
|
||||||
def select_formula_or_cask(key)
|
def select_formula_or_cask(key)
|
||||||
@hash.fetch(key, [])
|
@hash.fetch(key, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(reporter: Reporter, auto_update: T::Boolean).void }
|
||||||
def add(reporter, auto_update: false)
|
def add(reporter, auto_update: false)
|
||||||
@reporters << reporter
|
@reporters << reporter
|
||||||
report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? }
|
report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? }
|
||||||
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def empty?
|
def empty?
|
||||||
@hash.empty?
|
@hash.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(auto_update: T::Boolean).void }
|
||||||
def dump(auto_update: false)
|
def dump(auto_update: false)
|
||||||
unless Homebrew::EnvConfig.no_update_report_new?
|
unless Homebrew::EnvConfig.no_update_report_new?
|
||||||
dump_new_formula_report
|
dump_new_formula_report
|
||||||
@ -814,12 +866,14 @@ class ReporterHub
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_new_formula_report
|
def dump_new_formula_report
|
||||||
formulae = select_formula_or_cask(:A).sort.reject { |name| installed?(name) }
|
formulae = select_formula_or_cask(:A).sort.reject { |name| installed?(name) }
|
||||||
|
|
||||||
output_dump_formula_or_cask_report "New Formulae", formulae
|
output_dump_formula_or_cask_report "New Formulae", formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_new_cask_report
|
def dump_new_cask_report
|
||||||
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||||
|
|
||||||
@ -830,6 +884,7 @@ class ReporterHub
|
|||||||
output_dump_formula_or_cask_report "New Casks", casks
|
output_dump_formula_or_cask_report "New Casks", casks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_deleted_formula_report
|
def dump_deleted_formula_report
|
||||||
formulae = select_formula_or_cask(:D).sort.filter_map do |name|
|
formulae = select_formula_or_cask(:D).sort.filter_map do |name|
|
||||||
pretty_uninstalled(name) if installed?(name)
|
pretty_uninstalled(name) if installed?(name)
|
||||||
@ -838,37 +893,43 @@ class ReporterHub
|
|||||||
output_dump_formula_or_cask_report "Deleted Installed Formulae", formulae
|
output_dump_formula_or_cask_report "Deleted Installed Formulae", formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
def dump_deleted_cask_report
|
def dump_deleted_cask_report
|
||||||
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
return if Homebrew::SimulateSystem.simulating_or_running_on_linux?
|
||||||
|
|
||||||
casks = select_formula_or_cask(:DC).sort.filter_map do |name|
|
casks = select_formula_or_cask(:DC).sort.filter_map do |name|
|
||||||
name = name.split("/").last
|
name = T.must(name.split("/").last)
|
||||||
pretty_uninstalled(name) if cask_installed?(name)
|
pretty_uninstalled(name) if cask_installed?(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
output_dump_formula_or_cask_report "Deleted Installed Casks", casks
|
output_dump_formula_or_cask_report "Deleted Installed Casks", casks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(title: String, formulae_or_casks: T::Array[String]).void }
|
||||||
def output_dump_formula_or_cask_report(title, formulae_or_casks)
|
def output_dump_formula_or_cask_report(title, formulae_or_casks)
|
||||||
return if formulae_or_casks.blank?
|
return if formulae_or_casks.blank?
|
||||||
|
|
||||||
ohai title, Formatter.columns(formulae_or_casks.sort)
|
ohai title, Formatter.columns(formulae_or_casks.sort)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: String).returns(T::Boolean) }
|
||||||
def installed?(formula)
|
def installed?(formula)
|
||||||
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(formula: String).returns(T::Boolean) }
|
||||||
def outdated?(formula)
|
def outdated?(formula)
|
||||||
Formula[formula].outdated?
|
Formula[formula].outdated?
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: String).returns(T::Boolean) }
|
||||||
def cask_installed?(cask)
|
def cask_installed?(cask)
|
||||||
(Cask::Caskroom.path/cask).directory?
|
(Cask::Caskroom.path/cask).directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(cask: String).returns(T::Boolean) }
|
||||||
def cask_outdated?(cask)
|
def cask_outdated?(cask)
|
||||||
Cask::CaskLoader.load(cask).outdated?
|
Cask::CaskLoader.load(cask).outdated?
|
||||||
rescue Cask::CaskError
|
rescue Cask::CaskError
|
||||||
|
@ -54,9 +54,10 @@ git_init_if_necessary() {
|
|||||||
fi
|
fi
|
||||||
git config remote.origin.url "${HOMEBREW_BREW_GIT_REMOTE}"
|
git config remote.origin.url "${HOMEBREW_BREW_GIT_REMOTE}"
|
||||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||||
|
git config fetch.prune true
|
||||||
git fetch --force --tags origin
|
git fetch --force --tags origin
|
||||||
git remote set-head origin --auto >/dev/null
|
git remote set-head origin --auto >/dev/null
|
||||||
git reset --hard origin/master
|
git reset --hard origin/HEAD
|
||||||
SKIP_FETCH_BREW_REPOSITORY=1
|
SKIP_FETCH_BREW_REPOSITORY=1
|
||||||
set +e
|
set +e
|
||||||
trap - EXIT
|
trap - EXIT
|
||||||
@ -77,9 +78,10 @@ git_init_if_necessary() {
|
|||||||
fi
|
fi
|
||||||
git config remote.origin.url "${HOMEBREW_CORE_GIT_REMOTE}"
|
git config remote.origin.url "${HOMEBREW_CORE_GIT_REMOTE}"
|
||||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||||
git fetch --force origin refs/heads/master:refs/remotes/origin/master
|
git config fetch.prune true
|
||||||
|
git fetch --force origin
|
||||||
git remote set-head origin --auto >/dev/null
|
git remote set-head origin --auto >/dev/null
|
||||||
git reset --hard origin/master
|
git reset --hard origin/HEAD
|
||||||
SKIP_FETCH_CORE_REPOSITORY=1
|
SKIP_FETCH_CORE_REPOSITORY=1
|
||||||
set +e
|
set +e
|
||||||
trap - EXIT
|
trap - EXIT
|
||||||
@ -110,7 +112,7 @@ upstream_branch() {
|
|||||||
upstream_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)"
|
upstream_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)"
|
||||||
fi
|
fi
|
||||||
upstream_branch="${upstream_branch#refs/remotes/origin/}"
|
upstream_branch="${upstream_branch#refs/remotes/origin/}"
|
||||||
[[ -z "${upstream_branch}" ]] && upstream_branch="master"
|
[[ -z "${upstream_branch}" ]] && upstream_branch="main"
|
||||||
echo "${upstream_branch}"
|
echo "${upstream_branch}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +244,7 @@ merge_or_rebase() {
|
|||||||
Could not 'git stash' in ${DIR}!
|
Could not 'git stash' in ${DIR}!
|
||||||
Please stash/commit manually if you need to keep your changes or, if not, run:
|
Please stash/commit manually if you need to keep your changes or, if not, run:
|
||||||
cd ${DIR}
|
cd ${DIR}
|
||||||
git reset --hard origin/master
|
git reset --hard origin/HEAD
|
||||||
EOS
|
EOS
|
||||||
fi
|
fi
|
||||||
git reset --hard "${QUIET_ARGS[@]}"
|
git reset --hard "${QUIET_ARGS[@]}"
|
||||||
@ -260,10 +262,12 @@ EOS
|
|||||||
then
|
then
|
||||||
git checkout --force "${UPSTREAM_BRANCH}" "${QUIET_ARGS[@]}"
|
git checkout --force "${UPSTREAM_BRANCH}" "${QUIET_ARGS[@]}"
|
||||||
else
|
else
|
||||||
if [[ -n "${UPSTREAM_TAG}" && "${UPSTREAM_BRANCH}" != "master" ]] &&
|
if [[ -n "${UPSTREAM_TAG}" && "${UPSTREAM_BRANCH}" != "master" && "${UPSTREAM_BRANCH}" != "main" ]] &&
|
||||||
[[ "${INITIAL_BRANCH}" != "master" ]]
|
[[ "${INITIAL_BRANCH}" != "master" && "${INITIAL_BRANCH}" != "main" ]]
|
||||||
then
|
then
|
||||||
git branch --force "master" "origin/master" "${QUIET_ARGS[@]}"
|
local detected_upstream_branch
|
||||||
|
detected_upstream_branch="$(upstream_branch)"
|
||||||
|
git branch --force "${detected_upstream_branch}" "origin/${detected_upstream_branch}" "${QUIET_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git checkout --force -B "${UPSTREAM_BRANCH}" "${REMOTE_REF}" "${QUIET_ARGS[@]}"
|
git checkout --force -B "${UPSTREAM_BRANCH}" "${REMOTE_REF}" "${QUIET_ARGS[@]}"
|
||||||
@ -541,7 +545,8 @@ EOS
|
|||||||
echo "HOMEBREW_CORE_GIT_REMOTE set: using ${HOMEBREW_CORE_GIT_REMOTE} as the Homebrew/homebrew-core Git remote."
|
echo "HOMEBREW_CORE_GIT_REMOTE set: using ${HOMEBREW_CORE_GIT_REMOTE} as the Homebrew/homebrew-core Git remote."
|
||||||
git remote set-url origin "${HOMEBREW_CORE_GIT_REMOTE}"
|
git remote set-url origin "${HOMEBREW_CORE_GIT_REMOTE}"
|
||||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||||
git fetch --force origin refs/heads/master:refs/remotes/origin/master
|
git config fetch.prune true
|
||||||
|
git fetch --force origin
|
||||||
SKIP_FETCH_CORE_REPOSITORY=1
|
SKIP_FETCH_CORE_REPOSITORY=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -642,9 +647,9 @@ EOS
|
|||||||
UPDATING_MESSAGE_SHOWN=1
|
UPDATING_MESSAGE_SHOWN=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The upstream repository's default branch may not be master;
|
# The upstream repository's default branch may not be main or master;
|
||||||
# check refs/remotes/origin/HEAD to see what the default
|
# check refs/remotes/origin/HEAD to see what the default
|
||||||
# origin branch name is, and use that. If not set, fall back to "master".
|
# origin branch name is, and use that. If not set, fall back to "main".
|
||||||
# the refspec ensures that the default upstream branch gets updated
|
# the refspec ensures that the default upstream branch gets updated
|
||||||
(
|
(
|
||||||
UPSTREAM_REPOSITORY_URL="$(git config remote.origin.url)"
|
UPSTREAM_REPOSITORY_URL="$(git config remote.origin.url)"
|
||||||
@ -732,9 +737,9 @@ EOS
|
|||||||
then
|
then
|
||||||
local git_errors
|
local git_errors
|
||||||
git_errors="$(cat "${tmp_failure_file}")"
|
git_errors="$(cat "${tmp_failure_file}")"
|
||||||
|
# Attempt migration from master to main branch.
|
||||||
if [[ "${git_errors}" == "fatal: couldn't find remote ref refs/heads/master" ]]
|
if [[ "${git_errors}" == "fatal: couldn't find remote ref refs/heads/master" ]]
|
||||||
then
|
then
|
||||||
# Attempt migration from master to main branch.
|
|
||||||
if git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
if git fetch --tags --force "${QUIET_ARGS[@]}" origin \
|
||||||
"refs/heads/main:refs/remotes/origin/main" 2>>"${tmp_failure_file}"
|
"refs/heads/main:refs/remotes/origin/main" 2>>"${tmp_failure_file}"
|
||||||
then
|
then
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"$schema" : "https://json-schema.org/draft/2019-09/schema",
|
"$schema" : "https://json-schema.org/draft/2019-09/schema",
|
||||||
"$id" : "http://spdx.org/rdf/terms/2.3",
|
"$id" : "http://spdx.org/rdf/terms/2.3",
|
||||||
"title" : "SPDX 2.3",
|
"title" : "SPDX 2.3.1-dev",
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"$schema": {
|
"$schema": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Reference the SPDX 2.3 JSON schema."
|
"description": "Reference the SPDX 2.3.1 JSON schema."
|
||||||
},
|
},
|
||||||
"SPDXID" : {
|
"SPDXID" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
@ -90,7 +90,7 @@
|
|||||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||||
},
|
},
|
||||||
"checksumValue" : {
|
"checksumValue" : {
|
||||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -270,10 +270,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributionTexts" : {
|
"attributionTexts" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"items" : {
|
"items" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -293,7 +293,7 @@
|
|||||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||||
},
|
},
|
||||||
"checksumValue" : {
|
"checksumValue" : {
|
||||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -375,10 +375,10 @@
|
|||||||
"type" : "string"
|
"type" : "string"
|
||||||
},
|
},
|
||||||
"licenseInfoFromFiles" : {
|
"licenseInfoFromFiles" : {
|
||||||
"description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
"description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of all licenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"items" : {
|
"items" : {
|
||||||
"description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
"description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of all licenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -417,7 +417,7 @@
|
|||||||
"primaryPackagePurpose" : {
|
"primaryPackagePurpose" : {
|
||||||
"description" : "This field provides information about the primary purpose of the identified package. Package Purpose is intrinsic to how the package is being used rather than the content of the package.",
|
"description" : "This field provides information about the primary purpose of the identified package. Package Purpose is intrinsic to how the package is being used rather than the content of the package.",
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING_SYSTEM", "FILE" ]
|
"enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING-SYSTEM", "FILE" ]
|
||||||
},
|
},
|
||||||
"releaseDate" : {
|
"releaseDate" : {
|
||||||
"description" : "This field provides a place for recording the date the package was released.",
|
"description" : "This field provides a place for recording the date the package was released.",
|
||||||
@ -494,10 +494,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributionTexts" : {
|
"attributionTexts" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"items" : {
|
"items" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -514,7 +514,7 @@
|
|||||||
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
"enum" : [ "SHA1", "BLAKE3", "SHA3-384", "SHA256", "SHA384", "BLAKE2b-512", "BLAKE2b-256", "SHA3-512", "MD2", "ADLER32", "MD4", "SHA3-256", "BLAKE2b-384", "SHA512", "MD6", "MD5", "SHA224" ]
|
||||||
},
|
},
|
||||||
"checksumValue" : {
|
"checksumValue" : {
|
||||||
"description" : "The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.",
|
"description" : "The checksumValue property provides a lower case hexadecimal encoded digest value produced using a specific algorithm.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -624,10 +624,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributionTexts" : {
|
"attributionTexts" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"items" : {
|
"items" : {
|
||||||
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
"description" : "This field provides a place for the SPDX data creator to record acknowledgements that may be required to be communicated in some contexts. This is not meant to include the actual complete license text (see licenseConcluded and licenseDeclared), and may or may not include copyright notices (see also copyrightText). The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from license texts, which may be necessary or desirable to reproduce.",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -709,7 +709,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snippetFromFile" : {
|
"snippetFromFile" : {
|
||||||
"description" : "SPDX ID for File. File containing the SPDX element (e.g. the file contaning a snippet).",
|
"description" : "SPDX ID for File. File containing the SPDX element (e.g. the file containing a snippet).",
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "irb"
|
require "irb"
|
||||||
|
|
||||||
module IRB
|
module IRB
|
||||||
|
sig { params(binding: Binding).void }
|
||||||
def self.start_within(binding)
|
def self.start_within(binding)
|
||||||
old_stdout_sync = $stdout.sync
|
old_stdout_sync = $stdout.sync
|
||||||
$stdout.sync = true
|
$stdout.sync = true
|
||||||
|
|
||||||
|
@setup_done ||= T.let(false, T.nilable(T::Boolean))
|
||||||
unless @setup_done
|
unless @setup_done
|
||||||
setup(nil, argv: [])
|
setup(nil, argv: [])
|
||||||
@setup_done = true
|
@setup_done = true
|
||||||
|
@ -190,7 +190,7 @@ module Homebrew
|
|||||||
def generate_system_options(cask)
|
def generate_system_options(cask)
|
||||||
current_os = Homebrew::SimulateSystem.current_os
|
current_os = Homebrew::SimulateSystem.current_os
|
||||||
current_os_is_macos = MacOSVersion::SYMBOLS.include?(current_os)
|
current_os_is_macos = MacOSVersion::SYMBOLS.include?(current_os)
|
||||||
newest_macos = MacOSVersion::SYMBOLS.keys.first
|
newest_macos = MacOSVersion.new(HOMEBREW_MACOS_NEWEST_SUPPORTED).to_sym
|
||||||
|
|
||||||
depends_on_archs = cask.depends_on.arch&.filter_map { |arch| arch[:type] }&.uniq
|
depends_on_archs = cask.depends_on.arch&.filter_map { |arch| arch[:type] }&.uniq
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ module Homebrew
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if github_release_data.present?
|
if github_release_data.present? && github_release_data["body"].present?
|
||||||
pre = "pre" if github_release_data["prerelease"].present?
|
pre = "pre" if github_release_data["prerelease"].present?
|
||||||
# maximum length of PR body is 65,536 characters so let's truncate release notes to half of that.
|
# maximum length of PR body is 65,536 characters so let's truncate release notes to half of that.
|
||||||
body = Formatter.truncate(github_release_data["body"], max: 32_768)
|
body = Formatter.truncate(github_release_data["body"], max: 32_768)
|
||||||
|
@ -183,41 +183,42 @@ module Homebrew
|
|||||||
:zig
|
:zig
|
||||||
end
|
end
|
||||||
|
|
||||||
fc = FormulaCreator.new(
|
formula_creator = FormulaCreator.new(
|
||||||
args.set_name,
|
|
||||||
args.set_version,
|
|
||||||
tap: args.tap,
|
|
||||||
url: args.named.fetch(0),
|
url: args.named.fetch(0),
|
||||||
|
name: args.set_name,
|
||||||
|
version: args.set_version,
|
||||||
|
tap: args.tap,
|
||||||
mode:,
|
mode:,
|
||||||
license: args.set_license,
|
license: args.set_license,
|
||||||
fetch: !args.no_fetch?,
|
fetch: !args.no_fetch?,
|
||||||
head: args.HEAD?,
|
head: args.HEAD?,
|
||||||
)
|
)
|
||||||
fc.parse_url
|
|
||||||
# ask for confirmation if name wasn't passed explicitly
|
# ask for confirmation if name wasn't passed explicitly
|
||||||
if args.set_name.blank?
|
if args.set_name.blank?
|
||||||
print "Formula name [#{fc.name}]: "
|
print "Formula name [#{formula_creator.name}]: "
|
||||||
fc.name = __gets || fc.name
|
confirmed_name = __gets
|
||||||
|
formula_creator.name = confirmed_name if confirmed_name.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
fc.verify
|
formula_creator.verify_tap_available!
|
||||||
|
|
||||||
# Check for disallowed formula, or names that shadow aliases,
|
# Check for disallowed formula, or names that shadow aliases,
|
||||||
# unless --force is specified.
|
# unless --force is specified.
|
||||||
unless args.force?
|
unless args.force?
|
||||||
if (reason = MissingFormula.disallowed_reason(fc.name))
|
if (reason = MissingFormula.disallowed_reason(formula_creator.name))
|
||||||
odie <<~EOS
|
odie <<~EOS
|
||||||
The formula '#{fc.name}' is not allowed to be created.
|
The formula '#{formula_creator.name}' is not allowed to be created.
|
||||||
#{reason}
|
#{reason}
|
||||||
If you really want to create this formula use `--force`.
|
If you really want to create this formula use `--force`.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
Homebrew.with_no_api_env do
|
Homebrew.with_no_api_env do
|
||||||
if Formula.aliases.include? fc.name
|
if Formula.aliases.include?(formula_creator.name)
|
||||||
realname = Formulary.canonical_name(fc.name)
|
realname = Formulary.canonical_name(formula_creator.name)
|
||||||
odie <<~EOS
|
odie <<~EOS
|
||||||
The formula '#{realname}' is already aliased to '#{fc.name}'.
|
The formula '#{realname}' is already aliased to '#{formula_creator.name}'.
|
||||||
Please check that you are not creating a duplicate.
|
Please check that you are not creating a duplicate.
|
||||||
To force creation use `--force`.
|
To force creation use `--force`.
|
||||||
EOS
|
EOS
|
||||||
@ -225,19 +226,19 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
path = fc.write_formula!
|
path = formula_creator.write_formula!
|
||||||
|
|
||||||
formula = Homebrew.with_no_api_env do
|
formula = Homebrew.with_no_api_env do
|
||||||
CoreTap.instance.clear_cache
|
CoreTap.instance.clear_cache
|
||||||
Formula[fc.name]
|
Formula[formula_creator.name]
|
||||||
end
|
end
|
||||||
PyPI.update_python_resources! formula, ignore_non_pypi_packages: true if args.python?
|
PyPI.update_python_resources! formula, ignore_non_pypi_packages: true if args.python?
|
||||||
|
|
||||||
puts <<~EOS
|
puts <<~EOS
|
||||||
Please audit and test formula before submitting:
|
Please audit and test formula before submitting:
|
||||||
HOMEBREW_NO_INSTALL_FROM_API=1 brew audit --new #{fc.name}
|
HOMEBREW_NO_INSTALL_FROM_API=1 brew audit --new #{formula_creator.name}
|
||||||
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --build-from-source --verbose --debug #{fc.name}
|
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --build-from-source --verbose --debug #{formula_creator.name}
|
||||||
HOMEBREW_NO_INSTALL_FROM_API=1 brew test #{fc.name}
|
HOMEBREW_NO_INSTALL_FROM_API=1 brew test #{formula_creator.name}
|
||||||
EOS
|
EOS
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:disable Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "abstract_command"
|
require "abstract_command"
|
||||||
@ -172,7 +172,8 @@ module Homebrew
|
|||||||
with_monkey_patch { Formulary.from_contents(name, file, contents, ignore_errors: true) }
|
with_monkey_patch { Formulary.from_contents(name, file, contents, ignore_errors: true) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_monkey_patch
|
sig { params(_block: T.proc.void).returns(T.untyped) }
|
||||||
|
def with_monkey_patch(&_block)
|
||||||
# Since `method_defined?` is not a supported type guard, the use of `alias_method` below is not typesafe:
|
# Since `method_defined?` is not a supported type guard, the use of `alias_method` below is not typesafe:
|
||||||
BottleSpecification.class_eval do
|
BottleSpecification.class_eval do
|
||||||
T.unsafe(self).alias_method :old_method_missing, :method_missing if method_defined?(:method_missing)
|
T.unsafe(self).alias_method :old_method_missing, :method_missing if method_defined?(:method_missing)
|
||||||
@ -210,28 +211,28 @@ module Homebrew
|
|||||||
BottleSpecification.class_eval do
|
BottleSpecification.class_eval do
|
||||||
if method_defined?(:old_method_missing)
|
if method_defined?(:old_method_missing)
|
||||||
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
||||||
undef :old_method_missing
|
T.unsafe(self).undef :old_method_missing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Module.class_eval do
|
Module.class_eval do
|
||||||
if method_defined?(:old_method_missing)
|
if method_defined?(:old_method_missing)
|
||||||
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
||||||
undef :old_method_missing
|
T.unsafe(self).undef :old_method_missing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Resource.class_eval do
|
Resource.class_eval do
|
||||||
if method_defined?(:old_method_missing)
|
if method_defined?(:old_method_missing)
|
||||||
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
T.unsafe(self).alias_method :method_missing, :old_method_missing
|
||||||
undef :old_method_missing
|
T.unsafe(self).undef :old_method_missing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
DependencyCollector.class_eval do
|
DependencyCollector.class_eval do
|
||||||
if method_defined?(:old_parse_symbol_spec)
|
if method_defined?(:old_parse_symbol_spec)
|
||||||
T.unsafe(self).alias_method :parse_symbol_spec, :old_parse_symbol_spec
|
T.unsafe(self).alias_method :parse_symbol_spec, :old_parse_symbol_spec
|
||||||
undef :old_parse_symbol_spec
|
T.unsafe(self).undef :old_parse_symbol_spec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -45,7 +45,7 @@ module Homebrew
|
|||||||
Cask::Cask.generating_hash!
|
Cask::Cask.generating_hash!
|
||||||
|
|
||||||
all_casks = {}
|
all_casks = {}
|
||||||
latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym
|
latest_macos = MacOSVersion.new(HOMEBREW_MACOS_NEWEST_SUPPORTED).to_sym
|
||||||
Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do
|
Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do
|
||||||
tap.cask_files.each do |path|
|
tap.cask_files.each do |path|
|
||||||
cask = Cask::CaskLoader.load(path)
|
cask = Cask::CaskLoader.load(path)
|
||||||
|
@ -67,8 +67,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
raise UsageError, "Only one url can be specified" if pr_url&.count&.> 1
|
raise UsageError, "Only one url can be specified" if pr_url&.count&.> 1
|
||||||
|
|
||||||
labels = if pr_url
|
labels = if pr_url && (first_pr_url = pr_url.first)
|
||||||
pr = GitHub::API.open_rest(pr_url.first)
|
pr = GitHub::API.open_rest(first_pr_url)
|
||||||
pr.fetch("labels").map { |l| l.fetch("name") }
|
pr.fetch("labels").map { |l| l.fetch("name") }
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
@ -263,11 +263,10 @@ module Homebrew
|
|||||||
audit_exceptions << %w[homepage_https_availability] if labels.include?("ci-skip-homepage")
|
audit_exceptions << %w[homepage_https_availability] if labels.include?("ci-skip-homepage")
|
||||||
|
|
||||||
if labels.include?("ci-skip-livecheck")
|
if labels.include?("ci-skip-livecheck")
|
||||||
audit_exceptions << %w[hosting_with_livecheck livecheck_https_availability
|
audit_exceptions << %w[hosting_with_livecheck livecheck_https_availability livecheck_version min_os]
|
||||||
livecheck_min_os livecheck_version]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
audit_exceptions << "livecheck_min_os" if labels.include?("ci-skip-livecheck-min-os")
|
audit_exceptions << "min_os" if labels.include?("ci-skip-livecheck-min-os")
|
||||||
|
|
||||||
if labels.include?("ci-skip-repository")
|
if labels.include?("ci-skip-repository")
|
||||||
audit_exceptions << %w[github_repository github_prerelease_version
|
audit_exceptions << %w[github_repository github_prerelease_version
|
||||||
|
@ -44,12 +44,11 @@ module Homebrew
|
|||||||
titleized_repository = tap.repository.dup
|
titleized_repository = tap.repository.dup
|
||||||
titleized_user[0] = titleized_user[0].upcase
|
titleized_user[0] = titleized_user[0].upcase
|
||||||
titleized_repository[0] = titleized_repository[0].upcase
|
titleized_repository[0] = titleized_repository[0].upcase
|
||||||
root_url = GitHubPackages.root_url(tap.user, "homebrew-#{tap.repository}") if args.github_packages?
|
# Duplicate assignment to silence `assigned but unused variable` warning
|
||||||
|
root_url = root_url = GitHubPackages.root_url(tap.user, "homebrew-#{tap.repository}") if args.github_packages?
|
||||||
|
|
||||||
(tap.path/"Formula").mkpath
|
(tap.path/"Formula").mkpath
|
||||||
|
|
||||||
# FIXME: https://github.com/errata-ai/vale/issues/818
|
|
||||||
# <!-- vale off -->
|
|
||||||
readme = <<~MARKDOWN
|
readme = <<~MARKDOWN
|
||||||
# #{titleized_user} #{titleized_repository}
|
# #{titleized_user} #{titleized_repository}
|
||||||
|
|
||||||
@ -70,7 +69,6 @@ module Homebrew
|
|||||||
|
|
||||||
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
`brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh).
|
||||||
MARKDOWN
|
MARKDOWN
|
||||||
# <!-- vale on -->
|
|
||||||
write_path(tap, "README.md", readme)
|
write_path(tap, "README.md", readme)
|
||||||
|
|
||||||
tests_yml = <<~ERB
|
tests_yml = <<~ERB
|
||||||
@ -99,7 +97,7 @@ module Homebrew
|
|||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
id: set-up-homebrew
|
id: set-up-homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|
||||||
@ -164,12 +162,12 @@ module Homebrew
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@main
|
||||||
with:
|
with:
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|
||||||
- name: Set up git
|
- name: Set up git
|
||||||
uses: Homebrew/actions/git-user-config@master
|
uses: Homebrew/actions/git-user-config@main
|
||||||
|
|
||||||
- name: Pull bottles
|
- name: Pull bottles
|
||||||
env:
|
env:
|
||||||
@ -182,7 +180,7 @@ module Homebrew
|
|||||||
run: brew pr-pull --debug --tap="$GITHUB_REPOSITORY" "$PULL_REQUEST"
|
run: brew pr-pull --debug --tap="$GITHUB_REPOSITORY" "$PULL_REQUEST"
|
||||||
|
|
||||||
- name: Push commits
|
- name: Push commits
|
||||||
uses: Homebrew/actions/git-try-push@master
|
uses: Homebrew/actions/git-try-push@main
|
||||||
with:
|
with:
|
||||||
branch: <%= branch %>
|
branch: <%= branch %>
|
||||||
|
|
||||||
|
@ -51,6 +51,11 @@ module Homebrew
|
|||||||
HOMEBREW_LIBRARY_PATH.cd do
|
HOMEBREW_LIBRARY_PATH.cd do
|
||||||
setup_environment!
|
setup_environment!
|
||||||
|
|
||||||
|
# Needs required here, after `setup_environment!`, so that
|
||||||
|
# `HOMEBREW_TEST_GENERIC_OS` is set and `OS.linux?` and `OS.mac?` both
|
||||||
|
# `return false`.
|
||||||
|
require "extend/os/dev-cmd/tests"
|
||||||
|
|
||||||
parallel = !args.no_parallel?
|
parallel = !args.no_parallel?
|
||||||
|
|
||||||
only = args.only
|
only = args.only
|
||||||
@ -267,5 +272,3 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "extend/os/dev-cmd/tests"
|
|
||||||
|
@ -142,6 +142,7 @@ module Homebrew
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def git_tags
|
def git_tags
|
||||||
tags = Utils.popen_read("git", "tag", "--list", "--sort=-version:refname")
|
tags = Utils.popen_read("git", "tag", "--list", "--sort=-version:refname")
|
||||||
if tags.blank?
|
if tags.blank?
|
||||||
|
@ -350,7 +350,6 @@ module Homebrew
|
|||||||
sudo chmod +t #{HOMEBREW_TEMP}
|
sudo chmod +t #{HOMEBREW_TEMP}
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
alias generic_check_tmpdir_sticky_bit check_tmpdir_sticky_bit
|
|
||||||
|
|
||||||
def check_exist_directories
|
def check_exist_directories
|
||||||
return if HOMEBREW_PREFIX.writable?
|
return if HOMEBREW_PREFIX.writable?
|
||||||
|
@ -54,8 +54,6 @@ module SharedEnvExtension
|
|||||||
@debug_symbols = debug_symbols
|
@debug_symbols = debug_symbols
|
||||||
reset
|
reset
|
||||||
end
|
end
|
||||||
alias generic_shared_setup_build_environment setup_build_environment
|
|
||||||
private :generic_shared_setup_build_environment
|
|
||||||
|
|
||||||
sig { void }
|
sig { void }
|
||||||
def reset
|
def reset
|
||||||
|
@ -68,7 +68,6 @@ module Stdenv
|
|||||||
gcc_formula = gcc_version_formula(cc)
|
gcc_formula = gcc_version_formula(cc)
|
||||||
append_path "PATH", gcc_formula.opt_bin.to_s
|
append_path "PATH", gcc_formula.opt_bin.to_s
|
||||||
end
|
end
|
||||||
alias generic_setup_build_environment setup_build_environment
|
|
||||||
|
|
||||||
sig { returns(T.nilable(PATH)) }
|
sig { returns(T.nilable(PATH)) }
|
||||||
def determine_pkg_config_libdir
|
def determine_pkg_config_libdir
|
||||||
|
@ -125,7 +125,6 @@ module Superenv
|
|||||||
# These flags will also be present:
|
# These flags will also be present:
|
||||||
# a - apply fix for apr-1-config path
|
# a - apply fix for apr-1-config path
|
||||||
end
|
end
|
||||||
alias generic_setup_build_environment setup_build_environment
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
@ -152,7 +151,6 @@ module Superenv
|
|||||||
.reverse
|
.reverse
|
||||||
.map { |d| d.opt_libexec/"bin" }
|
.map { |d| d.opt_libexec/"bin" }
|
||||||
end
|
end
|
||||||
alias generic_homebrew_extra_paths homebrew_extra_paths
|
|
||||||
|
|
||||||
sig { returns(T.nilable(PATH)) }
|
sig { returns(T.nilable(PATH)) }
|
||||||
def determine_path
|
def determine_path
|
||||||
@ -372,8 +370,8 @@ module Superenv
|
|||||||
append_to_cccfg "O"
|
append_to_cccfg "O"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is an exception where we want to use this method name format.
|
||||||
# rubocop: disable Naming/MethodName
|
# rubocop: disable Naming/MethodName
|
||||||
# Fixes style error `Naming/MethodName: Use snake_case for method names.`
|
|
||||||
sig { params(block: T.nilable(T.proc.void)).void }
|
sig { params(block: T.nilable(T.proc.void)).void }
|
||||||
def O0(&block)
|
def O0(&block)
|
||||||
if block
|
if block
|
||||||
|
@ -15,6 +15,11 @@ module OS
|
|||||||
def os_bundle_args(bundle_args)
|
def os_bundle_args(bundle_args)
|
||||||
non_macos_bundle_args(bundle_args)
|
non_macos_bundle_args(bundle_args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(files: T::Array[String]).returns(T::Array[String]) }
|
||||||
|
def os_files(files)
|
||||||
|
non_macos_files(files)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Homebrew
|
module OS
|
||||||
module DevCmd
|
module Linux
|
||||||
class UpdateTest < AbstractCommand
|
module DevCmd
|
||||||
alias generic_git_tags git_tags
|
module UpdateTest
|
||||||
|
private
|
||||||
|
|
||||||
private
|
sig { returns(String) }
|
||||||
|
def git_tags
|
||||||
sig { returns(String) }
|
super.presence || Utils.popen_read("git tag --list | sort -rV")
|
||||||
def git_tags
|
end
|
||||||
tags = generic_git_tags
|
|
||||||
tags = Utils.popen_read("git tag --list | sort -rV") if tags.blank?
|
|
||||||
tags
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Homebrew::DevCmd::UpdateTest.prepend(OS::Linux::DevCmd::UpdateTest)
|
||||||
|
@ -62,7 +62,7 @@ module OS
|
|||||||
def build_system_info
|
def build_system_info
|
||||||
super.merge({
|
super.merge({
|
||||||
"glibc_version" => OS::Linux::Glibc.version.to_s.presence,
|
"glibc_version" => OS::Linux::Glibc.version.to_s.presence,
|
||||||
"oldest_cpu_family" => Hardware.oldest_cpu.to_s,
|
"oldest_cpu_family" => ::Hardware.oldest_cpu.to_s,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -32,7 +32,7 @@ module OS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_tmpdir_sticky_bit
|
def check_tmpdir_sticky_bit
|
||||||
message = generic_check_tmpdir_sticky_bit
|
message = super
|
||||||
return if message.nil?
|
return if message.nil?
|
||||||
|
|
||||||
message + <<~EOS
|
message + <<~EOS
|
||||||
@ -74,11 +74,11 @@ module OS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_supported_architecture
|
def check_supported_architecture
|
||||||
return if Hardware::CPU.intel?
|
return if ::Hardware::CPU.intel?
|
||||||
return if Homebrew::EnvConfig.developer? && ENV["HOMEBREW_ARM64_TESTING"].present? && Hardware::CPU.arm?
|
return if Homebrew::EnvConfig.developer? && ENV["HOMEBREW_ARM64_TESTING"].present? && ::Hardware::CPU.arm?
|
||||||
|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
Your CPU architecture (#{Hardware::CPU.arch}) is not supported. We only support
|
Your CPU architecture (#{::Hardware::CPU.arch}) is not supported. We only support
|
||||||
x86_64 CPU architectures. You will be unable to use binary packages (bottles).
|
x86_64 CPU architectures. You will be unable to use binary packages (bottles).
|
||||||
|
|
||||||
#{support_tier_message(tier: 2)}
|
#{support_tier_message(tier: 2)}
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module SharedEnvExtension
|
module OS
|
||||||
def effective_arch
|
module Linux
|
||||||
if @build_bottle && @bottle_arch
|
module SharedEnvExtension
|
||||||
@bottle_arch.to_sym
|
def effective_arch
|
||||||
elsif @build_bottle
|
if @build_bottle && @bottle_arch
|
||||||
Hardware.oldest_cpu
|
@bottle_arch.to_sym
|
||||||
elsif Hardware::CPU.intel? || Hardware::CPU.arm?
|
elsif @build_bottle
|
||||||
:native
|
::Hardware.oldest_cpu
|
||||||
else
|
elsif ::Hardware::CPU.intel? || ::Hardware::CPU.arm?
|
||||||
:dunno
|
:native
|
||||||
|
else
|
||||||
|
:dunno
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SharedEnvExtension.prepend(OS::Linux::SharedEnvExtension)
|
||||||
|
@ -1,36 +1,45 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Stdenv
|
module OS
|
||||||
sig {
|
module Linux
|
||||||
params(
|
module Stdenv
|
||||||
formula: T.nilable(Formula),
|
extend T::Helpers
|
||||||
cc: T.nilable(String),
|
|
||||||
build_bottle: T.nilable(T::Boolean),
|
|
||||||
bottle_arch: T.nilable(String),
|
|
||||||
testing_formula: T::Boolean,
|
|
||||||
debug_symbols: T.nilable(T::Boolean),
|
|
||||||
).void
|
|
||||||
}
|
|
||||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
|
||||||
debug_symbols: false)
|
|
||||||
generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:,
|
|
||||||
testing_formula:, debug_symbols:)
|
|
||||||
|
|
||||||
prepend_path "CPATH", HOMEBREW_PREFIX/"include"
|
requires_ancestor { ::SharedEnvExtension }
|
||||||
prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib"
|
|
||||||
prepend_path "LD_RUN_PATH", HOMEBREW_PREFIX/"lib"
|
|
||||||
|
|
||||||
return unless @formula
|
sig {
|
||||||
|
params(
|
||||||
|
formula: T.nilable(::Formula),
|
||||||
|
cc: T.nilable(String),
|
||||||
|
build_bottle: T.nilable(T::Boolean),
|
||||||
|
bottle_arch: T.nilable(String),
|
||||||
|
testing_formula: T::Boolean,
|
||||||
|
debug_symbols: T.nilable(T::Boolean),
|
||||||
|
).void
|
||||||
|
}
|
||||||
|
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil,
|
||||||
|
testing_formula: false, debug_symbols: false)
|
||||||
|
super
|
||||||
|
|
||||||
prepend_path "CPATH", @formula.include
|
prepend_path "CPATH", HOMEBREW_PREFIX/"include"
|
||||||
prepend_path "LIBRARY_PATH", @formula.lib
|
prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib"
|
||||||
prepend_path "LD_RUN_PATH", @formula.lib
|
prepend_path "LD_RUN_PATH", HOMEBREW_PREFIX/"lib"
|
||||||
end
|
|
||||||
|
|
||||||
def libxml2
|
return unless @formula
|
||||||
append "CPPFLAGS", "-I#{Formula["libxml2"].include/"libxml2"}"
|
|
||||||
rescue FormulaUnavailableError
|
prepend_path "CPATH", @formula.include
|
||||||
nil
|
prepend_path "LIBRARY_PATH", @formula.lib
|
||||||
|
prepend_path "LD_RUN_PATH", @formula.lib
|
||||||
|
end
|
||||||
|
|
||||||
|
def libxml2
|
||||||
|
append "CPPFLAGS", "-I#{::Formula["libxml2"].include/"libxml2"}"
|
||||||
|
rescue FormulaUnavailableError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Stdenv.prepend(OS::Linux::Stdenv)
|
||||||
|
@ -1,79 +1,93 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Superenv
|
module OS
|
||||||
sig { returns(Pathname) }
|
module Linux
|
||||||
def self.shims_path
|
module Superenv
|
||||||
HOMEBREW_SHIMS_PATH/"linux/super"
|
extend T::Helpers
|
||||||
end
|
|
||||||
|
|
||||||
sig { returns(T.nilable(Pathname)) }
|
requires_ancestor { SharedEnvExtension }
|
||||||
def self.bin
|
requires_ancestor { ::Superenv }
|
||||||
shims_path.realpath
|
|
||||||
end
|
|
||||||
|
|
||||||
sig {
|
module ClassMethods
|
||||||
params(
|
sig { returns(Pathname) }
|
||||||
formula: T.nilable(Formula),
|
def shims_path
|
||||||
cc: T.nilable(String),
|
HOMEBREW_SHIMS_PATH/"linux/super"
|
||||||
build_bottle: T.nilable(T::Boolean),
|
end
|
||||||
bottle_arch: T.nilable(String),
|
|
||||||
testing_formula: T::Boolean,
|
|
||||||
debug_symbols: T.nilable(T::Boolean),
|
|
||||||
).void
|
|
||||||
}
|
|
||||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
|
||||||
debug_symbols: false)
|
|
||||||
generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:,
|
|
||||||
testing_formula:, debug_symbols:)
|
|
||||||
self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2"
|
|
||||||
self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path
|
|
||||||
self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula)
|
|
||||||
m4_path_deps = ["libtool", "bison"]
|
|
||||||
self["M4"] = "#{HOMEBREW_PREFIX}/opt/m4/bin/m4" if deps.any? { m4_path_deps.include?(_1.name) }
|
|
||||||
|
|
||||||
# Pointer authentication and BTI are hardening techniques most distros
|
sig { returns(T.nilable(Pathname)) }
|
||||||
# use by default on their packages. arm64 Linux we're packaging
|
def bin
|
||||||
# everything from scratch so the entire dependency tree can have it.
|
shims_path.realpath
|
||||||
append_to_cccfg "b" if Hardware::CPU.arch == :arm64 && DevelopmentTools.gcc_version("gcc") >= 9
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def homebrew_extra_paths
|
sig {
|
||||||
paths = generic_homebrew_extra_paths
|
params(
|
||||||
paths += %w[binutils make].filter_map do |f|
|
formula: T.nilable(Formula),
|
||||||
bin = Formulary.factory(f).opt_bin
|
cc: T.nilable(String),
|
||||||
bin if bin.directory?
|
build_bottle: T.nilable(T::Boolean),
|
||||||
rescue FormulaUnavailableError
|
bottle_arch: T.nilable(String),
|
||||||
nil
|
testing_formula: T::Boolean,
|
||||||
|
debug_symbols: T.nilable(T::Boolean),
|
||||||
|
).void
|
||||||
|
}
|
||||||
|
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil,
|
||||||
|
testing_formula: false, debug_symbols: false)
|
||||||
|
super
|
||||||
|
|
||||||
|
self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2"
|
||||||
|
self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path
|
||||||
|
self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula)
|
||||||
|
m4_path_deps = ["libtool", "bison"]
|
||||||
|
self["M4"] = "#{HOMEBREW_PREFIX}/opt/m4/bin/m4" if deps.any? { m4_path_deps.include?(_1.name) }
|
||||||
|
|
||||||
|
# Pointer authentication and BTI are hardening techniques most distros
|
||||||
|
# use by default on their packages. arm64 Linux we're packaging
|
||||||
|
# everything from scratch so the entire dependency tree can have it.
|
||||||
|
append_to_cccfg "b" if ::Hardware::CPU.arch == :arm64 && ::DevelopmentTools.gcc_version("gcc") >= 9
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_paths
|
||||||
|
paths = super
|
||||||
|
paths += %w[binutils make].filter_map do |f|
|
||||||
|
bin = Formulary.factory(f).opt_bin
|
||||||
|
bin if bin.directory?
|
||||||
|
rescue FormulaUnavailableError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_isystem_paths
|
||||||
|
paths = []
|
||||||
|
# Add paths for GCC headers when building against versioned glibc because we have to use -nostdinc.
|
||||||
|
if deps.any? { |d| d.name.match?(/^glibc@.+$/) }
|
||||||
|
gcc_include_dir = Utils.safe_popen_read(cc, "--print-file-name=include").chomp
|
||||||
|
gcc_include_fixed_dir = Utils.safe_popen_read(cc, "--print-file-name=include-fixed").chomp
|
||||||
|
paths << gcc_include_dir << gcc_include_fixed_dir
|
||||||
|
end
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def determine_rpath_paths(formula)
|
||||||
|
PATH.new(
|
||||||
|
*formula&.lib,
|
||||||
|
"#{HOMEBREW_PREFIX}/opt/gcc/lib/gcc/current",
|
||||||
|
PATH.new(run_time_deps.map { |dep| dep.opt_lib.to_s }).existing,
|
||||||
|
"#{HOMEBREW_PREFIX}/lib",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { returns(T.nilable(String)) }
|
||||||
|
def determine_dynamic_linker_path
|
||||||
|
path = "#{HOMEBREW_PREFIX}/lib/ld.so"
|
||||||
|
return unless File.readable? path
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
end
|
end
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def homebrew_extra_isystem_paths
|
|
||||||
paths = []
|
|
||||||
# Add paths for GCC headers when building against versioned glibc because we have to use -nostdinc.
|
|
||||||
if deps.any? { |d| d.name.match?(/^glibc@.+$/) }
|
|
||||||
gcc_include_dir = Utils.safe_popen_read(cc, "--print-file-name=include").chomp
|
|
||||||
gcc_include_fixed_dir = Utils.safe_popen_read(cc, "--print-file-name=include-fixed").chomp
|
|
||||||
paths << gcc_include_dir << gcc_include_fixed_dir
|
|
||||||
end
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def determine_rpath_paths(formula)
|
|
||||||
PATH.new(
|
|
||||||
*formula&.lib,
|
|
||||||
"#{HOMEBREW_PREFIX}/opt/gcc/lib/gcc/current",
|
|
||||||
PATH.new(run_time_deps.map { |dep| dep.opt_lib.to_s }).existing,
|
|
||||||
"#{HOMEBREW_PREFIX}/lib",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { returns(T.nilable(String)) }
|
|
||||||
def determine_dynamic_linker_path
|
|
||||||
path = "#{HOMEBREW_PREFIX}/lib/ld.so"
|
|
||||||
return unless File.readable? path
|
|
||||||
|
|
||||||
path
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Superenv.singleton_class.prepend(OS::Linux::Superenv::ClassMethods)
|
||||||
|
Superenv.prepend(OS::Linux::Superenv)
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module FormulaCellarChecks
|
module OS
|
||||||
sig { params(filename: Pathname).returns(T::Boolean) }
|
module Linux
|
||||||
def valid_library_extension?(filename)
|
module FormulaCellarChecks
|
||||||
generic_valid_library_extension?(filename) || filename.basename.to_s.include?(".so.")
|
sig { params(filename: Pathname).returns(T::Boolean) }
|
||||||
|
def valid_library_extension?(filename)
|
||||||
|
super || filename.basename.to_s.include?(".so.")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
FormulaCellarChecks.prepend(OS::Linux::FormulaCellarChecks)
|
||||||
|
@ -1,161 +1,171 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Hardware
|
module OS
|
||||||
class CPU
|
module Linux
|
||||||
class << self
|
module Hardware
|
||||||
def optimization_flags
|
module CPU
|
||||||
@optimization_flags ||= begin
|
module ClassMethods
|
||||||
flags = generic_optimization_flags.dup
|
extend T::Helpers
|
||||||
flags[:native] = arch_flag(Homebrew::EnvConfig.arch)
|
|
||||||
flags
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def family
|
requires_ancestor { T.class_of(::Hardware::CPU) }
|
||||||
return :arm if arm?
|
|
||||||
return :ppc if ppc?
|
|
||||||
return :dunno unless intel?
|
|
||||||
|
|
||||||
# See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
|
def optimization_flags
|
||||||
# and https://github.com/llvm/llvm-project/blob/main/llvm/lib/TargetParser/Host.cpp
|
@optimization_flags ||= begin
|
||||||
# and https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures#Roadmap
|
flags = super.dup
|
||||||
vendor_id = cpuinfo[/^vendor_id\s*: (.*)/, 1]
|
flags[:native] = arch_flag(Homebrew::EnvConfig.arch)
|
||||||
cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
|
flags
|
||||||
cpu_model = cpuinfo[/^model\s*: ([0-9]+)/, 1].to_i
|
end
|
||||||
unknown = :"unknown_0x#{cpu_family.to_s(16)}_0x#{cpu_model.to_s(16)}"
|
|
||||||
case vendor_id
|
|
||||||
when "GenuineIntel"
|
|
||||||
intel_family(cpu_family, cpu_model)
|
|
||||||
when "AuthenticAMD"
|
|
||||||
amd_family(cpu_family, cpu_model)
|
|
||||||
end || unknown
|
|
||||||
end
|
|
||||||
|
|
||||||
def intel_family(family, cpu_model)
|
|
||||||
case family
|
|
||||||
when 0x06
|
|
||||||
case cpu_model
|
|
||||||
when 0x3a, 0x3e
|
|
||||||
:ivybridge
|
|
||||||
when 0x2a, 0x2d
|
|
||||||
:sandybridge
|
|
||||||
when 0x25, 0x2c, 0x2f
|
|
||||||
:westmere
|
|
||||||
when 0x1a, 0x1e, 0x1f, 0x2e
|
|
||||||
:nehalem
|
|
||||||
when 0x17, 0x1d
|
|
||||||
:penryn
|
|
||||||
when 0x0f, 0x16
|
|
||||||
:merom
|
|
||||||
when 0x0d
|
|
||||||
:dothan
|
|
||||||
when 0x1c, 0x26, 0x27, 0x35, 0x36
|
|
||||||
:atom
|
|
||||||
when 0x3c, 0x3f, 0x45, 0x46
|
|
||||||
:haswell
|
|
||||||
when 0x3d, 0x47, 0x4f, 0x56
|
|
||||||
:broadwell
|
|
||||||
when 0x4e, 0x5e, 0x8e, 0x9e, 0xa5, 0xa6
|
|
||||||
:skylake
|
|
||||||
when 0x66
|
|
||||||
:cannonlake
|
|
||||||
when 0x6a, 0x6c, 0x7d, 0x7e
|
|
||||||
:icelake
|
|
||||||
when 0xa7
|
|
||||||
:rocketlake
|
|
||||||
when 0x8c, 0x8d
|
|
||||||
:tigerlake
|
|
||||||
when 0x97, 0x9a, 0xbe, 0xb7, 0xba, 0xbf, 0xaa, 0xac
|
|
||||||
:alderlake
|
|
||||||
when 0xc5, 0xb5, 0xc6, 0xbd
|
|
||||||
:arrowlake
|
|
||||||
when 0xcc
|
|
||||||
:pantherlake
|
|
||||||
when 0xad, 0xae
|
|
||||||
:graniterapids
|
|
||||||
when 0xcf, 0x8f
|
|
||||||
:sapphirerapids
|
|
||||||
end
|
end
|
||||||
when 0x0f
|
|
||||||
case cpu_model
|
def family
|
||||||
when 0x06
|
return :arm if arm?
|
||||||
:presler
|
return :ppc if ppc?
|
||||||
when 0x03, 0x04
|
return :dunno unless intel?
|
||||||
:prescott
|
|
||||||
|
# See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
|
||||||
|
# and https://github.com/llvm/llvm-project/blob/main/llvm/lib/TargetParser/Host.cpp
|
||||||
|
# and https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures#Roadmap
|
||||||
|
vendor_id = cpuinfo[/^vendor_id\s*: (.*)/, 1]
|
||||||
|
cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
|
||||||
|
cpu_model = cpuinfo[/^model\s*: ([0-9]+)/, 1].to_i
|
||||||
|
unknown = :"unknown_0x#{cpu_family.to_s(16)}_0x#{cpu_model.to_s(16)}"
|
||||||
|
case vendor_id
|
||||||
|
when "GenuineIntel"
|
||||||
|
intel_family(cpu_family, cpu_model)
|
||||||
|
when "AuthenticAMD"
|
||||||
|
amd_family(cpu_family, cpu_model)
|
||||||
|
end || unknown
|
||||||
|
end
|
||||||
|
|
||||||
|
def intel_family(family, cpu_model)
|
||||||
|
case family
|
||||||
|
when 0x06
|
||||||
|
case cpu_model
|
||||||
|
when 0x3a, 0x3e
|
||||||
|
:ivybridge
|
||||||
|
when 0x2a, 0x2d
|
||||||
|
:sandybridge
|
||||||
|
when 0x25, 0x2c, 0x2f
|
||||||
|
:westmere
|
||||||
|
when 0x1a, 0x1e, 0x1f, 0x2e
|
||||||
|
:nehalem
|
||||||
|
when 0x17, 0x1d
|
||||||
|
:penryn
|
||||||
|
when 0x0f, 0x16
|
||||||
|
:merom
|
||||||
|
when 0x0d
|
||||||
|
:dothan
|
||||||
|
when 0x1c, 0x26, 0x27, 0x35, 0x36
|
||||||
|
:atom
|
||||||
|
when 0x3c, 0x3f, 0x45, 0x46
|
||||||
|
:haswell
|
||||||
|
when 0x3d, 0x47, 0x4f, 0x56
|
||||||
|
:broadwell
|
||||||
|
when 0x4e, 0x5e, 0x8e, 0x9e, 0xa5, 0xa6
|
||||||
|
:skylake
|
||||||
|
when 0x66
|
||||||
|
:cannonlake
|
||||||
|
when 0x6a, 0x6c, 0x7d, 0x7e
|
||||||
|
:icelake
|
||||||
|
when 0xa7
|
||||||
|
:rocketlake
|
||||||
|
when 0x8c, 0x8d
|
||||||
|
:tigerlake
|
||||||
|
when 0x97, 0x9a, 0xbe, 0xb7, 0xba, 0xbf, 0xaa, 0xac
|
||||||
|
:alderlake
|
||||||
|
when 0xc5, 0xb5, 0xc6, 0xbd
|
||||||
|
:arrowlake
|
||||||
|
when 0xcc
|
||||||
|
:pantherlake
|
||||||
|
when 0xad, 0xae
|
||||||
|
:graniterapids
|
||||||
|
when 0xcf, 0x8f
|
||||||
|
:sapphirerapids
|
||||||
|
end
|
||||||
|
when 0x0f
|
||||||
|
case cpu_model
|
||||||
|
when 0x06
|
||||||
|
:presler
|
||||||
|
when 0x03, 0x04
|
||||||
|
:prescott
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def amd_family(family, cpu_model)
|
||||||
|
case family
|
||||||
|
when 0x06
|
||||||
|
:amd_k7
|
||||||
|
when 0x0f
|
||||||
|
:amd_k8
|
||||||
|
when 0x10
|
||||||
|
:amd_k10
|
||||||
|
when 0x11
|
||||||
|
:amd_k8_k10_hybrid
|
||||||
|
when 0x12
|
||||||
|
:amd_k10_llano
|
||||||
|
when 0x14
|
||||||
|
:bobcat
|
||||||
|
when 0x15
|
||||||
|
:bulldozer
|
||||||
|
when 0x16
|
||||||
|
:jaguar
|
||||||
|
when 0x17
|
||||||
|
case cpu_model
|
||||||
|
when 0x10..0x2f
|
||||||
|
:zen
|
||||||
|
when 0x30..0x3f, 0x47, 0x60..0x7f, 0x84..0x87, 0x90..0xaf
|
||||||
|
:zen2
|
||||||
|
end
|
||||||
|
when 0x19
|
||||||
|
case cpu_model
|
||||||
|
when ..0x0f, 0x20..0x5f
|
||||||
|
:zen3
|
||||||
|
when 0x10..0x1f, 0x60..0x7f, 0xa0..0xaf
|
||||||
|
:zen4
|
||||||
|
end
|
||||||
|
when 0x1a
|
||||||
|
:zen5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Supported CPU instructions
|
||||||
|
def flags
|
||||||
|
@flags ||= cpuinfo[/^(?:flags|Features)\s*: (.*)/, 1]&.split
|
||||||
|
@flags ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
# Compatibility with Mac method, which returns lowercase symbols
|
||||||
|
# instead of strings.
|
||||||
|
def features
|
||||||
|
@features ||= flags[1..].map(&:intern)
|
||||||
|
end
|
||||||
|
|
||||||
|
%w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag|
|
||||||
|
define_method(:"#{flag}?") do
|
||||||
|
T.bind(self, OS::Linux::Hardware::CPU::ClassMethods)
|
||||||
|
flags.include? flag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sse3?
|
||||||
|
flags.include?("pni") || flags.include?("sse3")
|
||||||
|
end
|
||||||
|
|
||||||
|
def sse4?
|
||||||
|
flags.include? "sse4_1"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def cpuinfo
|
||||||
|
@cpuinfo ||= File.read("/proc/cpuinfo")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def amd_family(family, cpu_model)
|
|
||||||
case family
|
|
||||||
when 0x06
|
|
||||||
:amd_k7
|
|
||||||
when 0x0f
|
|
||||||
:amd_k8
|
|
||||||
when 0x10
|
|
||||||
:amd_k10
|
|
||||||
when 0x11
|
|
||||||
:amd_k8_k10_hybrid
|
|
||||||
when 0x12
|
|
||||||
:amd_k10_llano
|
|
||||||
when 0x14
|
|
||||||
:bobcat
|
|
||||||
when 0x15
|
|
||||||
:bulldozer
|
|
||||||
when 0x16
|
|
||||||
:jaguar
|
|
||||||
when 0x17
|
|
||||||
case cpu_model
|
|
||||||
when 0x10..0x2f
|
|
||||||
:zen
|
|
||||||
when 0x30..0x3f, 0x47, 0x60..0x7f, 0x84..0x87, 0x90..0xaf
|
|
||||||
:zen2
|
|
||||||
end
|
|
||||||
when 0x19
|
|
||||||
case cpu_model
|
|
||||||
when ..0x0f, 0x20..0x5f
|
|
||||||
:zen3
|
|
||||||
when 0x10..0x1f, 0x60..0x7f, 0xa0..0xaf
|
|
||||||
:zen4
|
|
||||||
end
|
|
||||||
when 0x1a
|
|
||||||
:zen5
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Supported CPU instructions
|
|
||||||
def flags
|
|
||||||
@flags ||= cpuinfo[/^(?:flags|Features)\s*: (.*)/, 1]&.split
|
|
||||||
@flags ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
# Compatibility with Mac method, which returns lowercase symbols
|
|
||||||
# instead of strings.
|
|
||||||
def features
|
|
||||||
@features ||= flags[1..].map(&:intern)
|
|
||||||
end
|
|
||||||
|
|
||||||
%w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag|
|
|
||||||
define_method(:"#{flag}?") do
|
|
||||||
T.bind(self, T.class_of(Hardware::CPU))
|
|
||||||
flags.include? flag
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def sse3?
|
|
||||||
flags.include?("pni") || flags.include?("sse3")
|
|
||||||
end
|
|
||||||
|
|
||||||
def sse4?
|
|
||||||
flags.include? "sse4_1"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def cpuinfo
|
|
||||||
@cpuinfo ||= File.read("/proc/cpuinfo")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Hardware::CPU.singleton_class.prepend(OS::Linux::Hardware::CPU::ClassMethods)
|
||||||
|
@ -1,132 +1,132 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Homebrew
|
module OS
|
||||||
module Install
|
module Linux
|
||||||
# This is a list of known paths to the host dynamic linker on Linux if
|
module Install
|
||||||
# the host glibc is new enough. The symlink_ld_so method will fail if
|
module ClassMethods
|
||||||
# the host linker cannot be found in this list.
|
# This is a list of known paths to the host dynamic linker on Linux if
|
||||||
DYNAMIC_LINKERS = %w[
|
# the host glibc is new enough. The symlink_ld_so method will fail if
|
||||||
/lib64/ld-linux-x86-64.so.2
|
# the host linker cannot be found in this list.
|
||||||
/lib64/ld64.so.2
|
DYNAMIC_LINKERS = %w[
|
||||||
/lib/ld-linux.so.3
|
/lib64/ld-linux-x86-64.so.2
|
||||||
/lib/ld-linux.so.2
|
/lib64/ld64.so.2
|
||||||
/lib/ld-linux-aarch64.so.1
|
/lib/ld-linux.so.3
|
||||||
/lib/ld-linux-armhf.so.3
|
/lib/ld-linux.so.2
|
||||||
/system/bin/linker64
|
/lib/ld-linux-aarch64.so.1
|
||||||
/system/bin/linker
|
/lib/ld-linux-armhf.so.3
|
||||||
].freeze
|
/system/bin/linker64
|
||||||
private_constant :DYNAMIC_LINKERS
|
/system/bin/linker
|
||||||
|
].freeze
|
||||||
|
|
||||||
# We link GCC runtime libraries that are not specifically used for Fortran,
|
# We link GCC runtime libraries that are not specifically used for Fortran,
|
||||||
# which are linked by the GCC formula. We only use the versioned shared libraries
|
# which are linked by the GCC formula. We only use the versioned shared libraries
|
||||||
# as the other shared and static libraries are only used at build time where
|
# as the other shared and static libraries are only used at build time where
|
||||||
# GCC can find its own libraries.
|
# GCC can find its own libraries.
|
||||||
GCC_RUNTIME_LIBS = %w[
|
GCC_RUNTIME_LIBS = %w[
|
||||||
libatomic.so.1
|
libatomic.so.1
|
||||||
libgcc_s.so.1
|
libgcc_s.so.1
|
||||||
libgomp.so.1
|
libgomp.so.1
|
||||||
libstdc++.so.6
|
libstdc++.so.6
|
||||||
].freeze
|
].freeze
|
||||||
private_constant :GCC_RUNTIME_LIBS
|
|
||||||
|
|
||||||
def self.perform_preinstall_checks(all_fatal: false)
|
def perform_preinstall_checks(all_fatal: false)
|
||||||
generic_perform_preinstall_checks(all_fatal:)
|
super
|
||||||
symlink_ld_so
|
symlink_ld_so
|
||||||
setup_preferred_gcc_libs
|
setup_preferred_gcc_libs
|
||||||
end
|
|
||||||
private_class_method :perform_preinstall_checks
|
|
||||||
|
|
||||||
def self.global_post_install
|
|
||||||
generic_global_post_install
|
|
||||||
symlink_ld_so
|
|
||||||
setup_preferred_gcc_libs
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.check_cpu
|
|
||||||
return if Hardware::CPU.intel? && Hardware::CPU.is_64_bit?
|
|
||||||
return if Hardware::CPU.arm?
|
|
||||||
|
|
||||||
message = "Sorry, Homebrew does not support your computer's CPU architecture!"
|
|
||||||
if Hardware::CPU.ppc64le?
|
|
||||||
message += <<~EOS
|
|
||||||
For OpenPOWER Linux (PPC64LE) support, see:
|
|
||||||
#{Formatter.url("https://github.com/homebrew-ppc64le/brew")}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
abort message
|
|
||||||
end
|
|
||||||
private_class_method :check_cpu
|
|
||||||
|
|
||||||
def self.symlink_ld_so
|
|
||||||
brew_ld_so = HOMEBREW_PREFIX/"lib/ld.so"
|
|
||||||
|
|
||||||
ld_so = HOMEBREW_PREFIX/"opt/glibc/bin/ld.so"
|
|
||||||
unless ld_so.readable?
|
|
||||||
ld_so = DYNAMIC_LINKERS.find { |s| File.executable? s }
|
|
||||||
if ld_so.blank?
|
|
||||||
raise "Unable to locate the system's dynamic linker" unless brew_ld_so.readable?
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return if brew_ld_so.readable? && (brew_ld_so.readlink == ld_so)
|
|
||||||
|
|
||||||
FileUtils.mkdir_p HOMEBREW_PREFIX/"lib"
|
|
||||||
FileUtils.ln_sf ld_so, brew_ld_so
|
|
||||||
end
|
|
||||||
private_class_method :symlink_ld_so
|
|
||||||
|
|
||||||
def self.setup_preferred_gcc_libs
|
|
||||||
gcc_opt_prefix = HOMEBREW_PREFIX/"opt/#{OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA}"
|
|
||||||
glibc_installed = (HOMEBREW_PREFIX/"opt/glibc/bin/ld.so").readable?
|
|
||||||
|
|
||||||
return unless gcc_opt_prefix.readable?
|
|
||||||
|
|
||||||
if glibc_installed
|
|
||||||
ld_so_conf_d = HOMEBREW_PREFIX/"etc/ld.so.conf.d"
|
|
||||||
unless ld_so_conf_d.exist?
|
|
||||||
ld_so_conf_d.mkpath
|
|
||||||
FileUtils.chmod "go-w", ld_so_conf_d
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add gcc to ld search paths
|
def global_post_install
|
||||||
ld_gcc_conf = ld_so_conf_d/"50-homebrew-preferred-gcc.conf"
|
super
|
||||||
ld_gcc_conf_content = <<~EOS
|
symlink_ld_so
|
||||||
# This file is generated by Homebrew. Do not modify.
|
setup_preferred_gcc_libs
|
||||||
#{gcc_opt_prefix}/lib/gcc/current
|
|
||||||
EOS
|
|
||||||
|
|
||||||
if !ld_gcc_conf.exist? || (ld_gcc_conf.read != ld_gcc_conf_content)
|
|
||||||
ld_gcc_conf.atomic_write ld_gcc_conf_content
|
|
||||||
FileUtils.chmod "u=rw,go-wx", ld_gcc_conf
|
|
||||||
|
|
||||||
FileUtils.rm_f HOMEBREW_PREFIX/"etc/ld.so.cache"
|
|
||||||
system HOMEBREW_PREFIX/"opt/glibc/sbin/ldconfig"
|
|
||||||
end
|
end
|
||||||
else
|
|
||||||
odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable?
|
|
||||||
end
|
|
||||||
|
|
||||||
GCC_RUNTIME_LIBS.each do |library|
|
def check_cpu
|
||||||
gcc_library_symlink = HOMEBREW_PREFIX/"lib/#{library}"
|
return if ::Hardware::CPU.intel? && ::Hardware::CPU.is_64_bit?
|
||||||
|
return if ::Hardware::CPU.arm?
|
||||||
|
|
||||||
if glibc_installed
|
message = "Sorry, Homebrew does not support your computer's CPU architecture!"
|
||||||
# Remove legacy symlinks
|
if ::Hardware::CPU.ppc64le?
|
||||||
FileUtils.rm gcc_library_symlink if gcc_library_symlink.symlink?
|
message += <<~EOS
|
||||||
else
|
For OpenPOWER Linux (PPC64LE) support, see:
|
||||||
gcc_library = gcc_opt_prefix/"lib/gcc/current/#{library}"
|
#{Formatter.url("https://github.com/homebrew-ppc64le/brew")}
|
||||||
# Skip if the link target doesn't exist.
|
EOS
|
||||||
next unless gcc_library.readable?
|
end
|
||||||
|
::Kernel.abort message
|
||||||
|
end
|
||||||
|
|
||||||
# Also skip if the symlink already exists.
|
def symlink_ld_so
|
||||||
next if gcc_library_symlink.readable? && (gcc_library_symlink.readlink == gcc_library)
|
brew_ld_so = HOMEBREW_PREFIX/"lib/ld.so"
|
||||||
|
|
||||||
FileUtils.ln_sf gcc_library, gcc_library_symlink
|
ld_so = HOMEBREW_PREFIX/"opt/glibc/bin/ld.so"
|
||||||
|
unless ld_so.readable?
|
||||||
|
ld_so = DYNAMIC_LINKERS.find { |s| File.executable? s }
|
||||||
|
if ld_so.blank?
|
||||||
|
::Kernel.raise "Unable to locate the system's dynamic linker" unless brew_ld_so.readable?
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return if brew_ld_so.readable? && (brew_ld_so.readlink == ld_so)
|
||||||
|
|
||||||
|
FileUtils.mkdir_p HOMEBREW_PREFIX/"lib"
|
||||||
|
FileUtils.ln_sf ld_so, brew_ld_so
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_preferred_gcc_libs
|
||||||
|
gcc_opt_prefix = HOMEBREW_PREFIX/"opt/#{OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA}"
|
||||||
|
glibc_installed = (HOMEBREW_PREFIX/"opt/glibc/bin/ld.so").readable?
|
||||||
|
|
||||||
|
return unless gcc_opt_prefix.readable?
|
||||||
|
|
||||||
|
if glibc_installed
|
||||||
|
ld_so_conf_d = HOMEBREW_PREFIX/"etc/ld.so.conf.d"
|
||||||
|
unless ld_so_conf_d.exist?
|
||||||
|
ld_so_conf_d.mkpath
|
||||||
|
FileUtils.chmod "go-w", ld_so_conf_d
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add gcc to ld search paths
|
||||||
|
ld_gcc_conf = ld_so_conf_d/"50-homebrew-preferred-gcc.conf"
|
||||||
|
ld_gcc_conf_content = <<~EOS
|
||||||
|
# This file is generated by Homebrew. Do not modify.
|
||||||
|
#{gcc_opt_prefix}/lib/gcc/current
|
||||||
|
EOS
|
||||||
|
|
||||||
|
if !ld_gcc_conf.exist? || (ld_gcc_conf.read != ld_gcc_conf_content)
|
||||||
|
ld_gcc_conf.atomic_write ld_gcc_conf_content
|
||||||
|
FileUtils.chmod "u=rw,go-wx", ld_gcc_conf
|
||||||
|
|
||||||
|
FileUtils.rm_f HOMEBREW_PREFIX/"etc/ld.so.cache"
|
||||||
|
::Kernel.system HOMEBREW_PREFIX/"opt/glibc/sbin/ldconfig"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
::Kernel.odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable?
|
||||||
|
end
|
||||||
|
|
||||||
|
GCC_RUNTIME_LIBS.each do |library|
|
||||||
|
gcc_library_symlink = HOMEBREW_PREFIX/"lib/#{library}"
|
||||||
|
|
||||||
|
if glibc_installed
|
||||||
|
# Remove legacy symlinks
|
||||||
|
FileUtils.rm gcc_library_symlink if gcc_library_symlink.symlink?
|
||||||
|
else
|
||||||
|
gcc_library = gcc_opt_prefix/"lib/gcc/current/#{library}"
|
||||||
|
# Skip if the link target doesn't exist.
|
||||||
|
next unless gcc_library.readable?
|
||||||
|
|
||||||
|
# Also skip if the symlink already exists.
|
||||||
|
next if gcc_library_symlink.readable? && (gcc_library_symlink.readlink == gcc_library)
|
||||||
|
|
||||||
|
FileUtils.ln_sf gcc_library, gcc_library_symlink
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private_class_method :setup_preferred_gcc_libs
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Homebrew::Install.singleton_class.prepend(OS::Linux::Install::ClassMethods)
|
||||||
|
@ -3,48 +3,55 @@
|
|||||||
|
|
||||||
require "compilers"
|
require "compilers"
|
||||||
|
|
||||||
class LinkageChecker
|
module OS
|
||||||
# Libraries provided by glibc and gcc.
|
module Linux
|
||||||
SYSTEM_LIBRARY_ALLOWLIST = %w[
|
module LinkageChecker
|
||||||
ld-linux-x86-64.so.2
|
# Libraries provided by glibc and gcc.
|
||||||
ld-linux-aarch64.so.1
|
SYSTEM_LIBRARY_ALLOWLIST = %w[
|
||||||
libanl.so.1
|
ld-linux-x86-64.so.2
|
||||||
libatomic.so.1
|
ld-linux-aarch64.so.1
|
||||||
libc.so.6
|
libanl.so.1
|
||||||
libdl.so.2
|
libatomic.so.1
|
||||||
libm.so.6
|
libc.so.6
|
||||||
libmvec.so.1
|
libdl.so.2
|
||||||
libnss_files.so.2
|
libm.so.6
|
||||||
libpthread.so.0
|
libmvec.so.1
|
||||||
libresolv.so.2
|
libnss_files.so.2
|
||||||
librt.so.1
|
libpthread.so.0
|
||||||
libthread_db.so.1
|
libresolv.so.2
|
||||||
libutil.so.1
|
librt.so.1
|
||||||
libgcc_s.so.1
|
libthread_db.so.1
|
||||||
libgomp.so.1
|
libutil.so.1
|
||||||
libstdc++.so.6
|
libgcc_s.so.1
|
||||||
libquadmath.so.0
|
libgomp.so.1
|
||||||
].freeze
|
libstdc++.so.6
|
||||||
|
libquadmath.so.0
|
||||||
|
].freeze
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_dylibs(rebuild_cache:)
|
def check_dylibs(rebuild_cache:)
|
||||||
generic_check_dylibs(rebuild_cache:)
|
super
|
||||||
|
|
||||||
# glibc and gcc are implicit dependencies.
|
# glibc and gcc are implicit dependencies.
|
||||||
# No other linkage to system libraries is expected or desired.
|
# No other linkage to system libraries is expected or desired.
|
||||||
@unwanted_system_dylibs = @system_dylibs.reject do |s|
|
@unwanted_system_dylibs = @system_dylibs.reject do |s|
|
||||||
SYSTEM_LIBRARY_ALLOWLIST.include? File.basename(s)
|
SYSTEM_LIBRARY_ALLOWLIST.include? File.basename(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
# We build all formulae with an RPATH that includes the gcc formula's runtime lib directory.
|
||||||
|
# See: https://github.com/Homebrew/brew/blob/e689cc07/Library/Homebrew/extend/os/linux/extend/ENV/super.rb#L53
|
||||||
|
# This results in formulae showing linkage with gcc whenever it is installed, even if no dependency is
|
||||||
|
# declared.
|
||||||
|
# See discussions at:
|
||||||
|
# https://github.com/Homebrew/brew/pull/13659
|
||||||
|
# https://github.com/Homebrew/brew/pull/13796
|
||||||
|
# TODO: Find a nicer way to handle this. (e.g. examining the ELF file to determine the required libstdc++.)
|
||||||
|
@undeclared_deps.delete("gcc")
|
||||||
|
@indirect_deps.delete("gcc")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# We build all formulae with an RPATH that includes the gcc formula's runtime lib directory.
|
|
||||||
# See: https://github.com/Homebrew/brew/blob/e689cc07/Library/Homebrew/extend/os/linux/extend/ENV/super.rb#L53
|
|
||||||
# This results in formulae showing linkage with gcc whenever it is installed, even if no dependency is declared.
|
|
||||||
# See discussions at:
|
|
||||||
# https://github.com/Homebrew/brew/pull/13659
|
|
||||||
# https://github.com/Homebrew/brew/pull/13796
|
|
||||||
# TODO: Find a nicer way to handle this. (e.g. examining the ELF file to determine the required libstdc++.)
|
|
||||||
@undeclared_deps.delete("gcc")
|
|
||||||
@indirect_deps.delete("gcc")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LinkageChecker.prepend(OS::Linux::LinkageChecker)
|
||||||
|
@ -5,53 +5,59 @@ require "compilers"
|
|||||||
require "os/linux/glibc"
|
require "os/linux/glibc"
|
||||||
require "system_command"
|
require "system_command"
|
||||||
|
|
||||||
module SystemConfig
|
module OS
|
||||||
include SystemCommand::Mixin
|
module Linux
|
||||||
|
module SystemConfig
|
||||||
|
module ClassMethods
|
||||||
|
include SystemCommand::Mixin
|
||||||
|
|
||||||
HOST_RUBY_PATH = "/usr/bin/ruby"
|
HOST_RUBY_PATH = "/usr/bin/ruby"
|
||||||
|
|
||||||
class << self
|
def host_glibc_version
|
||||||
def host_glibc_version
|
version = OS::Linux::Glibc.system_version
|
||||||
version = OS::Linux::Glibc.system_version
|
return "N/A" if version.null?
|
||||||
return "N/A" if version.null?
|
|
||||||
|
|
||||||
version
|
version
|
||||||
end
|
end
|
||||||
|
|
||||||
def host_gcc_version
|
def host_gcc_version
|
||||||
gcc = DevelopmentTools.host_gcc_path
|
gcc = ::DevelopmentTools.host_gcc_path
|
||||||
return "N/A" unless gcc.executable?
|
return "N/A" unless gcc.executable?
|
||||||
|
|
||||||
`#{gcc} --version 2>/dev/null`[/ (\d+\.\d+\.\d+)/, 1]
|
Utils.popen_read(gcc, "--version")[/ (\d+\.\d+\.\d+)/, 1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def formula_linked_version(formula)
|
def formula_linked_version(formula)
|
||||||
return "N/A" if Homebrew::EnvConfig.no_install_from_api? && !CoreTap.instance.installed?
|
return "N/A" if Homebrew::EnvConfig.no_install_from_api? && !CoreTap.instance.installed?
|
||||||
|
|
||||||
Formulary.factory(formula).any_installed_version || "N/A"
|
Formulary.factory(formula).any_installed_version || "N/A"
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
"N/A"
|
"N/A"
|
||||||
end
|
end
|
||||||
|
|
||||||
def host_ruby_version
|
def host_ruby_version
|
||||||
out, _, status = system_command(HOST_RUBY_PATH, args: ["-e", "puts RUBY_VERSION"], print_stderr: false)
|
out, _, status = system_command(HOST_RUBY_PATH, args: ["-e", "puts RUBY_VERSION"], print_stderr: false)
|
||||||
return "N/A" unless status.success?
|
return "N/A" unless status.success?
|
||||||
|
|
||||||
out
|
out
|
||||||
end
|
end
|
||||||
|
|
||||||
def dump_verbose_config(out = $stdout)
|
def dump_verbose_config(out = $stdout)
|
||||||
kernel = Utils.safe_popen_read("uname", "-mors").chomp
|
kernel = Utils.safe_popen_read("uname", "-mors").chomp
|
||||||
dump_generic_verbose_config(out)
|
super
|
||||||
out.puts "Kernel: #{kernel}"
|
out.puts "Kernel: #{kernel}"
|
||||||
out.puts "OS: #{OS::Linux.os_version}"
|
out.puts "OS: #{OS::Linux.os_version}"
|
||||||
out.puts "WSL: #{OS::Linux.wsl_version}" if OS::Linux.wsl?
|
out.puts "WSL: #{OS::Linux.wsl_version}" if OS::Linux.wsl?
|
||||||
out.puts "Host glibc: #{host_glibc_version}"
|
out.puts "Host glibc: #{host_glibc_version}"
|
||||||
out.puts "#{DevelopmentTools.host_gcc_path}: #{host_gcc_version}"
|
out.puts "#{::DevelopmentTools.host_gcc_path}: #{host_gcc_version}"
|
||||||
out.puts "/usr/bin/ruby: #{host_ruby_version}" if RUBY_PATH != HOST_RUBY_PATH
|
out.puts "/usr/bin/ruby: #{host_ruby_version}" if RUBY_PATH != HOST_RUBY_PATH
|
||||||
["glibc", CompilerSelector.preferred_gcc, OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA, "xorg"].each do |f|
|
["glibc", CompilerSelector.preferred_gcc, OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA, "xorg"].each do |f|
|
||||||
out.puts "#{f}: #{formula_linked_version(f)}"
|
out.puts "#{f}: #{formula_linked_version(f)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SystemConfig.singleton_class.prepend(OS::Linux::SystemConfig::ClassMethods)
|
||||||
|
@ -15,6 +15,11 @@ module OS
|
|||||||
def os_bundle_args(bundle_args)
|
def os_bundle_args(bundle_args)
|
||||||
non_linux_bundle_args(bundle_args)
|
non_linux_bundle_args(bundle_args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(files: T::Array[String]).returns(T::Array[String]) }
|
||||||
|
def os_files(files)
|
||||||
|
non_linux_files(files)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,42 +1,50 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module SharedEnvExtension
|
module OS
|
||||||
sig {
|
module Mac
|
||||||
params(
|
module SharedEnvExtension
|
||||||
formula: T.nilable(Formula),
|
extend T::Helpers
|
||||||
cc: T.nilable(String),
|
|
||||||
build_bottle: T.nilable(T::Boolean),
|
|
||||||
bottle_arch: T.nilable(String),
|
|
||||||
testing_formula: T::Boolean,
|
|
||||||
debug_symbols: T.nilable(T::Boolean),
|
|
||||||
).void
|
|
||||||
}
|
|
||||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
|
||||||
debug_symbols: false)
|
|
||||||
generic_shared_setup_build_environment(formula:, cc:, build_bottle:,
|
|
||||||
bottle_arch:, testing_formula:,
|
|
||||||
debug_symbols:)
|
|
||||||
|
|
||||||
# Normalise the system Perl version used, where multiple may be available
|
requires_ancestor { ::SharedEnvExtension }
|
||||||
self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig {
|
||||||
def no_weak_imports_support?
|
params(
|
||||||
return false if compiler != :clang
|
formula: T.nilable(::Formula),
|
||||||
|
cc: T.nilable(String),
|
||||||
|
build_bottle: T.nilable(T::Boolean),
|
||||||
|
bottle_arch: T.nilable(String),
|
||||||
|
testing_formula: T::Boolean,
|
||||||
|
debug_symbols: T.nilable(T::Boolean),
|
||||||
|
).void
|
||||||
|
}
|
||||||
|
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil,
|
||||||
|
testing_formula: false, debug_symbols: false)
|
||||||
|
super
|
||||||
|
|
||||||
return false if !MacOS::Xcode.version.null? && MacOS::Xcode.version < "8.0"
|
# Normalise the system Perl version used, where multiple may be available
|
||||||
return false if !MacOS::CLT.version.null? && MacOS::CLT.version < "8.0"
|
self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version
|
||||||
|
end
|
||||||
|
|
||||||
true
|
sig { returns(T::Boolean) }
|
||||||
end
|
def no_weak_imports_support?
|
||||||
|
return false if compiler != :clang
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
return false if !MacOS::Xcode.version.null? && MacOS::Xcode.version < "8.0"
|
||||||
def no_fixup_chains_support?
|
return false if !MacOS::CLT.version.null? && MacOS::CLT.version < "8.0"
|
||||||
# This is supported starting Xcode 13, which ships ld64-711.
|
|
||||||
# https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes
|
true
|
||||||
# https://en.wikipedia.org/wiki/Xcode#Xcode_11.0_-_14.x_(since_SwiftUI_framework)_2
|
end
|
||||||
OS::Mac::DevelopmentTools.ld64_version >= 711
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def no_fixup_chains_support?
|
||||||
|
# This is supported starting Xcode 13, which ships ld64-711.
|
||||||
|
# https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes
|
||||||
|
# https://en.wikipedia.org/wiki/Xcode#Xcode_11.0_-_14.x_(since_SwiftUI_framework)_2
|
||||||
|
OS::Mac::DevelopmentTools.ld64_version >= 711
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SharedEnvExtension.prepend(OS::Mac::SharedEnvExtension)
|
||||||
|
@ -1,117 +1,125 @@
|
|||||||
# typed: true # rubocop:disable Sorbet/StrictSigil
|
# typed: true # rubocop:disable Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Stdenv
|
module OS
|
||||||
undef homebrew_extra_pkg_config_paths
|
module Mac
|
||||||
|
module Stdenv
|
||||||
|
extend T::Helpers
|
||||||
|
|
||||||
sig { returns(T::Array[Pathname]) }
|
requires_ancestor { SharedEnvExtension }
|
||||||
def homebrew_extra_pkg_config_paths
|
requires_ancestor { ::Stdenv }
|
||||||
[Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
|
||||||
end
|
|
||||||
private :homebrew_extra_pkg_config_paths
|
|
||||||
|
|
||||||
sig {
|
sig { returns(T::Array[Pathname]) }
|
||||||
params(
|
def homebrew_extra_pkg_config_paths
|
||||||
formula: T.nilable(Formula),
|
[Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
||||||
cc: T.nilable(String),
|
end
|
||||||
build_bottle: T.nilable(T::Boolean),
|
private :homebrew_extra_pkg_config_paths
|
||||||
bottle_arch: T.nilable(String),
|
|
||||||
testing_formula: T::Boolean,
|
|
||||||
debug_symbols: T.nilable(T::Boolean),
|
|
||||||
).void
|
|
||||||
}
|
|
||||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
|
||||||
debug_symbols: false)
|
|
||||||
generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:,
|
|
||||||
testing_formula:, debug_symbols:)
|
|
||||||
|
|
||||||
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
sig {
|
||||||
|
params(
|
||||||
|
formula: T.nilable(Formula),
|
||||||
|
cc: T.nilable(String),
|
||||||
|
build_bottle: T.nilable(T::Boolean),
|
||||||
|
bottle_arch: T.nilable(String),
|
||||||
|
testing_formula: T::Boolean,
|
||||||
|
debug_symbols: T.nilable(T::Boolean),
|
||||||
|
).void
|
||||||
|
}
|
||||||
|
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil,
|
||||||
|
testing_formula: false, debug_symbols: false)
|
||||||
|
super
|
||||||
|
|
||||||
# `sed` is strict and errors out when it encounters files with mixed character sets.
|
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
||||||
delete("LC_ALL")
|
|
||||||
self["LC_CTYPE"] = "C"
|
|
||||||
|
|
||||||
# Add `lib` and `include` etc. from the current `macosxsdk` to compiler flags:
|
# `sed` is strict and errors out when it encounters files with mixed character sets.
|
||||||
macosxsdk(formula: @formula, testing_formula:)
|
delete("LC_ALL")
|
||||||
|
self["LC_CTYPE"] = "C"
|
||||||
|
|
||||||
return unless MacOS::Xcode.without_clt?
|
# Add `lib` and `include` etc. from the current `macosxsdk` to compiler flags:
|
||||||
|
macosxsdk(formula: @formula, testing_formula:)
|
||||||
|
|
||||||
append_path "PATH", "#{MacOS::Xcode.prefix}/usr/bin"
|
return unless MacOS::Xcode.without_clt?
|
||||||
append_path "PATH", "#{MacOS::Xcode.toolchain_path}/usr/bin"
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_macosxsdk(version = nil)
|
append_path "PATH", "#{MacOS::Xcode.prefix}/usr/bin"
|
||||||
# Clear all `lib` and `include` dirs from `CFLAGS`, `CPPFLAGS`, `LDFLAGS` that were
|
append_path "PATH", "#{MacOS::Xcode.toolchain_path}/usr/bin"
|
||||||
# previously added by `macosxsdk`.
|
end
|
||||||
remove_from_cflags(/ ?-mmacosx-version-min=\d+\.\d+/)
|
|
||||||
delete("CPATH")
|
|
||||||
remove "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
|
||||||
|
|
||||||
sdk = self["SDKROOT"] || MacOS.sdk_path_if_needed(version)
|
def remove_macosxsdk(version = nil)
|
||||||
return unless sdk
|
# Clear all `lib` and `include` dirs from `CFLAGS`, `CPPFLAGS`, `LDFLAGS` that were
|
||||||
|
# previously added by `macosxsdk`.
|
||||||
|
remove_from_cflags(/ ?-mmacosx-version-min=\d+\.\d+/)
|
||||||
|
delete("CPATH")
|
||||||
|
remove "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
||||||
|
|
||||||
delete("SDKROOT")
|
sdk = self["SDKROOT"] || MacOS.sdk_path_if_needed(version)
|
||||||
remove_from_cflags "-isysroot#{sdk}"
|
return unless sdk
|
||||||
remove "CPPFLAGS", "-isysroot#{sdk}"
|
|
||||||
remove "LDFLAGS", "-isysroot#{sdk}"
|
delete("SDKROOT")
|
||||||
if HOMEBREW_PREFIX.to_s == "/usr/local"
|
remove_from_cflags "-isysroot#{sdk}"
|
||||||
delete("CMAKE_PREFIX_PATH")
|
remove "CPPFLAGS", "-isysroot#{sdk}"
|
||||||
else
|
remove "LDFLAGS", "-isysroot#{sdk}"
|
||||||
# It was set in `setup_build_environment`, so we have to restore it here.
|
if HOMEBREW_PREFIX.to_s == "/usr/local"
|
||||||
self["CMAKE_PREFIX_PATH"] = HOMEBREW_PREFIX.to_s
|
delete("CMAKE_PREFIX_PATH")
|
||||||
|
else
|
||||||
|
# It was set in `setup_build_environment`, so we have to restore it here.
|
||||||
|
self["CMAKE_PREFIX_PATH"] = HOMEBREW_PREFIX.to_s
|
||||||
|
end
|
||||||
|
remove "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
||||||
|
end
|
||||||
|
|
||||||
|
def macosxsdk(version = nil, formula: nil, testing_formula: false)
|
||||||
|
# Sets all needed `lib` and `include` dirs to `CFLAGS`, `CPPFLAGS`, `LDFLAGS`.
|
||||||
|
remove_macosxsdk
|
||||||
|
min_version = version || MacOS.version
|
||||||
|
append_to_cflags("-mmacosx-version-min=#{min_version}")
|
||||||
|
self["CPATH"] = "#{HOMEBREW_PREFIX}/include"
|
||||||
|
prepend "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
||||||
|
|
||||||
|
sdk = if formula
|
||||||
|
MacOS.sdk_for_formula(formula, version, check_only_runtime_requirements: testing_formula)
|
||||||
|
else
|
||||||
|
MacOS.sdk(version)
|
||||||
|
end
|
||||||
|
return if !MacOS.sdk_root_needed? && sdk&.source != :xcode
|
||||||
|
|
||||||
|
Homebrew::Diagnostic.checks(:fatal_setup_build_environment_checks)
|
||||||
|
sdk = sdk.path
|
||||||
|
|
||||||
|
# Extra setup to support Xcode 4.3+ without CLT.
|
||||||
|
self["SDKROOT"] = sdk
|
||||||
|
# Tell clang/gcc where system include's are:
|
||||||
|
append_path "CPATH", "#{sdk}/usr/include"
|
||||||
|
# The -isysroot is needed, too, because of the Frameworks
|
||||||
|
append_to_cflags "-isysroot#{sdk}"
|
||||||
|
append "CPPFLAGS", "-isysroot#{sdk}"
|
||||||
|
# And the linker needs to find sdk/usr/lib
|
||||||
|
append "LDFLAGS", "-isysroot#{sdk}"
|
||||||
|
# Needed to build cmake itself and perhaps some cmake projects:
|
||||||
|
append_path "CMAKE_PREFIX_PATH", "#{sdk}/usr"
|
||||||
|
append_path "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Some configure scripts won't find libxml2 without help.
|
||||||
|
# This is a no-op with macOS SDK 10.15.4 and later.
|
||||||
|
def libxml2
|
||||||
|
sdk = self["SDKROOT"] || MacOS.sdk_path_if_needed
|
||||||
|
if !sdk
|
||||||
|
append "CPPFLAGS", "-I/usr/include/libxml2"
|
||||||
|
elsif !Pathname("#{sdk}/usr/include/libxml").directory?
|
||||||
|
# Use the includes form the sdk
|
||||||
|
append "CPPFLAGS", "-I#{sdk}/usr/include/libxml2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_weak_imports
|
||||||
|
append "LDFLAGS", "-Wl,-no_weak_imports" if no_weak_imports_support?
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_fixup_chains
|
||||||
|
append "LDFLAGS", "-Wl,-no_fixup_chains" if no_fixup_chains_support?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
remove "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
|
||||||
end
|
|
||||||
|
|
||||||
def macosxsdk(version = nil, formula: nil, testing_formula: false)
|
|
||||||
# Sets all needed `lib` and `include` dirs to `CFLAGS`, `CPPFLAGS`, `LDFLAGS`.
|
|
||||||
remove_macosxsdk
|
|
||||||
min_version = version || MacOS.version
|
|
||||||
append_to_cflags("-mmacosx-version-min=#{min_version}")
|
|
||||||
self["CPATH"] = "#{HOMEBREW_PREFIX}/include"
|
|
||||||
prepend "LDFLAGS", "-L#{HOMEBREW_PREFIX}/lib"
|
|
||||||
|
|
||||||
sdk = if formula
|
|
||||||
MacOS.sdk_for_formula(formula, version, check_only_runtime_requirements: testing_formula)
|
|
||||||
else
|
|
||||||
MacOS.sdk(version)
|
|
||||||
end
|
|
||||||
return if !MacOS.sdk_root_needed? && sdk&.source != :xcode
|
|
||||||
|
|
||||||
Homebrew::Diagnostic.checks(:fatal_setup_build_environment_checks)
|
|
||||||
sdk = sdk.path
|
|
||||||
|
|
||||||
# Extra setup to support Xcode 4.3+ without CLT.
|
|
||||||
self["SDKROOT"] = sdk
|
|
||||||
# Tell clang/gcc where system include's are:
|
|
||||||
append_path "CPATH", "#{sdk}/usr/include"
|
|
||||||
# The -isysroot is needed, too, because of the Frameworks
|
|
||||||
append_to_cflags "-isysroot#{sdk}"
|
|
||||||
append "CPPFLAGS", "-isysroot#{sdk}"
|
|
||||||
# And the linker needs to find sdk/usr/lib
|
|
||||||
append "LDFLAGS", "-isysroot#{sdk}"
|
|
||||||
# Needed to build cmake itself and perhaps some cmake projects:
|
|
||||||
append_path "CMAKE_PREFIX_PATH", "#{sdk}/usr"
|
|
||||||
append_path "CMAKE_FRAMEWORK_PATH", "#{sdk}/System/Library/Frameworks"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Some configure scripts won't find libxml2 without help.
|
|
||||||
# This is a no-op with macOS SDK 10.15.4 and later.
|
|
||||||
def libxml2
|
|
||||||
sdk = self["SDKROOT"] || MacOS.sdk_path_if_needed
|
|
||||||
if !sdk
|
|
||||||
append "CPPFLAGS", "-I/usr/include/libxml2"
|
|
||||||
elsif !Pathname("#{sdk}/usr/include/libxml").directory?
|
|
||||||
# Use the includes form the sdk
|
|
||||||
append "CPPFLAGS", "-I#{sdk}/usr/include/libxml2"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def no_weak_imports
|
|
||||||
append "LDFLAGS", "-Wl,-no_weak_imports" if no_weak_imports_support?
|
|
||||||
end
|
|
||||||
|
|
||||||
def no_fixup_chains
|
|
||||||
append "LDFLAGS", "-Wl,-no_fixup_chains" if no_fixup_chains_support?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Stdenv.prepend(OS::Mac::Stdenv)
|
||||||
|
@ -1,171 +1,173 @@
|
|||||||
# typed: true # rubocop:disable Sorbet/StrictSigil
|
# typed: true # rubocop:disable Sorbet/StrictSigil
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Superenv
|
module OS
|
||||||
class << self
|
module Mac
|
||||||
# The location of Homebrew's shims on macOS.
|
module Superenv
|
||||||
def shims_path
|
extend T::Helpers
|
||||||
HOMEBREW_SHIMS_PATH/"mac/super"
|
|
||||||
end
|
|
||||||
|
|
||||||
undef bin
|
requires_ancestor { SharedEnvExtension }
|
||||||
|
requires_ancestor { ::Superenv }
|
||||||
|
|
||||||
def bin
|
module ClassMethods
|
||||||
return unless DevelopmentTools.installed?
|
sig { returns(Pathname) }
|
||||||
|
def shims_path
|
||||||
|
HOMEBREW_SHIMS_PATH/"mac/super"
|
||||||
|
end
|
||||||
|
|
||||||
shims_path.realpath
|
sig { returns(T.nilable(Pathname)) }
|
||||||
end
|
def bin
|
||||||
end
|
return unless ::DevelopmentTools.installed?
|
||||||
|
|
||||||
undef homebrew_extra_pkg_config_paths,
|
shims_path.realpath
|
||||||
homebrew_extra_isystem_paths, homebrew_extra_library_paths,
|
end
|
||||||
homebrew_extra_cmake_include_paths,
|
|
||||||
homebrew_extra_cmake_library_paths,
|
|
||||||
homebrew_extra_cmake_frameworks_paths,
|
|
||||||
determine_cccfg
|
|
||||||
|
|
||||||
sig { returns(T::Array[Pathname]) }
|
|
||||||
def homebrew_extra_pkg_config_paths
|
|
||||||
[Pathname("/usr/lib/pkgconfig"), Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
|
||||||
end
|
|
||||||
private :homebrew_extra_pkg_config_paths
|
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
|
||||||
def libxml2_include_needed?
|
|
||||||
return false if deps.any? { |d| d.name == "libxml2" }
|
|
||||||
return false if Pathname("#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml").directory?
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
|
||||||
private :libxml2_include_needed?
|
|
||||||
|
|
||||||
def homebrew_extra_isystem_paths
|
|
||||||
paths = []
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml2" if libxml2_include_needed?
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/apache2" if MacOS::Xcode.without_clt?
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def homebrew_extra_library_paths
|
|
||||||
paths = []
|
|
||||||
if compiler == :llvm_clang
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/lib"
|
|
||||||
paths << Formula["llvm"].opt_lib.to_s
|
|
||||||
end
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def homebrew_extra_cmake_include_paths
|
|
||||||
paths = []
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml2" if libxml2_include_needed?
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/apache2" if MacOS::Xcode.without_clt?
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def homebrew_extra_cmake_library_paths
|
|
||||||
[Pathname("#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries")]
|
|
||||||
end
|
|
||||||
|
|
||||||
def homebrew_extra_cmake_frameworks_paths
|
|
||||||
paths = []
|
|
||||||
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks" if MacOS::Xcode.without_clt?
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def determine_cccfg
|
|
||||||
s = +""
|
|
||||||
# Fix issue with >= Mountain Lion apr-1-config having broken paths
|
|
||||||
s << "a"
|
|
||||||
s.freeze
|
|
||||||
end
|
|
||||||
|
|
||||||
# @private
|
|
||||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
|
||||||
debug_symbols: false)
|
|
||||||
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
|
|
||||||
is_xcode_sdk = sdk&.source == :xcode
|
|
||||||
|
|
||||||
if is_xcode_sdk || MacOS.sdk_root_needed?
|
|
||||||
Homebrew::Diagnostic.checks(:fatal_setup_build_environment_checks)
|
|
||||||
self["HOMEBREW_SDKROOT"] = sdk.path if sdk
|
|
||||||
end
|
|
||||||
|
|
||||||
self["HOMEBREW_DEVELOPER_DIR"] = if is_xcode_sdk
|
|
||||||
MacOS::Xcode.prefix.to_s
|
|
||||||
else
|
|
||||||
MacOS::CLT::PKG_PATH
|
|
||||||
end
|
|
||||||
|
|
||||||
# This is a workaround for the missing `m4` in Xcode CLT 15.3, which was
|
|
||||||
# reported in FB13679972. Apple has fixed this in Xcode CLT 16.0.
|
|
||||||
# See https://github.com/Homebrew/homebrew-core/issues/165388
|
|
||||||
if deps.none? { |d| d.name == "m4" } &&
|
|
||||||
MacOS.active_developer_dir == MacOS::CLT::PKG_PATH &&
|
|
||||||
!File.exist?("#{MacOS::CLT::PKG_PATH}/usr/bin/m4") &&
|
|
||||||
(gm4 = DevelopmentTools.locate("gm4").to_s).present?
|
|
||||||
self["M4"] = gm4
|
|
||||||
end
|
|
||||||
|
|
||||||
generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:,
|
|
||||||
testing_formula:, debug_symbols:)
|
|
||||||
|
|
||||||
# Filter out symbols known not to be defined since GNU Autotools can't
|
|
||||||
# reliably figure this out with Xcode 8 and above.
|
|
||||||
if MacOS.version == "10.12" && MacOS::Xcode.version >= "9.0"
|
|
||||||
%w[fmemopen futimens open_memstream utimensat].each do |s|
|
|
||||||
ENV["ac_cv_func_#{s}"] = "no"
|
|
||||||
end
|
|
||||||
elsif MacOS.version == "10.11" && MacOS::Xcode.version >= "8.0"
|
|
||||||
%w[basename_r clock_getres clock_gettime clock_settime dirname_r
|
|
||||||
getentropy mkostemp mkostemps timingsafe_bcmp].each do |s|
|
|
||||||
ENV["ac_cv_func_#{s}"] = "no"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
ENV["ac_cv_search_clock_gettime"] = "no"
|
sig { returns(T::Array[Pathname]) }
|
||||||
|
def homebrew_extra_pkg_config_paths
|
||||||
|
[Pathname("/usr/lib/pkgconfig"), Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
||||||
|
end
|
||||||
|
|
||||||
# works around libev.m4 unsetting ac_cv_func_clock_gettime
|
sig { returns(T::Boolean) }
|
||||||
ENV["ac_have_clock_syscall"] = "no"
|
def libxml2_include_needed?
|
||||||
|
return false if deps.any? { |d| d.name == "libxml2" }
|
||||||
|
return false if Pathname("#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml").directory?
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_isystem_paths
|
||||||
|
paths = []
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml2" if libxml2_include_needed?
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/apache2" if MacOS::Xcode.without_clt?
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_library_paths
|
||||||
|
paths = []
|
||||||
|
if compiler == :llvm_clang
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/lib"
|
||||||
|
paths << ::Formula["llvm"].opt_lib.to_s
|
||||||
|
end
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_cmake_include_paths
|
||||||
|
paths = []
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml2" if libxml2_include_needed?
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/usr/include/apache2" if MacOS::Xcode.without_clt?
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_cmake_library_paths
|
||||||
|
brew_sdkroot = self["HOMEBREW_SDKROOT"]
|
||||||
|
[Pathname("#{brew_sdkroot}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries")]
|
||||||
|
end
|
||||||
|
|
||||||
|
def homebrew_extra_cmake_frameworks_paths
|
||||||
|
paths = []
|
||||||
|
paths << "#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks" if MacOS::Xcode.without_clt?
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def determine_cccfg
|
||||||
|
s = +""
|
||||||
|
# Fix issue with >= Mountain Lion apr-1-config having broken paths
|
||||||
|
s << "a"
|
||||||
|
s.freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
# @private
|
||||||
|
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil,
|
||||||
|
testing_formula: false, debug_symbols: false)
|
||||||
|
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
|
||||||
|
is_xcode_sdk = sdk&.source == :xcode
|
||||||
|
|
||||||
|
if is_xcode_sdk || MacOS.sdk_root_needed?
|
||||||
|
Homebrew::Diagnostic.checks(:fatal_setup_build_environment_checks)
|
||||||
|
self["HOMEBREW_SDKROOT"] = sdk.path if sdk
|
||||||
|
end
|
||||||
|
|
||||||
|
self["HOMEBREW_DEVELOPER_DIR"] = if is_xcode_sdk
|
||||||
|
MacOS::Xcode.prefix.to_s
|
||||||
|
else
|
||||||
|
MacOS::CLT::PKG_PATH
|
||||||
|
end
|
||||||
|
|
||||||
|
# This is a workaround for the missing `m4` in Xcode CLT 15.3, which was
|
||||||
|
# reported in FB13679972. Apple has fixed this in Xcode CLT 16.0.
|
||||||
|
# See https://github.com/Homebrew/homebrew-core/issues/165388
|
||||||
|
if deps.none? { |d| d.name == "m4" } &&
|
||||||
|
MacOS.active_developer_dir == MacOS::CLT::PKG_PATH &&
|
||||||
|
!File.exist?("#{MacOS::CLT::PKG_PATH}/usr/bin/m4") &&
|
||||||
|
(gm4 = ::DevelopmentTools.locate("gm4").to_s).present?
|
||||||
|
self["M4"] = gm4
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
|
||||||
|
# Filter out symbols known not to be defined since GNU Autotools can't
|
||||||
|
# reliably figure this out with Xcode 8 and above.
|
||||||
|
if MacOS.version == "10.12" && MacOS::Xcode.version >= "9.0"
|
||||||
|
%w[fmemopen futimens open_memstream utimensat].each do |s|
|
||||||
|
ENV["ac_cv_func_#{s}"] = "no"
|
||||||
|
end
|
||||||
|
elsif MacOS.version == "10.11" && MacOS::Xcode.version >= "8.0"
|
||||||
|
%w[basename_r clock_getres clock_gettime clock_settime dirname_r
|
||||||
|
getentropy mkostemp mkostemps timingsafe_bcmp].each do |s|
|
||||||
|
ENV["ac_cv_func_#{s}"] = "no"
|
||||||
|
end
|
||||||
|
|
||||||
|
ENV["ac_cv_search_clock_gettime"] = "no"
|
||||||
|
|
||||||
|
# works around libev.m4 unsetting ac_cv_func_clock_gettime
|
||||||
|
ENV["ac_have_clock_syscall"] = "no"
|
||||||
|
end
|
||||||
|
|
||||||
|
# On macOS Sonoma (at least release candidate), iconv() is generally
|
||||||
|
# present and working, but has a minor regression that defeats the
|
||||||
|
# test implemented in gettext's configure script (and used by many
|
||||||
|
# gettext dependents).
|
||||||
|
ENV["am_cv_func_iconv_works"] = "yes" if MacOS.version == "14"
|
||||||
|
|
||||||
|
# The tools in /usr/bin proxy to the active developer directory.
|
||||||
|
# This means we can use them for any combination of CLT and Xcode.
|
||||||
|
self["HOMEBREW_PREFER_CLT_PROXIES"] = "1"
|
||||||
|
|
||||||
|
# Deterministic timestamping.
|
||||||
|
# This can work on older Xcode versions, but they contain some bugs.
|
||||||
|
# Notably, Xcode 10.2 fixes issues where ZERO_AR_DATE affected file mtimes.
|
||||||
|
# Xcode 11.0 contains fixes for lldb reading things built with ZERO_AR_DATE.
|
||||||
|
self["ZERO_AR_DATE"] = "1" if MacOS::Xcode.version >= "11.0" || MacOS::CLT.version >= "11.0"
|
||||||
|
|
||||||
|
# Pass `-no_fixup_chains` whenever the linker is invoked with `-undefined dynamic_lookup`.
|
||||||
|
# See: https://github.com/python/cpython/issues/97524
|
||||||
|
# https://github.com/pybind/pybind11/pull/4301
|
||||||
|
no_fixup_chains
|
||||||
|
|
||||||
|
# Strip build prefixes from linker where supported, for deterministic builds.
|
||||||
|
append_to_cccfg "o" if OS::Mac::DevelopmentTools.ld64_version >= 512
|
||||||
|
|
||||||
|
# Pass `-ld_classic` whenever the linker is invoked with `-dead_strip_dylibs`
|
||||||
|
# on `ld` versions that don't properly handle that option.
|
||||||
|
return unless OS::Mac::DevelopmentTools.ld64_version.between?("1015.7", "1022.1")
|
||||||
|
|
||||||
|
append_to_cccfg "c"
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_weak_imports
|
||||||
|
append_to_cccfg "w" if no_weak_imports_support?
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_fixup_chains
|
||||||
|
append_to_cccfg "f" if no_fixup_chains_support?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# On macOS Sonoma (at least release candidate), iconv() is generally
|
|
||||||
# present and working, but has a minor regression that defeats the
|
|
||||||
# test implemented in gettext's configure script (and used by many
|
|
||||||
# gettext dependents).
|
|
||||||
ENV["am_cv_func_iconv_works"] = "yes" if MacOS.version == "14"
|
|
||||||
|
|
||||||
# The tools in /usr/bin proxy to the active developer directory.
|
|
||||||
# This means we can use them for any combination of CLT and Xcode.
|
|
||||||
self["HOMEBREW_PREFER_CLT_PROXIES"] = "1"
|
|
||||||
|
|
||||||
# Deterministic timestamping.
|
|
||||||
# This can work on older Xcode versions, but they contain some bugs.
|
|
||||||
# Notably, Xcode 10.2 fixes issues where ZERO_AR_DATE affected file mtimes.
|
|
||||||
# Xcode 11.0 contains fixes for lldb reading things built with ZERO_AR_DATE.
|
|
||||||
self["ZERO_AR_DATE"] = "1" if MacOS::Xcode.version >= "11.0" || MacOS::CLT.version >= "11.0"
|
|
||||||
|
|
||||||
# Pass `-no_fixup_chains` whenever the linker is invoked with `-undefined dynamic_lookup`.
|
|
||||||
# See: https://github.com/python/cpython/issues/97524
|
|
||||||
# https://github.com/pybind/pybind11/pull/4301
|
|
||||||
no_fixup_chains
|
|
||||||
|
|
||||||
# Strip build prefixes from linker where supported, for deterministic builds.
|
|
||||||
append_to_cccfg "o" if OS::Mac::DevelopmentTools.ld64_version >= 512
|
|
||||||
|
|
||||||
# Pass `-ld_classic` whenever the linker is invoked with `-dead_strip_dylibs`
|
|
||||||
# on `ld` versions that don't properly handle that option.
|
|
||||||
return unless OS::Mac::DevelopmentTools.ld64_version.between?("1015.7", "1022.1")
|
|
||||||
|
|
||||||
append_to_cccfg "c"
|
|
||||||
end
|
|
||||||
|
|
||||||
def no_weak_imports
|
|
||||||
append_to_cccfg "w" if no_weak_imports_support?
|
|
||||||
end
|
|
||||||
|
|
||||||
def no_fixup_chains
|
|
||||||
append_to_cccfg "f" if no_fixup_chains_support?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Superenv.singleton_class.prepend(OS::Mac::Superenv::ClassMethods)
|
||||||
|
Superenv.prepend(OS::Mac::Superenv)
|
||||||
|
@ -4,133 +4,145 @@
|
|||||||
require "cache_store"
|
require "cache_store"
|
||||||
require "linkage_checker"
|
require "linkage_checker"
|
||||||
|
|
||||||
module FormulaCellarChecks
|
module OS
|
||||||
sig { returns(T.nilable(String)) }
|
module Mac
|
||||||
def check_shadowed_headers
|
module FormulaCellarChecks
|
||||||
return if ["libtool", "subversion", "berkeley-db"].any? do |formula_name|
|
extend T::Helpers
|
||||||
formula.name.start_with?(formula_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
return if formula.name.match?(Version.formula_optionally_versioned_regex(:php))
|
requires_ancestor { Homebrew::FormulaAuditor }
|
||||||
return if formula.keg_only? || !formula.include.directory?
|
requires_ancestor { ::FormulaCellarChecks }
|
||||||
|
|
||||||
files = relative_glob(formula.include, "**/*.h")
|
sig { returns(T.nilable(String)) }
|
||||||
files &= relative_glob("#{MacOS.sdk_path}/usr/include", "**/*.h")
|
def check_shadowed_headers
|
||||||
files.map! { |p| File.join(formula.include, p) }
|
return if ["libtool", "subversion", "berkeley-db"].any? do |formula_name|
|
||||||
|
formula.name.start_with?(formula_name)
|
||||||
|
end
|
||||||
|
|
||||||
return if files.empty?
|
return if formula.name.match?(Version.formula_optionally_versioned_regex(:php))
|
||||||
|
return if formula.keg_only? || !formula.include.directory?
|
||||||
|
|
||||||
<<~EOS
|
files = relative_glob(formula.include, "**/*.h")
|
||||||
Header files that shadow system header files were installed to "#{formula.include}"
|
files &= relative_glob("#{MacOS.sdk_path}/usr/include", "**/*.h")
|
||||||
The offending files are:
|
files.map! { |p| File.join(formula.include, p) }
|
||||||
#{files * "\n "}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { returns(T.nilable(String)) }
|
return if files.empty?
|
||||||
def check_openssl_links
|
|
||||||
return unless formula.prefix.directory?
|
|
||||||
|
|
||||||
keg = Keg.new(formula.prefix)
|
<<~EOS
|
||||||
system_openssl = keg.mach_o_files.select do |obj|
|
Header files that shadow system header files were installed to "#{formula.include}"
|
||||||
dlls = obj.dynamically_linked_libraries
|
The offending files are:
|
||||||
dlls.any? { |dll| %r{/usr/lib/lib(crypto|ssl|tls)\..*dylib}.match? dll }
|
#{files * "\n "}
|
||||||
end
|
|
||||||
return if system_openssl.empty?
|
|
||||||
|
|
||||||
<<~EOS
|
|
||||||
object files were linked against system openssl
|
|
||||||
These object files were linked against the deprecated system OpenSSL or
|
|
||||||
the system's private LibreSSL.
|
|
||||||
Adding `depends_on "openssl"` to the formula may help.
|
|
||||||
#{system_openssl * "\n "}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { params(lib: Pathname).returns(T.nilable(String)) }
|
|
||||||
def check_python_framework_links(lib)
|
|
||||||
python_modules = Pathname.glob lib/"python*/site-packages/**/*.so"
|
|
||||||
framework_links = python_modules.select do |obj|
|
|
||||||
dlls = obj.dynamically_linked_libraries
|
|
||||||
dlls.any? { |dll| dll.include?("Python.framework") }
|
|
||||||
end
|
|
||||||
return if framework_links.empty?
|
|
||||||
|
|
||||||
<<~EOS
|
|
||||||
python modules have explicit framework links
|
|
||||||
These python extension modules were linked directly to a Python
|
|
||||||
framework binary. They should be linked with -undefined dynamic_lookup
|
|
||||||
instead of -lpython or -framework Python.
|
|
||||||
#{framework_links * "\n "}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { void }
|
|
||||||
def check_linkage
|
|
||||||
return unless formula.prefix.directory?
|
|
||||||
|
|
||||||
keg = Keg.new(formula.prefix)
|
|
||||||
|
|
||||||
CacheStoreDatabase.use(:linkage) do |db|
|
|
||||||
checker = LinkageChecker.new(keg, formula, cache_db: db)
|
|
||||||
next unless checker.broken_library_linkage?
|
|
||||||
|
|
||||||
output = <<~EOS
|
|
||||||
#{formula} has broken dynamic library links:
|
|
||||||
#{checker.display_test_output}
|
|
||||||
EOS
|
|
||||||
|
|
||||||
tab = keg.tab
|
|
||||||
if tab.poured_from_bottle
|
|
||||||
output += <<~EOS
|
|
||||||
Rebuild this from source with:
|
|
||||||
brew reinstall --build-from-source #{formula}
|
|
||||||
If that's successful, file an issue#{formula.tap ? " here:\n #{T.must(formula.tap).issues_url}" : "."}
|
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
problem_if_output output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { params(formula: Formula).returns(T.nilable(String)) }
|
sig { returns(T.nilable(String)) }
|
||||||
def check_flat_namespace(formula)
|
def check_openssl_links
|
||||||
return unless formula.prefix.directory?
|
return unless formula.prefix.directory?
|
||||||
return if formula.tap&.audit_exception(:flat_namespace_allowlist, formula.name)
|
|
||||||
|
|
||||||
keg = ::Keg.new(formula.prefix)
|
keg = ::Keg.new(formula.prefix)
|
||||||
flat_namespace_files = keg.mach_o_files.reject do |file|
|
system_openssl = keg.mach_o_files.select do |obj|
|
||||||
next true unless file.dylib?
|
dlls = obj.dynamically_linked_libraries
|
||||||
|
dlls.any? { |dll| %r{/usr/lib/lib(crypto|ssl|tls)\..*dylib}.match? dll }
|
||||||
|
end
|
||||||
|
return if system_openssl.empty?
|
||||||
|
|
||||||
macho = MachO.open(file)
|
<<~EOS
|
||||||
if MachO::Utils.fat_magic?(macho.magic)
|
object files were linked against system openssl
|
||||||
macho.machos.map(&:header).all? { |h| h.flag? :MH_TWOLEVEL }
|
These object files were linked against the deprecated system OpenSSL or
|
||||||
else
|
the system's private LibreSSL.
|
||||||
macho.header.flag? :MH_TWOLEVEL
|
Adding `depends_on "openssl"` to the formula may help.
|
||||||
|
#{system_openssl * "\n "}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { params(lib: Pathname).returns(T.nilable(String)) }
|
||||||
|
def check_python_framework_links(lib)
|
||||||
|
python_modules = Pathname.glob lib/"python*/site-packages/**/*.so"
|
||||||
|
framework_links = python_modules.select do |obj|
|
||||||
|
dlls = obj.dynamically_linked_libraries
|
||||||
|
dlls.any? { |dll| dll.include?("Python.framework") }
|
||||||
|
end
|
||||||
|
return if framework_links.empty?
|
||||||
|
|
||||||
|
<<~EOS
|
||||||
|
python modules have explicit framework links
|
||||||
|
These python extension modules were linked directly to a Python
|
||||||
|
framework binary. They should be linked with -undefined dynamic_lookup
|
||||||
|
instead of -lpython or -framework Python.
|
||||||
|
#{framework_links * "\n "}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
|
def check_linkage
|
||||||
|
return unless formula.prefix.directory?
|
||||||
|
|
||||||
|
keg = ::Keg.new(formula.prefix)
|
||||||
|
|
||||||
|
CacheStoreDatabase.use(:linkage) do |db|
|
||||||
|
checker = ::LinkageChecker.new(keg, formula, cache_db: db)
|
||||||
|
next unless checker.broken_library_linkage?
|
||||||
|
|
||||||
|
output = <<~EOS
|
||||||
|
#{formula} has broken dynamic library links:
|
||||||
|
#{checker.display_test_output}
|
||||||
|
EOS
|
||||||
|
|
||||||
|
tab = keg.tab
|
||||||
|
if tab.poured_from_bottle
|
||||||
|
output += <<~EOS
|
||||||
|
Rebuild this from source with:
|
||||||
|
brew reinstall --build-from-source #{formula}
|
||||||
|
If that's successful, file an issue#{formula.tap ? " here:\n #{formula.tap.issues_url}" : "."}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
problem_if_output output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { params(formula: ::Formula).returns(T.nilable(String)) }
|
||||||
|
def check_flat_namespace(formula)
|
||||||
|
return unless formula.prefix.directory?
|
||||||
|
return if formula.tap&.audit_exception(:flat_namespace_allowlist, formula.name)
|
||||||
|
|
||||||
|
keg = ::Keg.new(formula.prefix)
|
||||||
|
flat_namespace_files = keg.mach_o_files.reject do |file|
|
||||||
|
next true unless file.dylib?
|
||||||
|
|
||||||
|
macho = MachO.open(file)
|
||||||
|
if MachO::Utils.fat_magic?(macho.magic)
|
||||||
|
macho.machos.map(&:header).all? { |h| h.flag? :MH_TWOLEVEL }
|
||||||
|
else
|
||||||
|
macho.header.flag? :MH_TWOLEVEL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return if flat_namespace_files.empty?
|
||||||
|
|
||||||
|
<<~EOS
|
||||||
|
Libraries were compiled with a flat namespace.
|
||||||
|
This can cause linker errors due to name collisions and
|
||||||
|
is often due to a bug in detecting the macOS version.
|
||||||
|
#{flat_namespace_files * "\n "}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
|
def audit_installed
|
||||||
|
super
|
||||||
|
problem_if_output(check_shadowed_headers)
|
||||||
|
problem_if_output(check_openssl_links)
|
||||||
|
problem_if_output(check_python_framework_links(formula.lib))
|
||||||
|
check_linkage
|
||||||
|
problem_if_output(check_flat_namespace(formula))
|
||||||
|
end
|
||||||
|
|
||||||
|
MACOS_LIB_EXTENSIONS = %w[.dylib .framework].freeze
|
||||||
|
|
||||||
|
sig { params(filename: Pathname).returns(T::Boolean) }
|
||||||
|
def valid_library_extension?(filename)
|
||||||
|
super || MACOS_LIB_EXTENSIONS.include?(filename.extname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return if flat_namespace_files.empty?
|
|
||||||
|
|
||||||
<<~EOS
|
|
||||||
Libraries were compiled with a flat namespace.
|
|
||||||
This can cause linker errors due to name collisions and
|
|
||||||
is often due to a bug in detecting the macOS version.
|
|
||||||
#{flat_namespace_files * "\n "}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { void }
|
|
||||||
def audit_installed
|
|
||||||
generic_audit_installed
|
|
||||||
problem_if_output(check_shadowed_headers)
|
|
||||||
problem_if_output(check_openssl_links)
|
|
||||||
problem_if_output(check_python_framework_links(formula.lib))
|
|
||||||
check_linkage
|
|
||||||
problem_if_output(check_flat_namespace(formula))
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { params(filename: Pathname).returns(T::Boolean) }
|
|
||||||
def valid_library_extension?(filename)
|
|
||||||
macos_lib_extensions = %w[.dylib .framework]
|
|
||||||
generic_valid_library_extension?(filename) || macos_lib_extensions.include?(filename.extname)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
FormulaCellarChecks.prepend(OS::Mac::FormulaCellarChecks)
|
||||||
|
@ -1,25 +1,33 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Hardware
|
module OS
|
||||||
sig { params(version: T.nilable(Version)).returns(Symbol) }
|
module Mac
|
||||||
def self.oldest_cpu(version = nil)
|
module Hardware
|
||||||
version = if version
|
module ClassMethods
|
||||||
MacOSVersion.new(version.to_s)
|
sig { params(version: T.nilable(MacOSVersion)).returns(Symbol) }
|
||||||
else
|
def oldest_cpu(version = nil)
|
||||||
MacOS.version
|
version = if version
|
||||||
end
|
MacOSVersion.new(version.to_s)
|
||||||
if CPU.arch == :arm64
|
else
|
||||||
:arm_vortex_tempest
|
MacOS.version
|
||||||
# This cannot use a newer CPU e.g. haswell because Rosetta 2 does not
|
end
|
||||||
# support AVX instructions in bottles:
|
if ::Hardware::CPU.arch == :arm64
|
||||||
# https://github.com/Homebrew/homebrew-core/issues/67713
|
:arm_vortex_tempest
|
||||||
elsif version >= :ventura
|
# This cannot use a newer CPU e.g. haswell because Rosetta 2 does not
|
||||||
:westmere
|
# support AVX instructions in bottles:
|
||||||
elsif version >= :mojave
|
# https://github.com/Homebrew/homebrew-core/issues/67713
|
||||||
:nehalem
|
elsif version >= :ventura
|
||||||
else
|
:westmere
|
||||||
generic_oldest_cpu
|
elsif version >= :mojave
|
||||||
|
:nehalem
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Hardware.singleton_class.prepend(OS::Mac::Hardware::ClassMethods)
|
||||||
|
@ -95,7 +95,7 @@ module OS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
generic_fix_dynamic_linkage
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def loader_name_for(file, target)
|
def loader_name_for(file, target)
|
||||||
@ -199,7 +199,7 @@ module OS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def prepare_relocation_to_locations
|
def prepare_relocation_to_locations
|
||||||
relocation = generic_prepare_relocation_to_locations
|
relocation = super
|
||||||
|
|
||||||
brewed_perl = runtime_dependencies&.any? { |dep| dep["full_name"] == "perl" && dep["declared_directly"] }
|
brewed_perl = runtime_dependencies&.any? { |dep| dep["full_name"] == "perl" && dep["declared_directly"] }
|
||||||
perl_path = if brewed_perl || name == "perl"
|
perl_path = if brewed_perl || name == "perl"
|
||||||
|
@ -5,55 +5,59 @@ require "cask/info"
|
|||||||
require "cask/cask_loader"
|
require "cask/cask_loader"
|
||||||
require "cask/caskroom"
|
require "cask/caskroom"
|
||||||
|
|
||||||
module Homebrew
|
module OS
|
||||||
module MissingFormula
|
module Mac
|
||||||
class << self
|
module MissingFormula
|
||||||
sig { params(name: String).returns(T.nilable(String)) }
|
module ClassMethods
|
||||||
def disallowed_reason(name)
|
sig { params(name: String).returns(T.nilable(String)) }
|
||||||
case name.downcase
|
def disallowed_reason(name)
|
||||||
when "xcode"
|
case name.downcase
|
||||||
<<~EOS
|
when "xcode"
|
||||||
Xcode can be installed from the App Store.
|
<<~EOS
|
||||||
EOS
|
Xcode can be installed from the App Store.
|
||||||
else
|
EOS
|
||||||
generic_disallowed_reason(name)
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
sig { params(name: String, silent: T::Boolean, show_info: T::Boolean).returns(T.nilable(String)) }
|
sig { params(name: String, silent: T::Boolean, show_info: T::Boolean).returns(T.nilable(String)) }
|
||||||
def cask_reason(name, silent: false, show_info: false)
|
def cask_reason(name, silent: false, show_info: false)
|
||||||
return if silent
|
return if silent
|
||||||
|
|
||||||
suggest_command(name, show_info ? "info" : "install")
|
suggest_command(name, show_info ? "info" : "install")
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(name: String, command: String).returns(T.nilable(String)) }
|
sig { params(name: String, command: String).returns(T.nilable(String)) }
|
||||||
def suggest_command(name, command)
|
def suggest_command(name, command)
|
||||||
suggestion = <<~EOS
|
|
||||||
Found a cask named "#{name}" instead. Try
|
|
||||||
brew #{command} --cask #{name}
|
|
||||||
|
|
||||||
EOS
|
|
||||||
case command
|
|
||||||
when "install"
|
|
||||||
Cask::CaskLoader.load(name)
|
|
||||||
when "uninstall"
|
|
||||||
cask = Cask::Caskroom.casks.find { |installed_cask| installed_cask.to_s == name }
|
|
||||||
raise Cask::CaskUnavailableError, name if cask.nil?
|
|
||||||
when "info"
|
|
||||||
cask = Cask::CaskLoader.load(name)
|
|
||||||
suggestion = <<~EOS
|
suggestion = <<~EOS
|
||||||
Found a cask named "#{name}" instead.
|
Found a cask named "#{name}" instead. Try
|
||||||
|
brew #{command} --cask #{name}
|
||||||
|
|
||||||
#{Cask::Info.get_info(cask)}
|
|
||||||
EOS
|
EOS
|
||||||
else
|
case command
|
||||||
return
|
when "install"
|
||||||
|
::Cask::CaskLoader.load(name)
|
||||||
|
when "uninstall"
|
||||||
|
cask = ::Cask::Caskroom.casks.find { |installed_cask| installed_cask.to_s == name }
|
||||||
|
Kernel.raise ::Cask::CaskUnavailableError, name if cask.nil?
|
||||||
|
when "info"
|
||||||
|
cask = ::Cask::CaskLoader.load(name)
|
||||||
|
suggestion = <<~EOS
|
||||||
|
Found a cask named "#{name}" instead.
|
||||||
|
|
||||||
|
#{::Cask::Info.get_info(cask)}
|
||||||
|
EOS
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
suggestion
|
||||||
|
rescue ::Cask::CaskUnavailableError
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
suggestion
|
|
||||||
rescue Cask::CaskUnavailableError
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Homebrew::MissingFormula.singleton_class.prepend(OS::Mac::MissingFormula::ClassMethods)
|
||||||
|
@ -6,46 +6,45 @@ require "system_command"
|
|||||||
module OS
|
module OS
|
||||||
module Mac
|
module Mac
|
||||||
module SystemConfig
|
module SystemConfig
|
||||||
sig { returns(String) }
|
module ClassMethods
|
||||||
def describe_clang
|
extend T::Helpers
|
||||||
return "N/A" if ::SystemConfig.clang.null?
|
|
||||||
|
|
||||||
clang_build_info = ::SystemConfig.clang_build.null? ? "(parse error)" : ::SystemConfig.clang_build
|
requires_ancestor { T.class_of(::SystemConfig) }
|
||||||
"#{::SystemConfig.clang} build #{clang_build_info}"
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def describe_clang
|
||||||
|
return "N/A" if ::SystemConfig.clang.null?
|
||||||
|
|
||||||
|
clang_build_info = ::SystemConfig.clang_build.null? ? "(parse error)" : ::SystemConfig.clang_build
|
||||||
|
"#{::SystemConfig.clang} build #{clang_build_info}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def xcode
|
||||||
|
@xcode ||= if MacOS::Xcode.installed?
|
||||||
|
xcode = MacOS::Xcode.version.to_s
|
||||||
|
xcode += " => #{MacOS::Xcode.prefix}" unless MacOS::Xcode.default_prefix?
|
||||||
|
xcode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def clt
|
||||||
|
@clt ||= MacOS::CLT.version if MacOS::CLT.installed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def core_tap_config(out = $stdout)
|
||||||
|
dump_tap_config(CoreTap.instance, out)
|
||||||
|
dump_tap_config(CoreCaskTap.instance, out)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dump_verbose_config(out = $stdout)
|
||||||
|
super
|
||||||
|
out.puts "macOS: #{MacOS.full_version}-#{kernel}"
|
||||||
|
out.puts "CLT: #{clt || "N/A"}"
|
||||||
|
out.puts "Xcode: #{xcode || "N/A"}"
|
||||||
|
out.puts "Rosetta 2: #{::Hardware::CPU.in_rosetta2?}" if ::Hardware::CPU.physical_cpu_arm64?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
SystemConfig.singleton_class.prepend(OS::Mac::SystemConfig::ClassMethods)
|
||||||
SystemConfig.prepend(OS::Mac::SystemConfig)
|
|
||||||
|
|
||||||
module SystemConfig
|
|
||||||
class << self
|
|
||||||
include SystemCommand::Mixin
|
|
||||||
|
|
||||||
def xcode
|
|
||||||
@xcode ||= if MacOS::Xcode.installed?
|
|
||||||
xcode = MacOS::Xcode.version.to_s
|
|
||||||
xcode += " => #{MacOS::Xcode.prefix}" unless MacOS::Xcode.default_prefix?
|
|
||||||
xcode
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def clt
|
|
||||||
@clt ||= MacOS::CLT.version if MacOS::CLT.installed?
|
|
||||||
end
|
|
||||||
|
|
||||||
def core_tap_config(out = $stdout)
|
|
||||||
dump_tap_config(CoreTap.instance, out)
|
|
||||||
dump_tap_config(CoreCaskTap.instance, out)
|
|
||||||
end
|
|
||||||
|
|
||||||
def dump_verbose_config(out = $stdout)
|
|
||||||
dump_generic_verbose_config(out)
|
|
||||||
out.puts "macOS: #{MacOS.full_version}-#{kernel}"
|
|
||||||
out.puts "CLT: #{clt || "N/A"}"
|
|
||||||
out.puts "Xcode: #{xcode || "N/A"}"
|
|
||||||
out.puts "Rosetta 2: #{Hardware::CPU.in_rosetta2?}" if Hardware::CPU.physical_cpu_arm64?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
@ -1,59 +1,66 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Utils
|
module OS
|
||||||
module Bottles
|
module Mac
|
||||||
class << self
|
module Bottles
|
||||||
module MacOSOverride
|
module ClassMethods
|
||||||
sig { params(tag: T.nilable(T.any(Symbol, Tag))).returns(Tag) }
|
sig { params(tag: T.nilable(T.any(Symbol, Utils::Bottles::Tag))).returns(Utils::Bottles::Tag) }
|
||||||
def tag(tag = nil)
|
def tag(tag = nil)
|
||||||
return Tag.new(system: MacOS.version.to_sym, arch: Hardware::CPU.arch) if tag.nil?
|
if tag.nil?
|
||||||
|
Utils::Bottles::Tag.new(system: MacOS.version.to_sym, arch: ::Hardware::CPU.arch)
|
||||||
super
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
prepend MacOSOverride
|
module Collector
|
||||||
end
|
extend T::Helpers
|
||||||
|
|
||||||
class Collector
|
requires_ancestor { Utils::Bottles::Collector }
|
||||||
private
|
|
||||||
|
|
||||||
alias generic_find_matching_tag find_matching_tag
|
private
|
||||||
|
|
||||||
sig { params(tag: Utils::Bottles::Tag, no_older_versions: T::Boolean).returns(T.nilable(Utils::Bottles::Tag)) }
|
sig {
|
||||||
def find_matching_tag(tag, no_older_versions: false)
|
params(tag: Utils::Bottles::Tag,
|
||||||
# Used primarily by developers testing beta macOS releases.
|
no_older_versions: T::Boolean).returns(T.nilable(Utils::Bottles::Tag))
|
||||||
if no_older_versions ||
|
}
|
||||||
(OS::Mac.version.prerelease? &&
|
def find_matching_tag(tag, no_older_versions: false)
|
||||||
Homebrew::EnvConfig.developer? &&
|
# Used primarily by developers testing beta macOS releases.
|
||||||
Homebrew::EnvConfig.skip_or_later_bottles?)
|
if no_older_versions ||
|
||||||
generic_find_matching_tag(tag)
|
(OS::Mac.version.prerelease? &&
|
||||||
else
|
Homebrew::EnvConfig.developer? &&
|
||||||
generic_find_matching_tag(tag) ||
|
Homebrew::EnvConfig.skip_or_later_bottles?)
|
||||||
find_older_compatible_tag(tag)
|
super(tag)
|
||||||
end
|
else
|
||||||
end
|
super(tag) || find_older_compatible_tag(tag)
|
||||||
|
end
|
||||||
# Find a bottle built for a previous version of macOS.
|
|
||||||
sig { params(tag: Utils::Bottles::Tag).returns(T.nilable(Utils::Bottles::Tag)) }
|
|
||||||
def find_older_compatible_tag(tag)
|
|
||||||
tag_version = begin
|
|
||||||
tag.to_macos_version
|
|
||||||
rescue MacOSVersion::Error
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return if tag_version.blank?
|
# Find a bottle built for a previous version of macOS.
|
||||||
|
sig { params(tag: Utils::Bottles::Tag).returns(T.nilable(Utils::Bottles::Tag)) }
|
||||||
|
def find_older_compatible_tag(tag)
|
||||||
|
tag_version = begin
|
||||||
|
tag.to_macos_version
|
||||||
|
rescue MacOSVersion::Error
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
tags.find do |candidate|
|
return if tag_version.blank?
|
||||||
next if candidate.standardized_arch != tag.standardized_arch
|
|
||||||
|
|
||||||
candidate.to_macos_version <= tag_version
|
tags.find do |candidate|
|
||||||
rescue MacOSVersion::Error
|
next if candidate.standardized_arch != tag.standardized_arch
|
||||||
false
|
|
||||||
|
candidate.to_macos_version <= tag_version
|
||||||
|
rescue MacOSVersion::Error
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Utils::Bottles.singleton_class.prepend(OS::Mac::Bottles::ClassMethods)
|
||||||
|
Utils::Bottles::Collector.prepend(OS::Mac::Bottles::Collector)
|
||||||
|
@ -84,7 +84,6 @@ module FormulaCellarChecks
|
|||||||
def valid_library_extension?(filename)
|
def valid_library_extension?(filename)
|
||||||
VALID_LIBRARY_EXTENSIONS.include? filename.extname
|
VALID_LIBRARY_EXTENSIONS.include? filename.extname
|
||||||
end
|
end
|
||||||
alias generic_valid_library_extension? valid_library_extension?
|
|
||||||
|
|
||||||
sig { returns(T.nilable(String)) }
|
sig { returns(T.nilable(String)) }
|
||||||
def check_non_libraries
|
def check_non_libraries
|
||||||
@ -437,7 +436,6 @@ module FormulaCellarChecks
|
|||||||
problem_if_output(check_cpuid_instruction(formula))
|
problem_if_output(check_cpuid_instruction(formula))
|
||||||
problem_if_output(check_binary_arches(formula))
|
problem_if_output(check_binary_arches(formula))
|
||||||
end
|
end
|
||||||
alias generic_audit_installed audit_installed
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "digest"
|
require "digest"
|
||||||
@ -7,62 +7,81 @@ require "erb"
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
# Class for generating a formula from a template.
|
# Class for generating a formula from a template.
|
||||||
class FormulaCreator
|
class FormulaCreator
|
||||||
|
sig { returns(String) }
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
|
||||||
|
sig { returns(Version) }
|
||||||
|
attr_reader :version
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
attr_reader :head
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
params(name: T.nilable(String), version: T.nilable(String), tap: T.nilable(String), url: String,
|
params(url: String, name: T.nilable(String), version: T.nilable(String), tap: T.nilable(String),
|
||||||
mode: T.nilable(Symbol), license: T.nilable(String), fetch: T::Boolean, head: T::Boolean).void
|
mode: T.nilable(Symbol), license: T.nilable(String), fetch: T::Boolean, head: T::Boolean).void
|
||||||
}
|
}
|
||||||
def initialize(name, version, tap:, url:, mode:, license:, fetch:, head:)
|
def initialize(url:, name: nil, version: nil, tap: nil, mode: nil, license: nil, fetch: false, head: false)
|
||||||
@name = name
|
|
||||||
@version = Version.new(version) if version
|
|
||||||
@tap = Tap.fetch(tap || "homebrew/core")
|
|
||||||
@url = url
|
@url = url
|
||||||
@mode = mode
|
|
||||||
@license = license
|
|
||||||
@fetch = fetch
|
|
||||||
@head = head
|
|
||||||
end
|
|
||||||
|
|
||||||
sig { void }
|
if name.blank?
|
||||||
def verify
|
stem = Pathname.new(url).stem
|
||||||
raise TapUnavailableError, @tap.name unless @tap.installed?
|
name = if stem.start_with?("index.cgi") && stem.include?("=")
|
||||||
end
|
# special cases first
|
||||||
|
# gitweb URLs e.g. http://www.codesrc.com/gitweb/index.cgi?p=libzipper.git;a=summary
|
||||||
sig { params(url: String).returns(T.nilable(String)) }
|
stem.rpartition("=").last
|
||||||
def self.name_from_url(url)
|
elsif url =~ %r{github\.com/\S+/(\S+)/(archive|releases)/}
|
||||||
stem = Pathname.new(url).stem
|
# e.g. https://github.com/stella-emu/stella/releases/download/6.7/stella-6.7-src.tar.xz
|
||||||
# special cases first
|
T.must(Regexp.last_match(1))
|
||||||
if stem.start_with? "index.cgi"
|
else
|
||||||
# gitweb URLs e.g. http://www.codesrc.com/gitweb/index.cgi?p=libzipper.git;a=summary
|
# e.g. http://digit-labs.org/files/tools/synscan/releases/synscan-5.02.tar.gz
|
||||||
stem.rpartition("=").last
|
pathver = Version.parse(stem).to_s
|
||||||
elsif url =~ %r{github\.com/\S+/(\S+)/(archive|releases)/}
|
stem.sub(/[-_.]?#{Regexp.escape(pathver)}$/, "")
|
||||||
# e.g. https://github.com/stella-emu/stella/releases/download/6.7/stella-6.7-src.tar.xz
|
end
|
||||||
Regexp.last_match(1)
|
odebug "name from url: #{name}"
|
||||||
else
|
|
||||||
# e.g. http://digit-labs.org/files/tools/synscan/releases/synscan-5.02.tar.gz
|
|
||||||
pathver = Version.parse(stem).to_s
|
|
||||||
stem.sub(/[-_.]?#{Regexp.escape(pathver)}$/, "")
|
|
||||||
end
|
end
|
||||||
end
|
@name = T.let(name, String)
|
||||||
|
|
||||||
sig { void }
|
version = if version.present?
|
||||||
def parse_url
|
Version.new(version)
|
||||||
@name = FormulaCreator.name_from_url(@url) if @name.blank?
|
else
|
||||||
odebug "name_from_url: #{@name}"
|
Version.detect(url)
|
||||||
@version = Version.detect(@url) if @version.nil?
|
end
|
||||||
|
@version = T.let(version, Version)
|
||||||
|
|
||||||
case @url
|
tap = if tap.blank?
|
||||||
|
CoreTap.instance
|
||||||
|
else
|
||||||
|
Tap.fetch(tap)
|
||||||
|
end
|
||||||
|
@tap = T.let(tap, Tap)
|
||||||
|
|
||||||
|
@mode = T.let(mode.presence, T.nilable(Symbol))
|
||||||
|
@license = T.let(license.presence, T.nilable(String))
|
||||||
|
@fetch = fetch
|
||||||
|
|
||||||
|
case url
|
||||||
when %r{github\.com/(\S+)/(\S+)\.git}
|
when %r{github\.com/(\S+)/(\S+)\.git}
|
||||||
@head = true
|
head = true
|
||||||
user = Regexp.last_match(1)
|
user = Regexp.last_match(1)
|
||||||
repo = Regexp.last_match(2)
|
repository = Regexp.last_match(2)
|
||||||
@github = GitHub.repository(user, repo) if @fetch
|
github = GitHub.repository(user, repository) if fetch
|
||||||
when %r{github\.com/(\S+)/(\S+)/(archive|releases)/}
|
when %r{github\.com/(\S+)/(\S+)/(archive|releases)/}
|
||||||
user = Regexp.last_match(1)
|
user = Regexp.last_match(1)
|
||||||
repo = Regexp.last_match(2)
|
repository = Regexp.last_match(2)
|
||||||
@github = GitHub.repository(user, repo) if @fetch
|
github = GitHub.repository(user, repository) if fetch
|
||||||
end
|
end
|
||||||
|
@head = head
|
||||||
|
@github = T.let(github, T.untyped)
|
||||||
|
|
||||||
|
@sha256 = T.let(nil, T.nilable(String))
|
||||||
|
@desc = T.let(nil, T.nilable(String))
|
||||||
|
@homepage = T.let(nil, T.nilable(String))
|
||||||
|
@license = T.let(nil, T.nilable(String))
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { void }
|
||||||
|
def verify_tap_available!
|
||||||
|
raise TapUnavailableError, @tap.name unless @tap.installed?
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(Pathname) }
|
sig { returns(Pathname) }
|
||||||
@ -91,7 +110,7 @@ module Homebrew
|
|||||||
raise "Downloaded URL is not archive"
|
raise "Downloaded URL is not archive"
|
||||||
end
|
end
|
||||||
|
|
||||||
@sha256 = filepath.sha256
|
@sha256 = T.let(filepath.sha256, T.nilable(String))
|
||||||
end
|
end
|
||||||
|
|
||||||
if @github
|
if @github
|
||||||
@ -106,6 +125,8 @@ module Homebrew
|
|||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
sig { params(name: String).returns(String) }
|
sig { params(name: String).returns(String) }
|
||||||
def latest_versioned_formula(name)
|
def latest_versioned_formula(name)
|
||||||
name_prefix = "#{name}@"
|
name_prefix = "#{name}@"
|
||||||
@ -116,8 +137,6 @@ module Homebrew
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def template
|
def template
|
||||||
# FIXME: https://github.com/errata-ai/vale/issues/818
|
|
||||||
# <!-- vale off -->
|
|
||||||
<<~ERB
|
<<~ERB
|
||||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||||
# https://rubydoc.brew.sh/Formula
|
# https://rubydoc.brew.sh/Formula
|
||||||
@ -261,7 +280,6 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
ERB
|
ERB
|
||||||
# <!-- vale on -->
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -51,6 +51,7 @@ HOMEBREW_HOME_PLACEHOLDER = "/$HOME"
|
|||||||
HOMEBREW_CASK_APPDIR_PLACEHOLDER = "$APPDIR"
|
HOMEBREW_CASK_APPDIR_PLACEHOLDER = "$APPDIR"
|
||||||
|
|
||||||
HOMEBREW_MACOS_NEWEST_UNSUPPORTED = ENV.fetch("HOMEBREW_MACOS_NEWEST_UNSUPPORTED").freeze
|
HOMEBREW_MACOS_NEWEST_UNSUPPORTED = ENV.fetch("HOMEBREW_MACOS_NEWEST_UNSUPPORTED").freeze
|
||||||
|
HOMEBREW_MACOS_NEWEST_SUPPORTED = ENV.fetch("HOMEBREW_MACOS_NEWEST_SUPPORTED").freeze
|
||||||
HOMEBREW_MACOS_OLDEST_SUPPORTED = ENV.fetch("HOMEBREW_MACOS_OLDEST_SUPPORTED").freeze
|
HOMEBREW_MACOS_OLDEST_SUPPORTED = ENV.fetch("HOMEBREW_MACOS_OLDEST_SUPPORTED").freeze
|
||||||
HOMEBREW_MACOS_OLDEST_ALLOWED = ENV.fetch("HOMEBREW_MACOS_OLDEST_ALLOWED").freeze
|
HOMEBREW_MACOS_OLDEST_ALLOWED = ENV.fetch("HOMEBREW_MACOS_OLDEST_ALLOWED").freeze
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ module Hardware
|
|||||||
ppc64le: "-mcpu=powerpc64le",
|
ppc64le: "-mcpu=powerpc64le",
|
||||||
}.freeze, T.nilable(T::Hash[Symbol, String]))
|
}.freeze, T.nilable(T::Hash[Symbol, String]))
|
||||||
end
|
end
|
||||||
alias generic_optimization_flags optimization_flags
|
|
||||||
|
|
||||||
sig { returns(Symbol) }
|
sig { returns(Symbol) }
|
||||||
def arch_32_bit
|
def arch_32_bit
|
||||||
@ -219,6 +218,7 @@ module Hardware
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(_version: T.nilable(MacOSVersion)).returns(Symbol) }
|
||||||
def oldest_cpu(_version = nil)
|
def oldest_cpu(_version = nil)
|
||||||
if Hardware::CPU.intel?
|
if Hardware::CPU.intel?
|
||||||
if Hardware::CPU.is_64_bit?
|
if Hardware::CPU.is_64_bit?
|
||||||
@ -242,7 +242,6 @@ module Hardware
|
|||||||
Hardware::CPU.family
|
Hardware::CPU.family
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias generic_oldest_cpu oldest_cpu
|
|
||||||
|
|
||||||
# Returns a Rust flag to set the target CPU if necessary.
|
# Returns a Rust flag to set the target CPU if necessary.
|
||||||
# Defaults to nil.
|
# Defaults to nil.
|
||||||
|
@ -37,7 +37,6 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def global_post_install; end
|
def global_post_install; end
|
||||||
alias generic_global_post_install global_post_install
|
|
||||||
|
|
||||||
def check_prefix
|
def check_prefix
|
||||||
if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) &&
|
if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) &&
|
||||||
@ -399,7 +398,6 @@ module Homebrew
|
|||||||
Diagnostic.checks(:supported_configuration_checks, fatal: all_fatal)
|
Diagnostic.checks(:supported_configuration_checks, fatal: all_fatal)
|
||||||
Diagnostic.checks(:fatal_preinstall_checks)
|
Diagnostic.checks(:fatal_preinstall_checks)
|
||||||
end
|
end
|
||||||
alias generic_perform_preinstall_checks perform_preinstall_checks
|
|
||||||
|
|
||||||
def attempt_directory_creation
|
def attempt_directory_creation
|
||||||
Keg.must_exist_directories.each do |dir|
|
Keg.must_exist_directories.each do |dir|
|
||||||
|
@ -77,7 +77,6 @@ class Keg
|
|||||||
FileUtils.ln_s(new_src, file)
|
FileUtils.ln_s(new_src, file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias generic_fix_dynamic_linkage fix_dynamic_linkage
|
|
||||||
|
|
||||||
def relocate_dynamic_linkage(_relocation)
|
def relocate_dynamic_linkage(_relocation)
|
||||||
[]
|
[]
|
||||||
@ -102,7 +101,6 @@ class Keg
|
|||||||
|
|
||||||
relocation
|
relocation
|
||||||
end
|
end
|
||||||
alias generic_prepare_relocation_to_placeholders prepare_relocation_to_placeholders
|
|
||||||
|
|
||||||
def replace_locations_with_placeholders
|
def replace_locations_with_placeholders
|
||||||
relocation = prepare_relocation_to_placeholders.freeze
|
relocation = prepare_relocation_to_placeholders.freeze
|
||||||
@ -123,7 +121,6 @@ class Keg
|
|||||||
|
|
||||||
relocation
|
relocation
|
||||||
end
|
end
|
||||||
alias generic_prepare_relocation_to_locations prepare_relocation_to_locations
|
|
||||||
|
|
||||||
def replace_placeholders_with_locations(files, skip_linkage: false)
|
def replace_placeholders_with_locations(files, skip_linkage: false)
|
||||||
relocation = prepare_relocation_to_locations.freeze
|
relocation = prepare_relocation_to_locations.freeze
|
||||||
@ -221,7 +218,6 @@ class Keg
|
|||||||
|
|
||||||
[grep_bin, grep_args]
|
[grep_bin, grep_args]
|
||||||
end
|
end
|
||||||
alias generic_egrep_args egrep_args
|
|
||||||
|
|
||||||
def each_unique_file_matching(string)
|
def each_unique_file_matching(string)
|
||||||
Utils.popen_read("fgrep", recursive_fgrep_args, string, to_s) do |io|
|
Utils.popen_read("fgrep", recursive_fgrep_args, string, to_s) do |io|
|
||||||
|
@ -188,12 +188,10 @@ class LinkageChecker
|
|||||||
|
|
||||||
store&.update!(keg_files_dylibs:)
|
store&.update!(keg_files_dylibs:)
|
||||||
end
|
end
|
||||||
alias generic_check_dylibs check_dylibs
|
|
||||||
|
|
||||||
def system_libraries_exist_in_cache?
|
def system_libraries_exist_in_cache?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
alias generic_system_libraries_exist_in_cache? system_libraries_exist_in_cache?
|
|
||||||
|
|
||||||
def dylib_found_in_shared_cache?(dylib)
|
def dylib_found_in_shared_cache?(dylib)
|
||||||
@dyld_shared_cache_contains_path ||= begin
|
@dyld_shared_cache_contains_path ||= begin
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strong
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "version"
|
require "version"
|
||||||
@ -10,6 +10,7 @@ class MacOSVersion < Version
|
|||||||
sig { returns(T.nilable(T.any(String, Symbol))) }
|
sig { returns(T.nilable(T.any(String, Symbol))) }
|
||||||
attr_reader :version
|
attr_reader :version
|
||||||
|
|
||||||
|
sig { params(version: T.nilable(T.any(String, Symbol))).void }
|
||||||
def initialize(version)
|
def initialize(version)
|
||||||
@version = version
|
@version = version
|
||||||
super "unknown or unsupported macOS version: #{version.inspect}"
|
super "unknown or unsupported macOS version: #{version.inspect}"
|
||||||
@ -18,7 +19,7 @@ class MacOSVersion < Version
|
|||||||
|
|
||||||
# NOTE: When removing symbols here, ensure that they are added
|
# NOTE: When removing symbols here, ensure that they are added
|
||||||
# to `DEPRECATED_MACOS_VERSIONS` in `MacOSRequirement`.
|
# to `DEPRECATED_MACOS_VERSIONS` in `MacOSRequirement`.
|
||||||
SYMBOLS = {
|
SYMBOLS = T.let({
|
||||||
tahoe: "26",
|
tahoe: "26",
|
||||||
sequoia: "15",
|
sequoia: "15",
|
||||||
sonoma: "14",
|
sonoma: "14",
|
||||||
@ -30,7 +31,7 @@ class MacOSVersion < Version
|
|||||||
high_sierra: "10.13",
|
high_sierra: "10.13",
|
||||||
sierra: "10.12",
|
sierra: "10.12",
|
||||||
el_capitan: "10.11",
|
el_capitan: "10.11",
|
||||||
}.freeze
|
}.freeze, T::Hash[Symbol, String])
|
||||||
|
|
||||||
sig { params(macos_version: MacOSVersion).returns(Version) }
|
sig { params(macos_version: MacOSVersion).returns(Version) }
|
||||||
def self.kernel_major_version(macos_version)
|
def self.kernel_major_version(macos_version)
|
||||||
@ -57,7 +58,9 @@ class MacOSVersion < Version
|
|||||||
|
|
||||||
super(T.must(version))
|
super(T.must(version))
|
||||||
|
|
||||||
@comparison_cache = {}
|
@comparison_cache = T.let({}, T::Hash[T.untyped, T.nilable(Integer)])
|
||||||
|
@pretty_name = T.let(nil, T.nilable(String))
|
||||||
|
@sym = T.let(nil, T.nilable(Symbol))
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { override.params(other: T.untyped).returns(T.nilable(Integer)) }
|
sig { override.params(other: T.untyped).returns(T.nilable(Integer)) }
|
||||||
@ -95,7 +98,7 @@ class MacOSVersion < Version
|
|||||||
|
|
||||||
sig { returns(Symbol) }
|
sig { returns(Symbol) }
|
||||||
def to_sym
|
def to_sym
|
||||||
return @sym if defined?(@sym)
|
return @sym if @sym
|
||||||
|
|
||||||
sym = SYMBOLS.invert.fetch(strip_patch.to_s, :dunno)
|
sym = SYMBOLS.invert.fetch(strip_patch.to_s, :dunno)
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ class MacOSVersion < Version
|
|||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def pretty_name
|
def pretty_name
|
||||||
return @pretty_name if defined?(@pretty_name)
|
return @pretty_name if @pretty_name
|
||||||
|
|
||||||
pretty_name = to_sym.to_s.split("_").map(&:capitalize).join(" ").freeze
|
pretty_name = to_sym.to_s.split("_").map(&:capitalize).join(" ").freeze
|
||||||
|
|
||||||
@ -154,5 +157,7 @@ class MacOSVersion < Version
|
|||||||
# Represents the absence of a version.
|
# Represents the absence of a version.
|
||||||
#
|
#
|
||||||
# NOTE: Constructor needs to called with an arbitrary macOS-like version which is then set to `nil`.
|
# NOTE: Constructor needs to called with an arbitrary macOS-like version which is then set to `nil`.
|
||||||
NULL = MacOSVersion.new("10.0").tap { |v| v.instance_variable_set(:@version, nil) }.freeze
|
NULL = T.let(MacOSVersion.new("10.0").tap do |v|
|
||||||
|
T.let(v, MacOSVersion).instance_variable_set(:@version, nil)
|
||||||
|
end.freeze, MacOSVersion)
|
||||||
end
|
end
|
||||||
|
@ -93,7 +93,6 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias generic_disallowed_reason disallowed_reason
|
|
||||||
|
|
||||||
sig { params(name: String).returns(T.nilable(String)) }
|
sig { params(name: String).returns(T.nilable(String)) }
|
||||||
def tap_migration_reason(name)
|
def tap_migration_reason(name)
|
||||||
@ -195,8 +194,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(name: String, silent: T::Boolean, show_info: T::Boolean).returns(T.nilable(String)) }
|
||||||
def cask_reason(name, silent: false, show_info: false); end
|
def cask_reason(name, silent: false, show_info: false); end
|
||||||
|
|
||||||
|
sig { params(name: String, command: String).returns(T.nilable(String)) }
|
||||||
def suggest_command(name, command); end
|
def suggest_command(name, command); end
|
||||||
|
|
||||||
require "extend/os/missing_formula"
|
require "extend/os/missing_formula"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "requirement"
|
require "requirement"
|
||||||
@ -7,10 +7,14 @@ require "requirement"
|
|||||||
class ArchRequirement < Requirement
|
class ArchRequirement < Requirement
|
||||||
fatal true
|
fatal true
|
||||||
|
|
||||||
|
@arch = T.let(nil, T.nilable(Symbol))
|
||||||
|
|
||||||
|
sig { returns(T.nilable(Symbol)) }
|
||||||
attr_reader :arch
|
attr_reader :arch
|
||||||
|
|
||||||
|
sig { params(tags: T::Array[Symbol]).void }
|
||||||
def initialize(tags)
|
def initialize(tags)
|
||||||
@arch = tags.shift
|
@arch = T.let(tags.shift, T.nilable(Symbol))
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "requirement"
|
require "requirement"
|
||||||
@ -7,6 +7,7 @@ require "requirement"
|
|||||||
class XcodeRequirement < Requirement
|
class XcodeRequirement < Requirement
|
||||||
fatal true
|
fatal true
|
||||||
|
|
||||||
|
sig { returns(T.nilable(String)) }
|
||||||
attr_reader :version
|
attr_reader :version
|
||||||
|
|
||||||
satisfy(build_env: false) do
|
satisfy(build_env: false) do
|
||||||
@ -14,8 +15,10 @@ class XcodeRequirement < Requirement
|
|||||||
xcode_installed_version
|
xcode_installed_version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(tags: T::Array[String]).void }
|
||||||
def initialize(tags = [])
|
def initialize(tags = [])
|
||||||
@version = tags.shift if tags.first.to_s.match?(/(\d\.)+\d/)
|
version = tags.shift if tags.first.to_s.match?(/(\d\.)+\d/)
|
||||||
|
@version = T.let(version, T.nilable(String))
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -53,6 +56,7 @@ class XcodeRequirement < Requirement
|
|||||||
"#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>"
|
"#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
def display_s
|
def display_s
|
||||||
return "#{name.capitalize} (on macOS)" unless @version
|
return "#{name.capitalize} (on macOS)" unless @version
|
||||||
|
|
||||||
|
@ -9,9 +9,6 @@ class Cask::Cask
|
|||||||
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
|
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
|
||||||
def app(*args, &block); end
|
def app(*args, &block); end
|
||||||
|
|
||||||
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
|
|
||||||
def appcast(*args, &block); end
|
|
||||||
|
|
||||||
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
|
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
|
||||||
def appdir(*args, &block); end
|
def appdir(*args, &block); end
|
||||||
|
|
||||||
|
58
Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi
Normal file
58
Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# typed: true
|
||||||
|
|
||||||
|
# DO NOT EDIT MANUALLY
|
||||||
|
# This is an autogenerated file for dynamic methods in `Cask::Config`.
|
||||||
|
# Please instead update this file by running `bin/tapioca dsl Cask::Config`.
|
||||||
|
|
||||||
|
|
||||||
|
module Cask
|
||||||
|
class Config
|
||||||
|
sig { returns(String) }
|
||||||
|
def appdir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def audio_unit_plugindir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def colorpickerdir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def dictionarydir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def fontdir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def input_methoddir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def internet_plugindir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def keyboard_layoutdir; end
|
||||||
|
|
||||||
|
sig { returns(T::Array[String]) }
|
||||||
|
def languages; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def mdimporterdir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def prefpanedir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def qlplugindir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def screen_saverdir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def servicedir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def vst3_plugindir; end
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def vst_plugindir; end
|
||||||
|
end
|
||||||
|
end
|
@ -23,9 +23,6 @@ class Homebrew::Cmd::TapCmd::Args < Homebrew::CLI::Args
|
|||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def force?; end
|
def force?; end
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
|
||||||
def force_auto_update?; end
|
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def repair?; end
|
def repair?; end
|
||||||
end
|
end
|
||||||
|
37
Library/Homebrew/sorbet/tapioca/compilers/cask/config.rb
Normal file
37
Library/Homebrew/sorbet/tapioca/compilers/cask/config.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# typed: strict
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative "../../../../global"
|
||||||
|
require "cask/config"
|
||||||
|
|
||||||
|
module Tapioca
|
||||||
|
module Compilers
|
||||||
|
class CaskConfig < Tapioca::Dsl::Compiler
|
||||||
|
ConstantType = type_member { { fixed: Module } }
|
||||||
|
|
||||||
|
sig { override.returns(T::Enumerable[Module]) }
|
||||||
|
def self.gather_constants = [Cask::Config]
|
||||||
|
|
||||||
|
sig { override.void }
|
||||||
|
def decorate
|
||||||
|
root.create_module("Cask") do |mod|
|
||||||
|
mod.create_class("Config") do |klass|
|
||||||
|
Cask::Config.defaults.each do |key, value|
|
||||||
|
return_type = if key == :languages
|
||||||
|
# :languages is a `LazyObject`, so it lazily evaluates to an
|
||||||
|
# array of strings when a method is called on it.
|
||||||
|
"T::Array[String]"
|
||||||
|
elsif key.end_with?("?")
|
||||||
|
"T::Boolean"
|
||||||
|
else
|
||||||
|
value.class.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
klass.create_method(key.to_s, return_type:, class_method: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -128,10 +128,12 @@ module SystemConfig
|
|||||||
out.puts "#{tap_name} origin: #{tap.remote}" if tap.remote != tap.default_remote
|
out.puts "#{tap_name} origin: #{tap.remote}" if tap.remote != tap.default_remote
|
||||||
out.puts "#{tap_name} HEAD: #{tap.git_head || "(none)"}"
|
out.puts "#{tap_name} HEAD: #{tap.git_head || "(none)"}"
|
||||||
out.puts "#{tap_name} last commit: #{tap.git_last_commit || "never"}"
|
out.puts "#{tap_name} last commit: #{tap.git_last_commit || "never"}"
|
||||||
out.puts "#{tap_name} branch: #{tap.git_branch || "(none)"}" if tap.git_branch != "master"
|
default_branches = %w[main master].freeze
|
||||||
|
out.puts "#{tap_name} branch: #{tap.git_branch || "(none)"}" if default_branches.exclude?(tap.git_branch)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (json_file = Homebrew::API::HOMEBREW_CACHE_API/json_file_name) && json_file.exist?
|
json_file = Homebrew::API::HOMEBREW_CACHE_API/json_file_name
|
||||||
|
if json_file.exist?
|
||||||
out.puts "#{tap_name} JSON: #{json_file.mtime.utc.strftime("%d %b %H:%M UTC")}"
|
out.puts "#{tap_name} JSON: #{json_file.mtime.utc.strftime("%d %b %H:%M UTC")}"
|
||||||
elsif !tap.installed?
|
elsif !tap.installed?
|
||||||
out.puts "#{tap_name}: N/A"
|
out.puts "#{tap_name}: N/A"
|
||||||
@ -194,7 +196,6 @@ module SystemConfig
|
|||||||
out.puts hardware if hardware
|
out.puts hardware if hardware
|
||||||
host_software_config(out)
|
host_software_config(out)
|
||||||
end
|
end
|
||||||
alias dump_generic_verbose_config dump_verbose_config
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ RSpec.describe Homebrew::Bundle::Dsl do
|
|||||||
cask_args appdir: '/Applications'
|
cask_args appdir: '/Applications'
|
||||||
tap 'homebrew/cask'
|
tap 'homebrew/cask'
|
||||||
tap 'telemachus/brew', 'https://telemachus@bitbucket.org/telemachus/brew.git'
|
tap 'telemachus/brew', 'https://telemachus@bitbucket.org/telemachus/brew.git'
|
||||||
tap 'auto/update', 'https://bitbucket.org/auto/update.git', force_auto_update: true
|
tap 'auto/update', 'https://bitbucket.org/auto/update.git'
|
||||||
brew 'imagemagick'
|
brew 'imagemagick'
|
||||||
brew 'mysql@5.6', restart_service: true, link: true, conflicts_with: ['mysql']
|
brew 'mysql@5.6', restart_service: true, link: true, conflicts_with: ['mysql']
|
||||||
brew 'emacs', args: ['with-cocoa', 'with-gnutls'], link: :overwrite
|
brew 'emacs', args: ['with-cocoa', 'with-gnutls'], link: :overwrite
|
||||||
@ -40,10 +40,7 @@ RSpec.describe Homebrew::Bundle::Dsl do
|
|||||||
expect(dsl.entries[0].name).to eql("homebrew/cask")
|
expect(dsl.entries[0].name).to eql("homebrew/cask")
|
||||||
expect(dsl.entries[1].name).to eql("telemachus/brew")
|
expect(dsl.entries[1].name).to eql("telemachus/brew")
|
||||||
expect(dsl.entries[1].options).to eql(clone_target: "https://telemachus@bitbucket.org/telemachus/brew.git")
|
expect(dsl.entries[1].options).to eql(clone_target: "https://telemachus@bitbucket.org/telemachus/brew.git")
|
||||||
expect(dsl.entries[2].options).to eql(
|
expect(dsl.entries[2].options).to eql(clone_target: "https://bitbucket.org/auto/update.git")
|
||||||
clone_target: "https://bitbucket.org/auto/update.git",
|
|
||||||
force_auto_update: true,
|
|
||||||
)
|
|
||||||
expect(dsl.entries[3].name).to eql("imagemagick")
|
expect(dsl.entries[3].name).to eql("imagemagick")
|
||||||
expect(dsl.entries[4].name).to eql("mysql@5.6")
|
expect(dsl.entries[4].name).to eql("mysql@5.6")
|
||||||
expect(dsl.entries[4].options).to eql(restart_service: true, link: true, conflicts_with: ["mysql"])
|
expect(dsl.entries[4].options).to eql(restart_service: true, link: true, conflicts_with: ["mysql"])
|
||||||
|
@ -55,25 +55,5 @@ RSpec.describe Homebrew::Bundle::TapInstaller do
|
|||||||
expect(described_class.install("homebrew/cask", clone_target: "clone_target_path")).to be(false)
|
expect(described_class.install("homebrew/cask", clone_target: "clone_target_path")).to be(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with force_auto_update" do
|
|
||||||
it "taps" do
|
|
||||||
expect(Homebrew::Bundle).to receive(:system).with(HOMEBREW_BREW_FILE, "tap", "homebrew/cask",
|
|
||||||
"--force-auto-update",
|
|
||||||
verbose: false)
|
|
||||||
.and_return(true)
|
|
||||||
expect(described_class.preinstall("homebrew/cask", force_auto_update: true)).to be(true)
|
|
||||||
expect(described_class.install("homebrew/cask", force_auto_update: true)).to be(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails" do
|
|
||||||
expect(Homebrew::Bundle).to receive(:system).with(HOMEBREW_BREW_FILE, "tap", "homebrew/cask",
|
|
||||||
"--force-auto-update",
|
|
||||||
verbose: false)
|
|
||||||
.and_return(false)
|
|
||||||
expect(described_class.preinstall("homebrew/cask", force_auto_update: true)).to be(true)
|
|
||||||
expect(described_class.install("homebrew/cask", force_auto_update: true)).to be(false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@ RSpec.describe Cask::Artifact::Artifact, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "without target" do
|
context "without target" do
|
||||||
it "fails to load" do
|
it "fails to load", :no_api do
|
||||||
expect do
|
expect do
|
||||||
Cask::CaskLoader.load("invalid-generic-artifact-no-target")
|
Cask::CaskLoader.load("invalid-generic-artifact-no-target")
|
||||||
end.to raise_error(Cask::CaskInvalidError, /Generic Artifact.*requires.*target/)
|
end.to raise_error(Cask::CaskInvalidError, /Generic Artifact.*requires.*target/)
|
||||||
|
@ -6,7 +6,7 @@ RSpec.describe Cask::Artifact::Manpage, :cask do
|
|||||||
context "without section" do
|
context "without section" do
|
||||||
let(:cask_token) { "invalid-manpage-no-section" }
|
let(:cask_token) { "invalid-manpage-no-section" }
|
||||||
|
|
||||||
it "fails to load a cask without section" do
|
it "fails to load a cask without section", :no_api do
|
||||||
expect { cask }.to raise_error(Cask::CaskInvalidError, /is not a valid man page name/)
|
expect { cask }.to raise_error(Cask::CaskInvalidError, /is not a valid man page name/)
|
||||||
end
|
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