diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 8d4100bfe2..b134ebcfd5 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,38 +1,47 @@ name: New issue for Reproducible Bug -about: "If you're sure it's reproducible and not just your machine: submit an issue so we can investigate." +description: "If you're sure it's reproducible and not just your machine: submit an issue so we can investigate." labels: bug issue_body: false -inputs: - - type: description +body: + - type: markdown attributes: value: Please note we will close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again. - type: textarea attributes: + render: shell label: "`brew config` output" + validations: required: true - type: textarea attributes: + render: shell label: "`brew doctor` output" + validations: required: true - type: checkboxes attributes: description: Please verify that you've followed these steps - choices: + options: - label: The `brew doctor` above contains no "Warning" lines. required: true - type: textarea attributes: label: What were you trying to do (and why)? + validations: required: true - type: textarea attributes: label: What happened (include all command output)? + validations: required: true - type: textarea attributes: label: What did you expect to happen? + validations: required: true - type: textarea attributes: + render: shell label: Step-by-step reproduction instructions (by running `brew` commands) + validations: required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 2b86eeb838..841c4e6aa9 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -9,7 +9,7 @@ contact_links: about: On macOS/Mac OS X? Having a `brew` problem with a `brew install` or `brew upgrade` of a single formula/package? Report it to Homebrew/homebrew-core (the macOS core tap/repository). - name: New issue on Homebrew/homebrew-cask url: https://github.com/Homebrew/homebrew-cask/issues/new/choose - about: Having a `brew cask` problem? Report it to Homebrew/homebrew-cask (the cask tap/repository). + about: Having a `brew --cask` problem? Report it to Homebrew/homebrew-cask (the cask tap/repository). - name: New issue on Homebrew/linuxbrew-core url: https://github.com/Homebrew/linuxbrew-core/issues/new/choose about: On Linux? Having a `brew` problem with a `brew install` or `brew upgrade` of a single formula/package? Report it to Homebrew/linuxbrew-core (the Linux core tap/repository). diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 361f7b0ac3..f946196101 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -1,27 +1,31 @@ name: New issue for Feature Suggestion -about: Request our thoughts on your suggestion for a new feature for Homebrew. +description: Request our thoughts on your suggestion for a new feature for Homebrew. labels: features issue_body: false -inputs: - - type: description +body: + - type: markdown attributes: value: Please note we will close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again. - type: textarea attributes: label: Provide a detailed description of the proposed feature + validations: required: true - type: textarea attributes: label: What is the motivation for the feature? + validations: required: true - type: textarea attributes: label: How will the feature be relevant to at least 90% of Homebrew users? + validations: required: true - type: textarea attributes: label: What alternatives to the feature have been considered? + validations: required: true - - type: description + - type: markdown attributes: value: We will close this issue or ask you to create a pull-request if it's something the maintainers are not actively planning to work on. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7dd8621f00..ff375f8801 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,6 +5,5 @@ - [ ] Have you successfully run `brew style` with your changes locally? - [ ] Have you successfully run `brew typecheck` with your changes locally? - [ ] Have you successfully run `brew tests` with your changes locally? -- [ ] Have you successfully run `brew man` locally and committed any changes? ----- diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b3ed8e6483..353e0bc22f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,10 +10,14 @@ updates: directory: /docs schedule: interval: weekly + allow: + - dependency-type: all - package-ecosystem: bundler directory: /Library/Homebrew schedule: interval: daily + allow: + - dependency-type: all ignore: - dependency-name: sorbet-runtime diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 6cfcff8c73..de25c282c2 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -16,7 +16,7 @@ jobs: tests: strategy: matrix: - version: ['11-arm', '11.0', '10.15', '10.14'] + version: ["11-arm", "11.0", "10.15", "10.14"] fail-fast: false runs-on: ${{ matrix.version }} env: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 97326fa971..1421642658 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,8 +31,6 @@ jobs: - run: brew style --display-cop-names - - run: brew man --fail-if-changed - - run: brew typecheck - name: Run vale for docs linting @@ -81,6 +79,58 @@ jobs: - name: Run brew audit --skip-style on all taps run: brew audit --skip-style + - name: Set up all Homebrew taps + run: | + HOMEBREW_REPOSITORY="$(brew --repo)" + HOMEBREW_CORE_REPOSITORY="$HOMEBREW_REPOSITORY/Library/Taps/homebrew/homebrew-core" + git -C "$HOMEBREW_CORE_REPOSITORY" remote add homebrew_core https://github.com/Homebrew/homebrew-core + git -C "$HOMEBREW_CORE_REPOSITORY" fetch homebrew_core || git -C "$HOMEBREW_CORE_REPOSITORY" fetch homebrew_core + git -C "$HOMEBREW_CORE_REPOSITORY" checkout --force -B master homebrew_core/master + + brew tap homebrew/aliases + brew tap homebrew/bundle + brew tap homebrew/cask + brew tap homebrew/cask-drivers + brew tap homebrew/cask-fonts + brew tap homebrew/cask-versions + brew tap homebrew/command-not-found + brew tap homebrew/formula-analytics + brew tap homebrew/linux-dev + brew tap homebrew/portable-ruby + brew tap homebrew/services + + brew update-reset Library/Taps/homebrew/homebrew-bundle + + # brew style doesn't like world writable directories + sudo chmod -R g-w,o-w "$HOMEBREW_REPOSITORY/Library/Taps" + + - name: Run brew style on homebrew-core + run: brew style --display-cop-names homebrew/core + + - name: Run brew audit --skip-style on homebrew-core + run: brew audit --skip-style --tap=homebrew/core + env: + HOMEBREW_SIMULATE_MACOS_ON_LINUX: 1 + + - name: Run brew style on official taps + run: | + brew style --display-cop-names homebrew/bundle \ + homebrew/services \ + homebrew/test-bot + + brew style --display-cop-names homebrew/aliases\ + homebrew/command-not-found \ + homebrew/formula-analytics \ + homebrew/linux-dev \ + homebrew/portable-ruby + + - name: Run brew style on cask taps + run: | + brew style --display-cop-names homebrew/cask \ + homebrew/cask-drivers \ + homebrew/cask-fonts \ + homebrew/cask-versions + vendored-gems: name: vendored gems (Linux) runs-on: ubuntu-latest @@ -231,29 +281,17 @@ jobs: - name: Run brew readall on all taps run: brew readall --aliases - - name: Run brew style on homebrew-core - run: brew style --display-cop-names homebrew/core - - - name: Run brew style on official taps + - name: Run brew audit --skip-style on Cask taps run: | - brew style --display-cop-names homebrew/bundle \ - homebrew/services \ - homebrew/test-bot - - - name: Run brew style on cask taps - run: | - brew style --display-cop-names homebrew/cask \ - homebrew/cask-drivers \ - homebrew/cask-fonts \ - homebrew/cask-versions - - - name: Run brew audit --skip-style on all taps - run: brew audit --skip-style + brew audit --skip-style --tap=homebrew/cask + brew audit --skip-style --tap=homebrew/cask-drivers + brew audit --skip-style --tap=homebrew/cask-fonts + brew audit --skip-style --tap=homebrew/cask-versions - name: Install brew tests dependencies run: | brew install subversion - Library/Homebrew/shims/scm/svn --homebrew=print-path + brew sh -c "svn --homebrew=print-path" which svn which svnadmin diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 9d551c86f4..857f3986d0 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Re-run this workflow if: github.event_name == 'schedule' || github.event.action == 'closed' - uses: reitermarkus/rerun-workflow@e2647e8885422412d5acbd61f9add5b1e77ad3ab + uses: reitermarkus/rerun-workflow@64cba9e834916060e77b7dad424d086837fdd0a6 with: token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} continuous-label: waiting for feedback diff --git a/.github/workflows/update-manpage.yml b/.github/workflows/update-manpage.yml new file mode 100644 index 0000000000..66ac852d53 --- /dev/null +++ b/.github/workflows/update-manpage.yml @@ -0,0 +1,82 @@ +name: Update maintainers, manpage and completions + +on: + push: + paths: + - .github/workflows/update-manpage.yml + - README.md + - Library/Homebrew/cmd/** + - Library/Homebrew/dev-cmd/** + - Library/Homebrew/completions/** + - Library/Homebrew/manpages/** + - Library/Homebrew/cli/parser.rb + - Library/Homebrew/completions.rb + - Library/Homebrew/env_config.rb + branches: + - master + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + update-manpage: + runs-on: ubuntu-latest + if: github.repository == 'Homebrew/brew' + steps: + - name: Setup Homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Configure Git user + uses: Homebrew/actions/git-user-config@master + with: + username: BrewTestBot + + - name: Update maintainers, manpage and completions + id: update + run: | + git fetch origin + + BRANCH=update-manpage + echo "::set-output name=branch::${BRANCH}" + + if git ls-remote --exit-code --heads origin "$BRANCH"; then + git checkout "$BRANCH" + git reset --hard origin/master + else + git checkout -B "$BRANCH" origin/master + BRANCH_EXISTS="1" + fi + + if [ "${{github.event_name}}" != "push" ]; then + brew update-maintainers + fi + + if brew man --fail-if-not-changed; then + git add "$GITHUB_WORKSPACE/README.md" \ + "$GITHUB_WORKSPACE/docs/Manpage.md" \ + "$GITHUB_WORKSPACE/manpages/brew.1" \ + "$GITHUB_WORKSPACE/completions" + git commit -m "Update maintainers, manpage and completions." \ + -m "Autogenerated by the [update-manpage](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/update-manpage.yml) workflow." + echo "::set-output name=committed::true" + if [ -n "$BRANCH_EXISTS" ]; then + echo "::set-output name=pull_request::true" + fi + fi + env: + HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} + + - name: Push commits + if: steps.update.outputs.committed == 'true' + uses: Homebrew/actions/git-try-push@master + with: + token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} + branch: ${{ steps.update.outputs.branch }} + force: true + origin_branch: "master" + + - name: Open a pull request + if: steps.update.outputs.pull_request == 'true' + run: hub pull-request --no-edit + env: + GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} diff --git a/Dockerfile b/Dockerfile index ee0fec3ee5..1819ad0464 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,7 @@ RUN apt-get update \ file \ fonts-dejavu-core \ g++ \ + gawk \ git \ less \ libz-dev \ diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 5769367b8a..e15f7840a6 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -240,6 +240,12 @@ Layout/SpaceAroundOperators: Layout/RescueEnsureAlignment: Enabled: false +# significantly less indentation involved; more consistent +Layout/FirstArrayElementIndentation: + EnforcedStyle: consistent +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + # favour parens-less DSL-style arguments Lint/AmbiguousBlockAssociation: Enabled: false @@ -255,14 +261,6 @@ Naming/MemoizedInstanceVariableName: Exclude: - "Homebrew/lazy_object.rb" -# so many of these in formulae and can't be autocorrected -# TODO: fix these as `ruby -w` complains about them. -Lint/AmbiguousRegexpLiteral: - Exclude: - - "Taps/*/*/*.rb" - - "/**/Formula/*.rb" - - "**/Formula/*.rb" - # useful for metaprogramming in RSpec Lint/ConstantDefinitionInBlock: Exclude: @@ -462,6 +460,11 @@ Style/StringLiteralsInInterpolation: Style/TernaryParentheses: EnforcedStyle: require_parentheses_when_complex +# `unless ... ||` and `unless ... &&` are hard to mentally parse +Style/UnlessLogicalOperators: + Enabled: true + EnforcedStyle: forbid_logical_operators + # a bit confusing to non-Rubyists but useful for longer arrays Style/WordArray: MinSize: 4 diff --git a/Library/.rubocop_rspec.yml b/Library/.rubocop_rspec.yml index 5a47d33451..1cc0a316d4 100644 --- a/Library/.rubocop_rspec.yml +++ b/Library/.rubocop_rspec.yml @@ -11,8 +11,6 @@ RSpec/SubjectStub: Enabled: false # TODO: try to enable these -RSpec/ContextWording: - Enabled: false RSpec/DescribeClass: Enabled: false RSpec/LeakyConstantDeclaration: @@ -21,8 +19,6 @@ RSpec/MessageSpies: Enabled: false RSpec/RepeatedDescription: Enabled: false -RSpec/RepeatedExampleGroupDescription: - Enabled: false RSpec/StubbedMock: Enabled: false diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml index b5cdb52bf7..63a44e0bad 100644 --- a/Library/Homebrew/.rubocop.yml +++ b/Library/Homebrew/.rubocop.yml @@ -7,10 +7,6 @@ Layout/MultilineMethodCallIndentation: Exclude: - "**/*_spec.rb" -# TODO: add parentheses for these and remove -Lint/AssignmentInCondition: - Enabled: false - # `formula do` uses nested method definitions Lint/NestedMethodDefinition: Exclude: @@ -36,9 +32,8 @@ Metrics/PerceivedComplexity: Max: 90 Metrics/MethodLength: Max: 260 -# TODO: Reduce to 600 after refactoring utils/github Metrics/ModuleLength: - Max: 620 + Max: 600 Exclude: - "test/**/*" diff --git a/Library/Homebrew/Gemfile b/Library/Homebrew/Gemfile index d76ebf5fa8..8dfd6cb0af 100644 --- a/Library/Homebrew/Gemfile +++ b/Library/Homebrew/Gemfile @@ -5,6 +5,7 @@ source "https://rubygems.org" # installed gems (should all be require: false) gem "bootsnap", require: false gem "byebug", require: false +gem "minitest", require: false gem "nokogiri", require: false gem "parallel_tests", require: false gem "ronn", require: false @@ -20,6 +21,7 @@ gem "simplecov", require: false gem "sorbet", require: false gem "sorbet-runtime", require: false gem "tapioca", require: false +gem "warning", require: false # vendored gems gem "activesupport" diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 49320b0379..81739b74bf 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.1.2) + activesupport (6.1.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -28,7 +28,7 @@ GEM hpricot (0.8.6) http-cookie (1.0.3) domain_name (~> 0.5) - i18n (1.8.8) + i18n (1.8.9) concurrent-ruby (~> 1.0) mechanize (2.7.7) domain_name (~> 0.5, >= 0.5.1) @@ -43,22 +43,22 @@ GEM method_source (1.0.0) mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2020.1104) + mime-types-data (3.2021.0212) mini_portile2 (2.5.0) - minitest (5.14.3) + minitest (5.14.4) msgpack (1.4.2) mustache (1.1.1) net-http-digest_auth (1.4.1) net-http-persistent (4.0.1) connection_pool (~> 2.2) - nokogiri (1.11.1) + nokogiri (1.11.2) mini_portile2 (~> 2.5.0) racc (~> 1.4) ntlm-http (0.1.1) parallel (1.20.1) - parallel_tests (3.4.0) + parallel_tests (3.5.2) parallel - parlour (5.0.0) + parlour (6.0.0) commander (~> 4.5) parser rainbow (~> 3.0) @@ -68,14 +68,14 @@ GEM patchelf (1.3.0) elftools (>= 1.1.3) plist (3.6.0) - pry (0.13.1) + pry (0.14.0) coderay (~> 1.1) method_source (~> 1.0) racc (1.5.2) rack (2.2.3) rainbow (3.0.0) rdiscount (2.2.0.2) - regexp_parser (2.0.3) + regexp_parser (2.1.1) rexml (3.2.4) ronn (0.7.3) hpricot (>= 0.8.2) @@ -85,9 +85,9 @@ GEM rspec-core (~> 3.10.0) rspec-expectations (~> 3.10.0) rspec-mocks (~> 3.10.0) - rspec-core (3.10.0) + rspec-core (3.10.1) rspec-support (~> 3.10.0) - rspec-expectations (3.10.0) + rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) rspec-github (2.3.1) @@ -95,7 +95,7 @@ GEM rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.10.0) + rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) rspec-retry (0.6.2) @@ -103,10 +103,10 @@ GEM rspec-sorbet (1.8.0) sorbet sorbet-runtime - rspec-support (3.10.0) + rspec-support (3.10.2) rspec-wait (0.0.9) rspec (>= 3, < 4) - rubocop (1.9.1) + rubocop (1.11.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -117,7 +117,7 @@ GEM unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.4.1) parser (>= 2.7.1.5) - rubocop-performance (1.9.2) + rubocop-performance (1.10.1) rubocop (>= 0.90.0, < 2.0) rubocop-ast (>= 0.4.0) rubocop-rails (2.9.1) @@ -127,7 +127,7 @@ GEM rubocop-rspec (2.2.0) rubocop (~> 1.0) rubocop-ast (>= 1.1.0) - rubocop-sorbet (0.5.1) + rubocop-sorbet (0.6.1) rubocop ruby-macho (2.5.0) ruby-progressbar (1.11.0) @@ -139,28 +139,30 @@ GEM simplecov_json_formatter (0.1.2) sorbet (0.5.6274) sorbet-static (= 0.5.6274) - sorbet-runtime (0.5.6267) + sorbet-runtime (0.5.6274) sorbet-runtime-stub (0.2.0) sorbet-static (0.5.6274-universal-darwin-14) - spoom (1.0.7) + spoom (1.0.9) colorize sorbet (~> 0.5.5) sorbet-runtime thor (>= 0.19.2) - tapioca (0.4.13) + tapioca (0.4.17) + bundler (>= 1.17.3) parlour (>= 2.1.0) pry (>= 0.12.2) sorbet-runtime sorbet-static (>= 0.4.4471) spoom thor (>= 0.19.2) - thor (1.0.1) + thor (1.1.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) unf (0.1.4) unf_ext unf_ext (0.0.7.7) unicode-display_width (2.0.0) + warning (1.2.0) webrick (1.7.0) webrobots (0.1.2) zeitwerk (2.4.2) @@ -174,6 +176,7 @@ DEPENDENCIES byebug concurrent-ruby mechanize + minitest nokogiri parallel_tests patchelf @@ -197,6 +200,7 @@ DEPENDENCIES sorbet-runtime sorbet-runtime-stub tapioca + warning BUNDLED WITH 1.17.3 diff --git a/Library/Homebrew/archive.rb b/Library/Homebrew/archive.rb new file mode 100644 index 0000000000..46e4e6a64b --- /dev/null +++ b/Library/Homebrew/archive.rb @@ -0,0 +1,180 @@ +# typed: false +# frozen_string_literal: true + +require "digest/md5" +require "utils/curl" + +# The Internet Archive API client. +# +# @api private +class Archive + extend T::Sig + + include Context + include Utils::Curl + + class Error < RuntimeError + end + + URL_PREFIX = "https://archive.org" + S3_DOMAIN = "s3.us.archive.org" + + sig { returns(String) } + def inspect + "#" + end + + sig { params(item: T.nilable(String)).void } + def initialize(item: "homebrew") + raise UsageError, "Must set the Archive item!" unless item + + @archive_item = item + end + + def open_api(url, *args, auth: true) + if auth + key = Homebrew::EnvConfig.internet_archive_key + raise UsageError, "HOMEBREW_INTERNET_ARCHIVE_KEY is unset." if key.blank? + + if key.exclude?(":") + raise UsageError, "Use HOMEBREW_INTERNET_ARCHIVE_KEY=access:secret. See #{URL_PREFIX}/account/s3.php" + end + + args += ["--header", "Authorization: AWS #{key}"] + end + + curl(*args, url, print_stdout: false, secrets: key) + end + + sig { + params(local_file: String, + directory: String, + remote_file: String, + warn_on_error: T.nilable(T::Boolean)).void + } + def upload(local_file, directory:, remote_file:, warn_on_error: false) + local_file = Pathname.new(local_file) + unless local_file.exist? + msg = "#{local_file} for upload doesn't exist!" + raise Error, msg unless warn_on_error + + # Warn and return early here since we know this upload is going to fail. + opoo msg + return + end + + md5_base64 = Digest::MD5.base64digest(local_file.read) + url = "https://#{@archive_item}.#{S3_DOMAIN}/#{directory}/#{remote_file}" + args = ["--upload-file", local_file, "--header", "Content-MD5: #{md5_base64}"] + args << "--fail" unless warn_on_error + result = T.unsafe(self).open_api(url, *args) + return if result.success? && result.stdout.exclude?("Error") + + msg = "Bottle upload failed: #{result.stdout}" + raise msg unless warn_on_error + + opoo msg + end + + sig { + params(formula: Formula, + directory: String, + warn_on_error: T::Boolean).returns(String) + } + def mirror_formula(formula, directory: "mirror", warn_on_error: false) + formula.downloader.fetch + + filename = ERB::Util.url_encode(formula.downloader.basename) + destination_url = "#{URL_PREFIX}/download/#{@archive_item}/#{directory}/#{filename}" + + odebug "Uploading to #{destination_url}" + + upload( + formula.downloader.cached_location, + directory: directory, + remote_file: filename, + warn_on_error: warn_on_error, + ) + + destination_url + end + + # Gets the MD5 hash of the specified remote file. + # + # @return the hash, the empty string (if the file doesn't have a hash), nil (if the file doesn't exist) + sig { params(directory: String, remote_file: String).returns(T.nilable(String)) } + def remote_md5(directory:, remote_file:) + url = "https://#{@archive_item}.#{S3_DOMAIN}/#{directory}/#{remote_file}" + result = curl_output "--fail", "--silent", "--head", "--location", url + if result.success? + result.stdout.match(/^ETag: "(\h{32})"/)&.values_at(1)&.first || "" + else + raise Error if result.status.exitstatus != 22 && result.stderr.exclude?("404 Not Found") + + nil + end + end + + sig { params(directory: String, filename: String).returns(String) } + def file_delete_instructions(directory, filename) + <<~EOS + Run: + curl -X DELETE -H "Authorization: AWS $HOMEBREW_INTERNET_ARCHIVE_KEY" https://#{@archive_item}.#{S3_DOMAIN}/#{directory}/#{filename} + Or run: + ia delete #{@archive_item} #{directory}/#{filename} + EOS + end + + sig { + params(bottles_hash: T::Hash[String, T.untyped], + warn_on_error: T.nilable(T::Boolean)).void + } + def upload_bottles(bottles_hash, warn_on_error: false) + bottles_hash.each do |_formula_name, bottle_hash| + directory = bottle_hash["bintray"]["repository"] + bottle_count = bottle_hash["bottle"]["tags"].length + + bottle_hash["bottle"]["tags"].each_value do |tag_hash| + filename = tag_hash["filename"] # URL encoded in Bottle::Filename#archive + delete_instructions = file_delete_instructions(directory, filename) + + local_filename = tag_hash["local_filename"] + md5 = Digest::MD5.hexdigest(File.read(local_filename)) + + odebug "Checking remote file #{@archive_item}/#{directory}/#{filename}" + result = remote_md5(directory: directory, remote_file: filename) + case result + when nil + # File doesn't exist. + odebug "Uploading #{@archive_item}/#{directory}/#{filename}" + upload(local_filename, + directory: directory, + remote_file: filename, + warn_on_error: warn_on_error) + when md5 + # File exists, hash matches. + odebug "#{filename} is already published with matching hash." + bottle_count -= 1 + when "" + # File exists, but can't find hash + failed_message = "#{filename} is already published!" + raise Error, "#{failed_message}\n#{delete_instructions}" unless warn_on_error + + opoo failed_message + else + # File exists, but hash either doesn't exist or is mismatched. + failed_message = <<~EOS + #{filename} is already published with a mismatched hash! + Expected: #{md5} + Actual: #{result} + EOS + raise Error, "#{failed_message}#{delete_instructions}" unless warn_on_error + + opoo failed_message + end + end + + odebug "Uploaded #{bottle_count} bottles" + end + end +end diff --git a/Library/Homebrew/bintray.rb b/Library/Homebrew/bintray.rb index ddba6adcac..0290903641 100644 --- a/Library/Homebrew/bintray.rb +++ b/Library/Homebrew/bintray.rb @@ -14,6 +14,7 @@ class Bintray include Utils::Curl API_URL = "https://api.bintray.com" + URL_REGEX = %r{^https://[\w-]+\.bintray\.com/}.freeze class Error < RuntimeError end diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 7feeac9f23..b653558c5b 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -48,7 +48,6 @@ HOMEBREW_TEMP="${HOMEBREW_TEMP:-${HOMEBREW_DEFAULT_TEMP}}" # Don't need shellcheck to follow these `source`. # shellcheck disable=SC1090 case "$*" in - --prefix) echo "$HOMEBREW_PREFIX"; exit 0 ;; --cellar) echo "$HOMEBREW_CELLAR"; exit 0 ;; --repository|--repo) echo "$HOMEBREW_REPOSITORY"; exit 0 ;; --caskroom) echo "$HOMEBREW_PREFIX/Caskroom"; exit 0 ;; @@ -56,6 +55,8 @@ case "$*" in shellenv) source "$HOMEBREW_LIBRARY/Homebrew/cmd/shellenv.sh"; homebrew-shellenv; exit 0 ;; formulae) source "$HOMEBREW_LIBRARY/Homebrew/cmd/formulae.sh"; homebrew-formulae; exit 0 ;; casks) source "$HOMEBREW_LIBRARY/Homebrew/cmd/casks.sh"; homebrew-casks; exit 0 ;; + # falls back to cmd/prefix.rb on a non-zero return + --prefix*) source "$HOMEBREW_LIBRARY/Homebrew/prefix.sh"; homebrew-prefix "$@" && exit 0 ;; esac ##### @@ -187,9 +188,9 @@ update-preinstall() { # last $HOMEBREW_AUTO_UPDATE_SECS. if [[ "$HOMEBREW_COMMAND" = "cask" ]] then - tap_fetch_head="$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-cask/.git/FETCH_HEAD" + tap_fetch_head="$HOMEBREW_CASK_REPOSITORY/.git/FETCH_HEAD" else - tap_fetch_head="$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core/.git/FETCH_HEAD" + tap_fetch_head="$HOMEBREW_CORE_REPOSITORY/.git/FETCH_HEAD" fi if [[ -f "$tap_fetch_head" && -n "$(find "$tap_fetch_head" -type f -mtime -"${HOMEBREW_AUTO_UPDATE_SECS}"s 2>/dev/null)" ]] @@ -313,6 +314,20 @@ then HOMEBREW_USER_AGENT_VERSION="2.X.Y" fi +HOMEBREW_CASK_REPOSITORY="$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-cask" +HOMEBREW_CORE_REPOSITORY="$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" + +# Don't need shellcheck to follow these `source`. +# shellcheck disable=SC1090 +case "$*" in + --version|-v) source "$HOMEBREW_LIBRARY/Homebrew/cmd/--version.sh"; homebrew-version; exit 0 ;; +esac + +if [[ -n "$HOMEBREW_SIMULATE_MACOS_ON_LINUX" ]] +then + export HOMEBREW_FORCE_HOMEBREW_ON_LINUX="1" +fi + if [[ -n "$HOMEBREW_MACOS" ]] then HOMEBREW_PRODUCT="Homebrew" @@ -439,13 +454,6 @@ curl_version_output="$("$HOMEBREW_CURL" --version 2>/dev/null)" curl_name_and_version="${curl_version_output%% (*}" HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT ${curl_name_and_version// //}" -# Declared in bin/brew -export HOMEBREW_BREW_FILE -export HOMEBREW_PREFIX -export HOMEBREW_REPOSITORY -export HOMEBREW_LIBRARY - -# Declared in brew.sh export HOMEBREW_VERSION export HOMEBREW_DEFAULT_CACHE export HOMEBREW_CACHE @@ -567,16 +575,16 @@ then # Don't allow non-developers to customise Ruby warnings. unset HOMEBREW_RUBY_WARNINGS - # Disable Ruby options we don't need. RubyGems provides a decent speedup. - RUBY_DISABLE_OPTIONS="--disable=gems,did_you_mean,rubyopt" + # Disable Ruby options we don't need. + RUBY_DISABLE_OPTIONS="--disable=did_you_mean,rubyopt" else # Don't disable did_you_mean for developers as it's useful. - RUBY_DISABLE_OPTIONS="--disable=gems,rubyopt" + RUBY_DISABLE_OPTIONS="--disable=rubyopt" fi if [[ -z "$HOMEBREW_RUBY_WARNINGS" ]] then - export HOMEBREW_RUBY_WARNINGS="-W0" + export HOMEBREW_RUBY_WARNINGS="-W1" fi if [[ -z "$HOMEBREW_BOTTLE_DOMAIN" ]] diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 03814cc855..62c566f922 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -6,7 +6,7 @@ old_trap = trap("INT") { exit! 130 } -require "global" +require_relative "global" require "build_options" require "cxxstdlib" require "keg" @@ -240,7 +240,14 @@ rescue Exception => e # rubocop:disable Lint/RescueException error_hash["env"] = e.env when "ErrorDuringExecution" error_hash["cmd"] = e.cmd - error_hash["status"] = e.status.exitstatus + error_hash["status"] = if e.status.is_a?(Process::Status) + { + exitstatus: e.status.exitstatus, + termsig: e.status.termsig, + } + else + e.status + end error_hash["output"] = e.output end diff --git a/Library/Homebrew/cask/artifact/installer.rb b/Library/Homebrew/cask/artifact/installer.rb index b9d181d0e7..91ffe92f57 100644 --- a/Library/Homebrew/cask/artifact/installer.rb +++ b/Library/Homebrew/cask/artifact/installer.rb @@ -13,9 +13,9 @@ module Cask # @api private class Installer < AbstractArtifact VALID_KEYS = Set.new([ - :manual, - :script, - ]).freeze + :manual, + :script, + ]).freeze # Extension module for manual installers. module ManualInstaller diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 897ba8a535..2fec78dd1e 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -165,7 +165,7 @@ module Cask odebug "Auditing stanzas which require an uninstall" return if cask.artifacts.none? { |k| k.is_a?(Artifact::Pkg) || k.is_a?(Artifact::Installer) } - return if cask.artifacts.any? { |k| k.is_a?(Artifact::Uninstall) } + return if cask.artifacts.any?(Artifact::Uninstall) add_error "installer and pkg stanzas require an uninstall stanza" end @@ -696,7 +696,7 @@ module Cask def check_denylist return unless cask.tap return unless cask.tap.official? - return unless reason = Denylist.reason(cask.token) + return unless (reason = Denylist.reason(cask.token)) add_error "#{cask.token} is not allowed: #{reason}" end @@ -717,7 +717,12 @@ module Cask check_url_for_https_availability(cask.appcast, check_content: true) if cask.appcast && appcast? - check_url_for_https_availability(cask.homepage, check_content: true, user_agents: [:browser]) if cask.homepage + return unless cask.homepage + + check_url_for_https_availability(cask.homepage, + user_agents: [:browser, :default], + check_content: true, + strict: strict?) end def check_url_for_https_availability(url_to_check, **options) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index 2475b84da0..caf666397c 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -162,7 +162,7 @@ module Cask end def eql?(other) - token == other.token + instance_of?(other.class) && token == other.token end alias == eql? diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index d6dab183ca..fa7eed16ae 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -157,7 +157,7 @@ module Cask end def load(config:) - tap.install unless tap.installed? + raise TapCaskUnavailableError.new(tap, token) unless tap.installed? super end diff --git a/Library/Homebrew/cask/caskroom.rb b/Library/Homebrew/cask/caskroom.rb index c65d5649ac..ded8b2e81c 100644 --- a/Library/Homebrew/cask/caskroom.rb +++ b/Library/Homebrew/cask/caskroom.rb @@ -39,9 +39,9 @@ module Cask Pathname.glob(path.join("*")).sort.select(&:directory?).map do |path| token = path.basename.to_s - if tap_path = CaskLoader.tap_paths(token).first + if (tap_path = CaskLoader.tap_paths(token).first) CaskLoader::FromTapPathLoader.new(tap_path).load(config: config) - elsif caskroom_path = Pathname.glob(path.join(".metadata/*/*/*/*.rb")).first + elsif (caskroom_path = Pathname.glob(path.join(".metadata/*/*/*/*.rb")).first) CaskLoader::FromPathLoader.new(caskroom_path).load(config: config) else CaskLoader.load(token, config: config) diff --git a/Library/Homebrew/cask/download.rb b/Library/Homebrew/cask/download.rb index a5b3d31f74..4c80eb2628 100644 --- a/Library/Homebrew/cask/download.rb +++ b/Library/Homebrew/cask/download.rb @@ -19,9 +19,10 @@ module Cask @quarantine = quarantine end - def fetch(verify_download_integrity: true) + def fetch(quiet: nil, verify_download_integrity: true, timeout: nil) downloaded_path = begin - downloader.fetch + downloader.shutup! if quiet + downloader.fetch(timeout: timeout) downloader.cached_location rescue => e error = CaskError.new("Download failed on Cask '#{cask}' with message: #{e}") @@ -40,8 +41,8 @@ module Cask end end - def time_file_size - downloader.resolved_time_file_size + def time_file_size(timeout: nil) + downloader.resolved_time_file_size(timeout: timeout) end def clear_cache diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 3125316274..a46a7c18bc 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -64,30 +64,30 @@ module Cask ].freeze DSL_METHODS = Set.new([ - :appcast, - :artifacts, - :auto_updates, - :caveats, - :conflicts_with, - :container, - :desc, - :depends_on, - :homepage, - :language, - :languages, - :name, - :sha256, - :staged_path, - :url, - :version, - :appdir, - :discontinued?, - :livecheck, - :livecheckable?, - *ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key), - *ACTIVATABLE_ARTIFACT_CLASSES.map(&:dsl_key), - *ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] }, - ]).freeze + :appcast, + :artifacts, + :auto_updates, + :caveats, + :conflicts_with, + :container, + :desc, + :depends_on, + :homepage, + :language, + :languages, + :name, + :sha256, + :staged_path, + :url, + :version, + :appdir, + :discontinued?, + :livecheck, + :livecheckable?, + *ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key), + *ACTIVATABLE_ARTIFACT_CLASSES.map(&:dsl_key), + *ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] }, + ]).freeze attr_reader :cask, :token @@ -181,7 +181,11 @@ module Cask set_unique_stanza(:url, args.empty? && options.empty? && !block_given?) do if block_given? - LazyObject.new { URL.new(*yield, from_block: true, caller_location: caller_location) } + LazyObject.new do + *args = yield + options = args.last.is_a?(Hash) ? args.pop : {} + URL.new(*args, **options, from_block: true, caller_location: caller_location) + end else URL.new(*args, **options, caller_location: caller_location) end diff --git a/Library/Homebrew/cask/dsl/container.rb b/Library/Homebrew/cask/dsl/container.rb index 852907b32e..a386adab8d 100644 --- a/Library/Homebrew/cask/dsl/container.rb +++ b/Library/Homebrew/cask/dsl/container.rb @@ -10,9 +10,9 @@ module Cask # @api private class Container VALID_KEYS = Set.new([ - :type, - :nested, - ]).freeze + :type, + :nested, + ]).freeze attr_accessor(*VALID_KEYS, :pairs) diff --git a/Library/Homebrew/cask/dsl/depends_on.rb b/Library/Homebrew/cask/dsl/depends_on.rb index ca85b1e44b..26aed28b1f 100644 --- a/Library/Homebrew/cask/dsl/depends_on.rb +++ b/Library/Homebrew/cask/dsl/depends_on.rb @@ -12,13 +12,13 @@ module Cask # @api private class DependsOn < SimpleDelegator VALID_KEYS = Set.new([ - :formula, - :cask, - :macos, - :arch, - :x11, - :java, - ]).freeze + :formula, + :cask, + :macos, + :arch, + :x11, + :java, + ]).freeze VALID_ARCHES = { intel: { type: :intel, bits: 64 }, diff --git a/Library/Homebrew/cask/exceptions.rb b/Library/Homebrew/cask/exceptions.rb index 34cd2b62ab..8a2214e3c4 100644 --- a/Library/Homebrew/cask/exceptions.rb +++ b/Library/Homebrew/cask/exceptions.rb @@ -103,6 +103,27 @@ module Cask end end + # Error when a cask in a specific tap is not available. + # + # @api private + class TapCaskUnavailableError < CaskUnavailableError + extend T::Sig + + attr_reader :tap + + def initialize(tap, token) + super("#{tap}/#{token}") + @tap = tap + end + + sig { returns(String) } + def to_s + s = super + s += "\nPlease tap it and then try again: brew tap #{tap}" unless tap.installed? + s + end + end + # Error when a cask already exists. # # @api private diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 0f1467862d..4b1395786b 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -62,13 +62,15 @@ module Cask EOS end - def fetch + sig { params(quiet: T.nilable(T::Boolean), timeout: T.nilable(T.any(Integer, Float))).void } + def fetch(quiet: nil, timeout: nil) odebug "Cask::Installer#fetch" verify_has_sha if require_sha? && !force? - satisfy_dependencies - download + download(quiet: quiet, timeout: timeout) + + satisfy_dependencies end def stage @@ -146,7 +148,7 @@ module Cask installed_cask = installed_caskfile.exist? ? CaskLoader.load(installed_caskfile) : @cask # Always force uninstallation, ignore method parameter - Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true, upgrade: upgrade?).uninstall + Installer.new(installed_cask, verbose: verbose?, force: true, upgrade: upgrade?).uninstall end sig { returns(String) } @@ -162,9 +164,10 @@ module Cask @downloader ||= Download.new(@cask, quarantine: quarantine?) end - sig { returns(Pathname) } - def download - @download ||= downloader.fetch(verify_download_integrity: @verify_download_integrity) + sig { params(quiet: T.nilable(T::Boolean), timeout: T.nilable(T.any(Integer, Float))).returns(Pathname) } + def download(quiet: nil, timeout: nil) + @download ||= downloader.fetch(quiet: quiet, verify_download_integrity: @verify_download_integrity, +timeout: timeout) end def verify_has_sha @@ -179,7 +182,7 @@ module Cask def primary_container @primary_container ||= begin - downloaded_path = download + downloaded_path = download(quiet: true) UnpackStrategy.detect(downloaded_path, type: @cask.container&.type, merge_xattrs: true) end end @@ -191,7 +194,7 @@ module Cask basename = downloader.basename - if nested_container = @cask.container&.nested + if (nested_container = @cask.container&.nested) Dir.mktmpdir do |tmpdir| tmpdir = Pathname(tmpdir) primary_container.extract(to: tmpdir, basename: basename, verbose: verbose?) diff --git a/Library/Homebrew/cask/pkg.rb b/Library/Homebrew/cask/pkg.rb index b66ac90475..0a63d49df1 100644 --- a/Library/Homebrew/cask/pkg.rb +++ b/Library/Homebrew/cask/pkg.rb @@ -32,9 +32,7 @@ module Cask odebug "Deleting pkg files" @command.run!( "/usr/bin/xargs", - args: [ - "-0", "--", "/bin/rm", "--" - ], + args: ["-0", "--", "/bin/rm", "--"], input: pkgutil_bom_files.join("\0"), sudo: true, ) @@ -44,9 +42,7 @@ module Cask odebug "Deleting pkg symlinks and special files" @command.run!( "/usr/bin/xargs", - args: [ - "-0", "--", "/bin/rm", "--" - ], + args: ["-0", "--", "/bin/rm", "--"], input: pkgutil_bom_specials.join("\0"), sudo: true, ) @@ -54,19 +50,10 @@ module Cask unless pkgutil_bom_dirs.empty? odebug "Deleting pkg directories" - deepest_path_first(pkgutil_bom_dirs).each do |dir| - with_full_permissions(dir) do - clean_broken_symlinks(dir) - clean_ds_store(dir) - rmdir(dir) - end - end + rmdir(deepest_path_first(pkgutil_bom_dirs)) end - if root.directory? && !MacOS.undeletable?(root) - clean_ds_store(root) - rmdir(root) - end + rmdir(root) unless MacOS.undeletable?(root) forget end @@ -118,55 +105,51 @@ module Cask path.symlink? || path.chardev? || path.blockdev? end - sig { params(path: Pathname).void } + # Helper script to delete empty directories after deleting `.DS_Store` files and broken symlinks. + # Needed in order to execute all file operations with `sudo`. + RMDIR_SH = <<~'BASH' + set -euo pipefail + + for path in "${@}"; do + if [[ ! -e "${path}" ]]; then + continue + fi + + if [[ -e "${path}/.DS_Store" ]]; then + /bin/rm -f "${path}/.DS_Store" + fi + + # Some packages leave broken symlinks around; we clean them out before + # attempting to `rmdir` to prevent extra cruft from accumulating. + /usr/bin/find "${path}" -mindepth 1 -maxdepth 1 -type l ! -exec /bin/test -e {} \; -delete + + if [[ -L "${path}" ]]; then + # Delete directory symlink. + /bin/rm "${path}" + elif [[ -d "${path}" ]]; then + # Delete directory if empty. + /usr/bin/find "${path}" -maxdepth 0 -type d -empty -exec /bin/rmdir {} \; + else + # Try `rmdir` anyways to show a proper error. + /bin/rmdir "${path}" + fi + done + BASH + private_constant :RMDIR_SH + + sig { params(path: T.any(Pathname, T::Array[Pathname])).void } def rmdir(path) - return unless path.children.empty? - - if path.symlink? - @command.run!("/bin/rm", args: ["-f", "--", path], sudo: true) - else - @command.run!("/bin/rmdir", args: ["--", path], sudo: true) - end - end - - sig { params(path: Pathname, _block: T.proc.void).void } - def with_full_permissions(path, &_block) - original_mode = (path.stat.mode % 01000).to_s(8) - original_flags = @command.run!("/usr/bin/stat", args: ["-f", "%Of", "--", path]).stdout.chomp - - @command.run!("/bin/chmod", args: ["--", "777", path], sudo: true) - yield - ensure - if path.exist? # block may have removed dir - @command.run!("/bin/chmod", args: ["--", original_mode, path], sudo: true) - @command.run!("/usr/bin/chflags", args: ["--", original_flags, path], sudo: true) - end + @command.run!( + "/usr/bin/xargs", + args: ["-0", "--", "/bin/bash", "-c", RMDIR_SH, "--"], + input: Array(path).join("\0"), + sudo: true, + ) end sig { params(paths: T::Array[Pathname]).returns(T::Array[Pathname]) } def deepest_path_first(paths) paths.sort_by { |path| -path.to_s.split(File::SEPARATOR).count } end - - sig { params(dir: Pathname).void } - def clean_ds_store(dir) - return unless (ds_store = dir.join(".DS_Store")).exist? - - @command.run!("/bin/rm", args: ["--", ds_store], sudo: true) - end - - # Some packages leave broken symlinks around; we clean them out before - # attempting to `rmdir` to prevent extra cruft from accumulating. - sig { params(dir: Pathname).void } - def clean_broken_symlinks(dir) - dir.children.select(&method(:broken_symlink?)).each do |path| - @command.run!("/bin/rm", args: ["--", path], sudo: true) - end - end - - sig { params(path: Pathname).returns(T::Boolean) } - def broken_symlink?(path) - path.symlink? && !path.exist? - end end end diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 47ef774cdc..e205ebd3bc 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -3,7 +3,6 @@ require "utils/bottles" -require "utils/gems" require "formula" require "cask/cask_loader" require "set" @@ -80,7 +79,7 @@ module Homebrew version = Version.new(version) - return false unless formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1] + return false unless (formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1]) formula = begin Formulary.from_rack(HOMEBREW_CELLAR/formula_name) @@ -95,7 +94,7 @@ module Homebrew if resource_name == "patch" patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version) return true unless patch_hashes&.include?(Checksum.new(version.to_s)) - elsif resource_name && resource_version = formula.stable&.resources&.dig(resource_name)&.version + elsif resource_name && (resource_version = formula.stable&.resources&.dig(resource_name)&.version) return true if resource_version != version elsif version.is_a?(PkgVersion) return true if formula.pkg_version > version @@ -111,7 +110,7 @@ module Homebrew end def stale_cask?(scrub) - return false unless name = basename.to_s[/\A(.*?)--/, 1] + return false unless (name = basename.to_s[/\A(.*?)--/, 1]) cask = begin Cask::CaskLoader.load(name) diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 0ced43a550..f8dd68b917 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -132,6 +132,12 @@ module Homebrew raise unreadable_error if unreadable_error.present? + user, repo, short_name = name.downcase.split("/", 3) + if repo.present? && short_name.present? + tap = Tap.fetch(user, repo) + raise TapFormulaOrCaskUnavailableError.new(tap, short_name) + end + raise FormulaOrCaskUnavailableError, name end private :load_formula_or_cask @@ -265,28 +271,24 @@ module Homebrew opt_prefix = HOMEBREW_PREFIX/"opt/#{rack.basename}" begin - if opt_prefix.symlink? && opt_prefix.directory? - Keg.new(opt_prefix.resolved_path) - elsif linked_keg_ref.symlink? && linked_keg_ref.directory? - Keg.new(linked_keg_ref.resolved_path) - elsif dirs.length == 1 - Keg.new(dirs.first) + return Keg.new(opt_prefix.resolved_path) if opt_prefix.symlink? && opt_prefix.directory? + return Keg.new(linked_keg_ref.resolved_path) if linked_keg_ref.symlink? && linked_keg_ref.directory? + return Keg.new(dirs.first) if dirs.length == 1 + + f = if name.include?("/") || File.exist?(name) + Formulary.factory(name) else - f = if name.include?("/") || File.exist?(name) - Formulary.factory(name) - else - Formulary.from_rack(rack) - end - - unless (prefix = f.latest_installed_prefix).directory? - raise MultipleVersionsInstalledError, <<~EOS - #{rack.basename} has multiple installed versions - Run `brew uninstall --force #{rack.basename}` to remove all versions. - EOS - end - - Keg.new(prefix) + Formulary.from_rack(rack) end + + unless (prefix = f.latest_installed_prefix).directory? + raise MultipleVersionsInstalledError, <<~EOS + #{rack.basename} has multiple installed versions + Run `brew uninstall --force #{rack.basename}` to remove all versions. + EOS + end + + Keg.new(prefix) rescue FormulaUnavailableError raise MultipleVersionsInstalledError, <<~EOS Multiple kegs installed to #{rack} diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index ed43646664..1ebd604576 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -474,7 +474,7 @@ module Homebrew "<#{type}>" end.compact - types << "" if @named_args_type.any? { |type| type.is_a? String } + types << "" if @named_args_type.any?(String) types.join("|") elsif SYMBOL_TO_USAGE_MAPPING.key? @named_args_type SYMBOL_TO_USAGE_MAPPING[@named_args_type] @@ -623,7 +623,7 @@ module Homebrew end def split_non_options(argv) - if sep = argv.index("--") + if (sep = argv.index("--")) [argv.take(sep), argv.drop(sep + 1)] else [argv, []] diff --git a/Library/Homebrew/cmd/--prefix.rb b/Library/Homebrew/cmd/--prefix.rb index 90c6bbe36b..b68571c442 100644 --- a/Library/Homebrew/cmd/--prefix.rb +++ b/Library/Homebrew/cmd/--prefix.rb @@ -18,8 +18,7 @@ module Homebrew - macOS ARM: `#{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX}` - Linux: `#{HOMEBREW_LINUX_DEFAULT_PREFIX}` - If is provided, display the location in the Cellar where - is or would be installed. + If is provided, display the location where is or would be installed. EOS switch "--unbrewed", description: "List files in Homebrew's prefix not installed by Homebrew." @@ -45,13 +44,10 @@ module Homebrew else formulae = args.named.to_resolved_formulae prefixes = formulae.map do |f| - if f.opt_prefix.exist? - f.opt_prefix - elsif args.installed? - nil - else - f.latest_installed_prefix - end + next nil if args.installed? && !f.opt_prefix.exist? + + # this case wil be short-circuited by brew.sh logic for a single formula + f.opt_prefix end.compact puts prefixes if args.installed? diff --git a/Library/Homebrew/cmd/--version.rb b/Library/Homebrew/cmd/--version.rb deleted file mode 100644 index f423cc7c0c..0000000000 --- a/Library/Homebrew/cmd/--version.rb +++ /dev/null @@ -1,30 +0,0 @@ -# typed: true -# frozen_string_literal: true - -require "cli/parser" - -module Homebrew - extend T::Sig - - module_function - - sig { returns(CLI::Parser) } - def __version_args - Homebrew::CLI::Parser.new do - description <<~EOS - Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask - (if tapped) to standard output. - EOS - - named_args :none - end - end - - def __version - __version_args.parse - - puts "Homebrew #{HOMEBREW_VERSION}" - puts "#{CoreTap.instance.full_name} #{CoreTap.instance.version_string}" - puts "#{Tap.default_cask_tap.full_name} #{Tap.default_cask_tap.version_string}" if Tap.default_cask_tap.installed? - end -end diff --git a/Library/Homebrew/cmd/--version.sh b/Library/Homebrew/cmd/--version.sh new file mode 100644 index 0000000000..c1d92a7a0d --- /dev/null +++ b/Library/Homebrew/cmd/--version.sh @@ -0,0 +1,31 @@ +#: * `--version`, `-v` +#: +#: Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask (if tapped) to standard output. + +version_string() { + local repo="$1" + if ! [ -d "$repo" ]; then + echo "N/A" + return + fi + + local pretty_revision + pretty_revision="$(git -C "$repo" rev-parse --short --verify --quiet HEAD)" + if [ -z "$pretty_revision" ]; then + echo "(no Git repository)" + return + fi + + local git_last_commit_date + git_last_commit_date=$(git -C "$repo" show -s --format='%cd' --date=short HEAD) + echo "(git revision ${pretty_revision}; last commit ${git_last_commit_date})" +} + +homebrew-version() { + echo "Homebrew $HOMEBREW_VERSION" + echo "Homebrew/homebrew-core $(version_string "$HOMEBREW_CORE_REPOSITORY")" + + if [ -d "$HOMEBREW_CASK_REPOSITORY" ]; then + echo "Homebrew/homebrew-cask $(version_string "$HOMEBREW_CASK_REPOSITORY")" + fi +} diff --git a/Library/Homebrew/cmd/gist-logs.rb b/Library/Homebrew/cmd/gist-logs.rb index 86436de503..d9a184a948 100644 --- a/Library/Homebrew/cmd/gist-logs.rb +++ b/Library/Homebrew/cmd/gist-logs.rb @@ -55,7 +55,7 @@ module Homebrew files["00.tap.out"] = { content: tap } end - odie "`brew gist-logs` requires HOMEBREW_GITHUB_API_TOKEN to be set!" if GitHub.api_credentials_type == :none + odie "`brew gist-logs` requires HOMEBREW_GITHUB_API_TOKEN to be set!" if GitHub::API.credentials_type == :none # Description formatted to work well as page title when viewing gist descr = if f.core_formula? @@ -63,9 +63,9 @@ module Homebrew else "#{f.name} (#{f.full_name}) on #{OS_VERSION} - Homebrew build logs" end - url = create_gist(files, descr, private: args.private?) + url = GitHub.create_gist(files, descr, private: args.private?) - url = create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) if args.new_issue? + url = GitHub.create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) if args.new_issue? puts url if url end @@ -85,9 +85,9 @@ module Homebrew # Causes some terminals to display secure password entry indicators. def noecho_gets - system "stty -echo" + system "stty", "-echo" result = $stdin.gets - system "stty echo" + system "stty", "echo" puts result end @@ -108,20 +108,6 @@ module Homebrew logs end - def create_gist(files, description, private:) - url = "https://api.github.com/gists" - data = { "public" => !private, "files" => files, "description" => description } - scopes = GitHub::CREATE_GIST_SCOPES - GitHub.open_api(url, data: data, scopes: scopes)["html_url"] - end - - def create_issue(repo, title, body) - url = "https://api.github.com/repos/#{repo}/issues" - data = { "title" => title, "body" => body } - scopes = GitHub::CREATE_ISSUE_FORK_OR_PR_SCOPES - GitHub.open_api(url, data: data, scopes: scopes)["html_url"] - end - def gist_logs args = gist_logs_args.parse diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index 7d5b1f8f04..d67e898b7e 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -227,7 +227,7 @@ module Homebrew def info_formula(f, args:) specs = [] - if stable = f.stable + if (stable = f.stable) s = "stable #{stable.version}" s += " (bottled)" if stable.bottled? && f.pour_bottle? specs << s @@ -338,6 +338,7 @@ module Homebrew end def info_cask(cask, args:) + require "cask/cmd" require "cask/cmd/info" Cask::Cmd::Info.info(cask) diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 25fbee9de6..b02fca771b 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -264,7 +264,7 @@ module Homebrew end end opoo msg if msg - elsif !f.any_version_installed? && old_formula = f.old_installed_formulae.first + elsif !f.any_version_installed? && (old_formula = f.old_installed_formulae.first) msg = "#{old_formula.full_name} #{old_formula.any_installed_version} already installed" msg = if !old_formula.linked? && !old_formula.keg_only? <<~EOS diff --git a/Library/Homebrew/cmd/log.rb b/Library/Homebrew/cmd/log.rb index 42344b700b..6c3e39829e 100644 --- a/Library/Homebrew/cmd/log.rb +++ b/Library/Homebrew/cmd/log.rb @@ -51,7 +51,7 @@ module Homebrew def git_log(cd_dir, path = nil, tap = nil, args:) cd cd_dir - repo = Utils.popen_read("git rev-parse --show-toplevel").chomp + repo = Utils.popen_read("git", "rev-parse", "--show-toplevel").chomp if tap name = tap.to_s git_cd = "$(brew --repo #{tap})" diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb index 66ca2764cf..755458f636 100644 --- a/Library/Homebrew/cmd/search.rb +++ b/Library/Homebrew/cmd/search.rb @@ -73,7 +73,7 @@ module Homebrew def search args = search_args.parse - if package_manager = PACKAGE_MANAGERS.find { |name,| args[:"#{name}?"] } + if (package_manager = PACKAGE_MANAGERS.find { |name,| args[:"#{name}?"] }) _, url = package_manager exec_browser url.call(URI.encode_www_form_component(args.named.join(" "))) return diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index 4b1c4bead7..a459946007 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -54,6 +54,7 @@ module Homebrew Uninstall.uninstall_kegs( kegs_by_rack, + casks: casks, force: args.force?, ignore_dependencies: args.ignore_dependencies?, named_args: args.named, @@ -68,9 +69,8 @@ module Homebrew else T.unsafe(Cask::Cmd::Uninstall).uninstall_casks( *casks, - binaries: EnvConfig.cask_opts_binaries?, - verbose: args.verbose?, - force: args.force?, + verbose: args.verbose?, + force: args.force?, ) end end diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 3e071d8371..aeee8ffa79 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -129,15 +129,40 @@ module Homebrew if hub.empty? puts_stdout_or_stderr "No changes to formulae." unless args.quiet? else - hub.dump(updated_formula_report: !args.preinstall?) + hub.dump(updated_formula_report: !args.preinstall?) unless args.quiet? hub.reporters.each(&:migrate_tap_migration) hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?, verbose: args.verbose?) } CacheStoreDatabase.use(:descriptions) do |db| DescriptionCacheStore.new(db) .update_from_report!(hub) end + + if !args.preinstall? && !args.quiet? + outdated_formulae = Formula.installed.count(&:outdated?) + outdated_casks = Cask::Caskroom.casks.count(&:outdated?) + update_pronoun = if (outdated_formulae + outdated_casks) == 1 + "it" + else + "them" + end + msg = "" + if outdated_formulae.positive? + msg += "#{Tty.bold}#{outdated_formulae}#{Tty.reset} outdated #{"formula".pluralize(outdated_formulae)}" + end + if outdated_casks.positive? + msg += " and " if msg.present? + msg += "#{Tty.bold}#{outdated_casks}#{Tty.reset} outdated #{"cask".pluralize(outdated_casks)}" + end + if msg.present? + puts_stdout_or_stderr + puts_stdout_or_stderr <<~EOS + You have #{msg} installed. + You can update #{update_pronoun} with #{Tty.bold}brew upgrade#{Tty.reset}. + EOS + end + end end - puts if args.preinstall? + puts_stdout_or_stderr if args.preinstall? elsif !args.preinstall? && !ENV["HOMEBREW_UPDATE_FAILED"] puts_stdout_or_stderr "Already up-to-date." unless args.quiet? end @@ -161,6 +186,7 @@ module Homebrew return if new_repository_version.blank? + puts_stdout_or_stderr ohai_stdout_or_stderr "Homebrew was updated to version #{new_repository_version}" if new_repository_version.split(".").last == "0" puts_stdout_or_stderr <<~EOS diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 92999d7b80..592e3e658d 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -308,6 +308,7 @@ homebrew-update() { -\?|-h|--help|--usage) brew help update; exit $? ;; --verbose) HOMEBREW_VERBOSE=1 ;; --debug) HOMEBREW_DEBUG=1 ;; + --quiet) HOMEBREW_QUIET=1 ;; --merge) HOMEBREW_MERGE=1 ;; --force) HOMEBREW_UPDATE_FORCE=1 ;; --simulate-from-current-branch) HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH=1 ;; @@ -315,6 +316,7 @@ homebrew-update() { --*) ;; -*) [[ "$option" = *v* ]] && HOMEBREW_VERBOSE=1 + [[ "$option" = *q* ]] && HOMEBREW_QUIET=1 [[ "$option" = *d* ]] && HOMEBREW_DEBUG=1 [[ "$option" = *f* ]] && HOMEBREW_UPDATE_FORCE=1 ;; @@ -661,7 +663,8 @@ EOS then brew update-report "$@" return $? - elif [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]] + elif [[ -z "$HOMEBREW_UPDATE_PREINSTALL" && + -z "$HOMEBREW_QUIET" ]] then echo "Already up-to-date." fi diff --git a/Library/Homebrew/commands.rb b/Library/Homebrew/commands.rb index 23ebde0cfc..4004392fd6 100644 --- a/Library/Homebrew/commands.rb +++ b/Library/Homebrew/commands.rb @@ -175,7 +175,7 @@ module Commands path = self.path(command) return if path.blank? - if cmd_parser = Homebrew::CLI::Parser.from_cmd_path(path) + if (cmd_parser = Homebrew::CLI::Parser.from_cmd_path(path)) cmd_parser.processed_options.map do |short, long, _, desc| [long || short, desc] end @@ -198,7 +198,7 @@ module Commands path = self.path(command) return if path.blank? - if cmd_parser = Homebrew::CLI::Parser.from_cmd_path(path) + if (cmd_parser = Homebrew::CLI::Parser.from_cmd_path(path)) if short cmd_parser.description.split(".").first else diff --git a/Library/Homebrew/completions.rb b/Library/Homebrew/completions.rb index 583d5cef6c..43033ed4f8 100644 --- a/Library/Homebrew/completions.rb +++ b/Library/Homebrew/completions.rb @@ -129,8 +129,6 @@ module Homebrew sig { params(command: String).returns(T::Boolean) } def command_gets_completions?(command) - return false if command.start_with? "cask " # TODO: (2.8) remove when `brew cask` commands are removed - command_options(command).any? end @@ -167,7 +165,7 @@ module Homebrew return unless command_gets_completions? command named_completion_string = "" - if types = Commands.named_args_type(command) + if (types = Commands.named_args_type(command)) named_args_strings, named_args_types = types.partition { |type| type.is_a? String } named_args_types.each do |type| @@ -215,29 +213,51 @@ module Homebrew def generate_zsh_subcommand_completion(command) return unless command_gets_completions? command - options = command_options(command).sort.map do |opt, desc| - next opt if desc.blank? + options = command_options(command) - conflicts = generate_zsh_option_exclusions(command, opt) - "#{conflicts}#{opt}[#{format_description desc}]" - end - if types = Commands.named_args_type(command) + args_options = [] + if (types = Commands.named_args_type(command)) named_args_strings, named_args_types = types.partition { |type| type.is_a? String } named_args_types.each do |type| next unless ZSH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING.key? type - options << "::#{type}:#{ZSH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING[type]}" + args_options << "- #{type}" + opt = "--#{type.to_s.gsub(/(installed|outdated)_/, "")}" + if options.key?(opt) + desc = options[opt] + + if desc.blank? + args_options << opt + else + conflicts = generate_zsh_option_exclusions(command, opt) + args_options << "#{conflicts}#{opt}[#{format_description desc}]" + end + + options.delete(opt) + end + args_options << "*::#{type}:#{ZSH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING[type]}" end - options << "::subcommand:(#{named_args_strings.join(" ")})" if named_args_strings.any? + if named_args_strings.any? + args_options << "- subcommand" + args_options << "*::subcommand:(#{named_args_strings.join(" ")})" + end end + options = options.sort.map do |opt, desc| + next opt if desc.blank? + + conflicts = generate_zsh_option_exclusions(command, opt) + "#{conflicts}#{opt}[#{format_description desc}]" + end + options += args_options + <<~COMPLETION # brew #{command} _brew_#{Commands.method_name command}() { _arguments \\ - #{options.map! { |opt| "'#{opt}'" }.join(" \\\n ")} + #{options.map! { |opt| opt.start_with?("- ") ? opt : "'#{opt}'" }.join(" \\\n ")} } COMPLETION end @@ -291,7 +311,7 @@ module Homebrew subcommands = [] named_args = [] - if types = Commands.named_args_type(command) + if (types = Commands.named_args_type(command)) named_args_strings, named_args_types = types.partition { |type| type.is_a? String } named_args_types.each do |type| diff --git a/Library/Homebrew/config.rb b/Library/Homebrew/config.rb index f7ce3cc14f..4369b95616 100644 --- a/Library/Homebrew/config.rb +++ b/Library/Homebrew/config.rb @@ -67,3 +67,9 @@ HOMEBREW_TEMP = Pathname(EnvVar["HOMEBREW_TEMP"]).yield_self do |tmp| tmp.mkpath unless tmp.exist? tmp.realpath end.freeze + +# The Ruby path and args to use for forked Ruby calls +HOMEBREW_RUBY_EXEC_ARGS = [ + RUBY_PATH, + ENV["HOMEBREW_RUBY_WARNINGS"], +].freeze diff --git a/Library/Homebrew/context.rb b/Library/Homebrew/context.rb index 7655c8eaa7..5a9c410bcc 100644 --- a/Library/Homebrew/context.rb +++ b/Library/Homebrew/context.rb @@ -16,7 +16,7 @@ module Context end def self.current - if current_context = Thread.current[:context] + if (current_context = Thread.current[:context]) return current_context end diff --git a/Library/Homebrew/descriptions.rb b/Library/Homebrew/descriptions.rb index 8f980de1c6..ef5b33f852 100644 --- a/Library/Homebrew/descriptions.rb +++ b/Library/Homebrew/descriptions.rb @@ -52,7 +52,7 @@ class Descriptions private def short_names - @short_names ||= Hash[@descriptions.keys.map { |k| [k, k.split("/").last] }] + @short_names ||= @descriptions.keys.map { |k| [k, k.split("/").last] }.to_h end def short_name_counts diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 5d4af842d9..032552a218 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -254,7 +254,7 @@ module Homebrew def bottle_formula(f, args:) return ofail "Formula not installed or up-to-date: #{f.full_name}" unless f.latest_version_installed? - unless tap = f.tap + unless (tap = f.tap) return ofail "Formula not from core or any installed taps: #{f.full_name}" unless args.force_core_tap? tap = CoreTap.instance diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index 406f16cd13..cd4ca2cb35 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -125,29 +125,21 @@ module Homebrew tmp_config = cask.config tmp_url = tmp_cask.url.to_s - if new_hash.nil? && old_hash != :no_check - resource_path = fetch_resource(cask, new_version, tmp_url) - Utils::Tar.validate_file(resource_path) - new_hash = resource_path.sha256 + if old_hash != :no_check + new_hash = fetch_resource(cask, new_version, tmp_url) if new_hash.nil? + + if tmp_contents.include?("Hardware::CPU.intel?") + other_intel = !Hardware::CPU.intel? + other_contents = tmp_contents.gsub("Hardware::CPU.intel?", other_intel.to_s) + replacement_pairs << fetch_cask(other_contents, new_version) + end end cask.languages.each do |language| next if language == cask.language lang_config = tmp_config.merge(Cask::Config.new(explicit: { languages: [language] })) - lang_cask = Cask::CaskLoader.load(tmp_contents) - lang_cask.config = lang_config - lang_url = lang_cask.url.to_s - lang_old_hash = lang_cask.sha256.to_s - - resource_path = fetch_resource(cask, new_version, lang_url) - Utils::Tar.validate_file(resource_path) - lang_new_hash = resource_path.sha256 - - replacement_pairs << [ - lang_old_hash, - lang_new_hash, - ] + replacement_pairs << fetch_cask(tmp_contents, new_version, config: lang_config) end end end @@ -186,12 +178,24 @@ module Homebrew GitHub.create_bump_pr(pr_info, args: args) end - def fetch_resource(cask, new_version, url, **specs) + def fetch_resource(cask, version, url, **specs) resource = Resource.new resource.url(url, specs) resource.owner = Resource.new(cask.token) - resource.version = new_version - resource.fetch + resource.version = version + + resource_path = resource.fetch + Utils::Tar.validate_file(resource_path) + resource_path.sha256 + end + + def fetch_cask(contents, version, config: nil) + cask = Cask::CaskLoader.load(contents) + cask.config = config if config.present? + url = cask.url.to_s + old_hash = cask.sha256.to_s + new_hash = fetch_resource(cask, version, url) + [old_hash, new_hash] end def check_open_pull_requests(cask, args:) diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index 33fb4bb2cb..f88704091a 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -103,7 +103,7 @@ module Homebrew end formula.tap.path.cd do - unless Utils.popen_read("git remote -v").match?(%r{^homebrew.*Homebrew/homebrew-core.*$}) + unless Utils.popen_read("git", "remote", "-v").match?(%r{^homebrew.*Homebrew/homebrew-core.*$}) ohai "Adding #{homebrew_core_remote} remote" safe_system "git", "remote", "add", homebrew_core_remote, homebrew_core_url end @@ -193,7 +193,7 @@ module Homebrew end check_new_version(formula, tap_full_name, url: old_url, tag: new_tag, args: args) if new_version.blank? resource_path, forced_version = fetch_resource(formula, new_version, old_url, tag: new_tag) - new_revision = Utils.popen_read("git -C \"#{resource_path}\" rev-parse -q --verify HEAD") + new_revision = Utils.popen_read("git", "-C", resource_path.to_s, "rev-parse", "-q", "--verify", "HEAD") new_revision = new_revision.strip elsif new_revision.blank? odie "#{formula}: the current URL requires specifying a `--revision=` argument." diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index ffbc2feab4..17655e4b33 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -16,66 +16,148 @@ module Homebrew Display out-of-date brew formulae and the latest version available. Also displays whether a pull request has been opened with the URL. EOS + switch "--full-name", + description: "Print formulae/casks with fully-qualified names." + switch "--no-pull-requests", + description: "Do not retrieve pull requests from GitHub." + switch "--formula", "--formulae", + description: "Check only formulae." + switch "--cask", "--casks", + description: "Check only casks." flag "--limit=", description: "Limit number of package results returned." - named_args :formula + conflicts "--cask", "--formula" + + named_args [:formula, :cask] end end def bump args = bump_args.parse - requested_formulae = args.named.to_formulae.presence - requested_limit = args.limit.to_i if args.limit.present? + if args.limit.present? && !args.formula? && !args.cask? + raise UsageError, "`--limit` must be used with either `--formula` or `--cask`." + end - if requested_formulae - Livecheck.load_other_tap_strategies(requested_formulae) + formulae_and_casks = if args.formula? + args.named.to_formulae + elsif args.cask? + args.named.to_casks + else + args.named.to_formulae_and_casks + end + formulae_and_casks = formulae_and_casks&.sort_by do |formula_or_cask| + formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name + end - requested_formulae.each_with_index do |formula, i| + limit = args.limit.to_i if args.limit.present? + + if formulae_and_casks + Livecheck.load_other_tap_strategies(formulae_and_casks) + + ambiguous_casks = [] + if !args.formula? && !args.cask? + ambiguous_casks = formulae_and_casks.group_by { |item| Livecheck.formula_or_cask_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } + end + + ambiguous_names = [] + unless args.full_name? + ambiguous_names = + (formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.formula_or_cask_name(item) } + .values + .select { |items| items.length > 1 } + .flatten + end + + formulae_and_casks.each_with_index do |formula_or_cask, i| puts if i.positive? - if formula.head_only? - ohai formula.name - puts "Formula is HEAD-only." - next + use_full_name = args.full_name? || ambiguous_names.include?(formula_or_cask) + name = Livecheck.formula_or_cask_name(formula_or_cask, full_name: use_full_name) + repository = if formula_or_cask.is_a?(Formula) + if formula_or_cask.head_only? + ohai name + puts "Formula is HEAD-only." + next + end + + Repology::HOMEBREW_CORE + else + Repology::HOMEBREW_CASK end - package_data = Repology.single_package_query(formula.name) - retrieve_and_display_info(formula, package_data&.values&.first) + package_data = Repology.single_package_query(name, repository: repository) + retrieve_and_display_info( + formula_or_cask, + name, + package_data&.values&.first, + args: args, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask), + ) end else - outdated_packages = Repology.parse_api_response(requested_limit) - outdated_packages.each_with_index do |(_name, repositories), i| - puts if i.positive? + api_response = {} + unless args.cask? + api_response[:formulae] = + Repology.parse_api_response(limit, repository: Repology::HOMEBREW_CORE) + end + unless args.formula? + api_response[:casks] = + Repology.parse_api_response(limit, repository: Repology::HOMEBREW_CASK) + end - homebrew_repo = repositories.find do |repo| - repo["repo"] == "homebrew" + api_response.each do |package_type, outdated_packages| + repository = if package_type == :formulae + Repology::HOMEBREW_CORE + else + Repology::HOMEBREW_CASK end - next if homebrew_repo.blank? + outdated_packages.each_with_index do |(_name, repositories), i| + homebrew_repo = repositories.find do |repo| + repo["repo"] == repository + end - formula = begin - Formula[homebrew_repo["srcname"]] - rescue - next + next if homebrew_repo.blank? + + formula_or_cask = begin + if repository == Repology::HOMEBREW_CORE + Formula[homebrew_repo["srcname"]] + else + Cask::CaskLoader.load(homebrew_repo["srcname"]) + end + rescue + next + end + name = Livecheck.formula_or_cask_name(formula_or_cask) + ambiguous_cask = begin + formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name] + rescue FormulaUnavailableError + false + end + + puts if i.positive? + retrieve_and_display_info(formula_or_cask, name, repositories, args: args, ambiguous_cask: ambiguous_cask) + + break if limit && i >= limit end - - retrieve_and_display_info(formula, repositories) - - break if requested_limit && i >= requested_limit end end end - def livecheck_result(formula) - skip_result = Livecheck::SkipConditions.skip_information(formula) + def livecheck_result(formula_or_cask) + skip_result = Livecheck::SkipConditions.skip_information(formula_or_cask) if skip_result.present? return "#{skip_result[:status]}#{" - #{skip_result[:messages].join(", ")}" if skip_result[:messages].present?}" end version_info = Livecheck.latest_version( - formula, + formula_or_cask, json: true, full_name: false, verbose: false, debug: false, ) latest = version_info[:latest] if version_info.present? @@ -83,10 +165,12 @@ module Homebrew return "unable to get versions" if latest.blank? latest.to_s + rescue => e + "error: #{e}" end - def retrieve_pull_requests(formula) - pull_requests = GitHub.fetch_pull_requests(formula.name, formula.tap&.full_name, state: "open") + def retrieve_pull_requests(formula_or_cask, name) + pull_requests = GitHub.fetch_pull_requests(name, formula_or_cask.tap&.full_name, state: "open") if pull_requests.try(:any?) pull_requests = pull_requests.map { |pr| "#{pr["title"]} (#{Formatter.url(pr["html_url"])})" }.join(", ") end @@ -96,8 +180,12 @@ module Homebrew pull_requests end - def retrieve_and_display_info(formula, repositories) - current_version = formula.stable.version.to_s + def retrieve_and_display_info(formula_or_cask, name, repositories, args:, ambiguous_cask: false) + current_version = if formula_or_cask.is_a?(Formula) + formula_or_cask.stable.version + else + Version.new(formula_or_cask.version) + end repology_latest = if repositories.present? Repology.latest_version(repositories) @@ -105,14 +193,15 @@ module Homebrew "not found" end - livecheck_latest = livecheck_result(formula) - pull_requests = retrieve_pull_requests(formula) + livecheck_latest = livecheck_result(formula_or_cask) + pull_requests = retrieve_pull_requests(formula_or_cask, name) unless args.no_pull_requests? + name += " (cask)" if ambiguous_cask title = if current_version == repology_latest && current_version == livecheck_latest - "#{formula} is up to date!" + "#{name} is up to date!" else - formula.name + name end ohai title @@ -120,7 +209,7 @@ module Homebrew Current formula version: #{current_version} Latest Repology version: #{repology_latest} Latest livecheck version: #{livecheck_latest} - Open pull requests: #{pull_requests} EOS + puts "Open pull requests: #{pull_requests}" unless args.no_pull_requests? end end diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index 23f9b7bdbc..0d4e4b6ccd 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -179,7 +179,7 @@ module Homebrew # Check for disallowed formula, or names that shadow aliases, # unless --force is specified. unless args.force? - if reason = MissingFormula.disallowed_reason(fc.name) + if (reason = MissingFormula.disallowed_reason(fc.name)) odie <<~EOS The formula '#{fc.name}' is not allowed to be created. #{reason} diff --git a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb index 7fd1a133ca..915e3d5106 100644 --- a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb +++ b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb @@ -25,7 +25,10 @@ module Homebrew description: "Dispatch specified workflow (default: `dispatch-build-bottle.yml`)." switch "--upload", description: "Upload built bottles to Bintray." + switch "--linux", + description: "Dispatch bottle for Linux (using GitHub runners)." + conflicts "--macos", "--linux" named_args :formula, min: 1 end end @@ -33,45 +36,55 @@ module Homebrew def dispatch_build_bottle args = dispatch_build_bottle_args.parse - # Fixup version for ARM/Apple Silicon - # TODO: fix label name to be 11-arm64 instead and remove this. - args.macos&.gsub!(/^11-arm$/, "11-arm64") - - macos = args.macos&.yield_self do |s| - MacOS::Version.from_symbol(s.to_sym) - rescue MacOSVersionError - MacOS::Version.new(s) - end - - raise UsageError, "Must specify --macos option" if macos.blank? - - # Fixup label for ARM/Apple Silicon - macos_label = if macos.arch == :arm64 - # TODO: fix label name to be 11-arm64 instead. - "#{macos}-arm" - else - macos.to_s - end - tap = Tap.fetch(args.tap || CoreTap.instance.name) user, repo = tap.full_name.split("/") - - workflow = args.workflow || "dispatch-build-bottle.yml" ref = "master" + workflow = args.workflow || "dispatch-build-bottle.yml" + + # Ensure we dispatch the bottle in homebrew/homebrew-core + # TODO: remove when core taps are merged + repo.gsub!("linux", "home") unless args.tap + + if (macos = args.macos) + # Fixup version for ARM/Apple Silicon + # TODO: fix label name to be 11-arm64 instead and remove this. + macos.gsub!(/^11-arm$/, "11-arm64") + + macos = macos.yield_self do |s| + MacOS::Version.from_symbol(s.to_sym) + rescue MacOSVersionError + MacOS::Version.new(s) + end + + # Fixup label for ARM/Apple Silicon + macos_label = if macos.arch == :arm64 + # TODO: fix label name to be 11-arm64 instead. + "#{macos}-arm" + else + macos.to_s + end + + dispatching_for = "macOS #{macos}" + elsif T.unsafe(args).linux? + workflow = args.workflow || "linux-#{workflow}" + dispatching_for = "Linux" + else + raise UsageError, "Must specify --macos or --linux option" + end args.named.to_resolved_formulae.each do |formula| # Required inputs inputs = { formula: formula.name, - macos: macos_label, } # Optional inputs # These cannot be passed as nil to GitHub API + inputs[:macos] = macos_label if args.macos inputs[:issue] = args.issue if args.issue inputs[:upload] = args.upload?.to_s if args.upload? - ohai "Dispatching #{tap} bottling request of formula \"#{formula.name}\" for macOS #{macos}" + ohai "Dispatching #{tap} bottling request of formula \"#{formula.name}\" for #{dispatching_for}" GitHub.workflow_dispatch_event(user, repo, workflow, ref, inputs) end end diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 13f05f09f4..c702bc4fc3 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -61,54 +61,55 @@ module Homebrew puts ENV["HOMEBREW_LIVECHECK_WATCHLIST"] if ENV["HOMEBREW_LIVECHECK_WATCHLIST"].present? end - formulae_and_casks_to_check = - if args.tap - tap = Tap.fetch(args.tap) - formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } - casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } - formulae + casks - elsif args.installed? - formulae = args.cask? ? [] : Formula.installed - casks = args.formula? ? [] : Cask::Caskroom.casks - formulae + casks - elsif args.all? - formulae = args.cask? ? [] : Formula.to_a - casks = args.formula? ? [] : Cask::Cask.to_a - formulae + casks - elsif args.named.present? - if args.formula? - args.named.to_formulae - elsif args.cask? - args.named.to_casks - else - args.named.to_formulae_and_casks - end - elsif File.exist?(WATCHLIST_PATH) - begin - names = Pathname.new(WATCHLIST_PATH).read.lines - .reject { |line| line.start_with?("#") || line.blank? } - .map(&:strip) - - named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) - named_args.to_formulae_and_casks(ignore_unavailable: true) - rescue Errno::ENOENT => e - onoe e - end + formulae_and_casks_to_check = if args.tap + tap = Tap.fetch(args.tap) + formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } + casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } + formulae + casks + elsif args.installed? + formulae = args.cask? ? [] : Formula.installed + casks = args.formula? ? [] : Cask::Caskroom.casks + formulae + casks + elsif args.all? + formulae = args.cask? ? [] : Formula.to_a + casks = args.formula? ? [] : Cask::Cask.to_a + formulae + casks + elsif args.named.present? + if args.formula? + args.named.to_formulae + elsif args.cask? + args.named.to_casks else - raise UsageError, "A watchlist file is required when no arguments are given." - end&.sort_by do |formula_or_cask| - formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name + args.named.to_formulae_and_casks end + elsif File.exist?(WATCHLIST_PATH) + begin + names = Pathname.new(WATCHLIST_PATH).read.lines + .reject { |line| line.start_with?("#") || line.blank? } + .map(&:strip) + + named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) + named_args.to_formulae_and_casks(ignore_unavailable: true) + rescue Errno::ENOENT => e + onoe e + end + else + raise UsageError, "A watchlist file is required when no arguments are given." + end + formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| + formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name + end raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank? options = { - json: args.json?, - full_name: args.full_name?, - newer_only: args.newer_only?, - quiet: args.quiet?, - debug: args.debug?, - verbose: args.verbose?, + json: args.json?, + full_name: args.full_name?, + handle_name_conflict: !args.formula? && !args.cask?, + newer_only: args.newer_only?, + quiet: args.quiet?, + debug: args.debug?, + verbose: args.verbose?, }.compact Livecheck.run_checks(formulae_and_casks_to_check, **options) diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb index 2d375eaa6a..3d15f07424 100644 --- a/Library/Homebrew/dev-cmd/man.rb +++ b/Library/Homebrew/dev-cmd/man.rb @@ -24,9 +24,9 @@ module Homebrew *Note:* Not (yet) working on Apple Silicon. EOS - switch "--fail-if-changed", - description: "Return a failing status code if changes are detected in the manpage outputs. This "\ - "can be used to notify CI when the manpages are out of date. Additionally, "\ + switch "--fail-if-not-changed", + description: "Return a failing status code if no changes are detected in the manpage outputs. "\ + "This can be used to notify CI when the manpages are out of date. Additionally, "\ "the date used in new manpages will match those in the existing manpages (to allow "\ "comparison without factoring in the date)." named_args :none @@ -42,19 +42,17 @@ module Homebrew args = man_args.parse Commands.rebuild_internal_commands_completion_list - regenerate_man_pages(preserve_date: args.fail_if_changed?, quiet: args.quiet?) + regenerate_man_pages(preserve_date: args.fail_if_not_changed?, quiet: args.quiet?) Completions.update_shell_completions! diff = system_command "git", args: [ "-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", "docs/Manpage.md", "manpages", "completions" ] - if diff.status.success? - puts "No changes to manpage or completions output detected." - elsif args.fail_if_changed? - puts "Changes to manpage or completions detected:" - puts diff.stdout - Homebrew.failed = true - end + + return unless diff.status.success? + + puts "No changes to manpage or completions output detected." + Homebrew.failed = true if args.fail_if_not_changed? end def regenerate_man_pages(preserve_date:, quiet:) @@ -62,6 +60,7 @@ module Homebrew markup = build_man_page(quiet: quiet) convert_man_page(markup, TARGET_DOC_PATH/"Manpage.md", preserve_date: preserve_date) + markup = I18n.transliterate(markup, locale: :en) convert_man_page(markup, TARGET_MAN_PATH/"brew.1", preserve_date: preserve_date) end @@ -164,7 +163,7 @@ module Homebrew # preserve existing manpage order cmd_paths.sort_by(&method(:sort_key_for_path)) .each do |cmd_path| - cmd_man_page_lines = if cmd_parser = CLI::Parser.from_cmd_path(cmd_path) + cmd_man_page_lines = if (cmd_parser = CLI::Parser.from_cmd_path(cmd_path)) next if cmd_parser.hide_from_man_page cmd_parser_manpage_lines(cmd_parser).join diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 369fe76bc4..fb4e67d4cc 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -49,6 +49,8 @@ module Homebrew description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." flag "--artifact=", description: "Download artifacts with the specified name (default: `bottles`)." + flag "--archive-item=", + description: "Upload to the specified Internet Archive item (default: `homebrew`)." flag "--bintray-org=", description: "Upload to the specified Bintray organisation (default: `homebrew`)." flag "--tap=", @@ -65,6 +67,7 @@ module Homebrew description: "Comma-separated list of workflows which can be ignored if they have not been run." conflicts "--clean", "--autosquash" + conflicts "--archive-item", "--bintray-org" named_args :pull_request, min: 1 end @@ -337,9 +340,9 @@ module Homebrew end def download_artifact(url, dir, pr) - odie "Credentials must be set to access the Artifacts API" if GitHub.api_credentials_type == :none + odie "Credentials must be set to access the Artifacts API" if GitHub::API.credentials_type == :none - token = GitHub.api_credentials + token = GitHub::API.credentials curl_args = ["--header", "Authorization: token #{token}"] # Download the artifact as a zip file and unpack it into `dir`. This is @@ -357,6 +360,7 @@ module Homebrew workflows = args.workflows.presence || ["tests.yml"] artifact = args.artifact || "bottles" + archive_item = args.archive_item bintray_org = args.bintray_org || "homebrew" mirror_repo = args.bintray_mirror || "mirror" tap = Tap.fetch(args.tap || CoreTap.instance.name) @@ -424,7 +428,11 @@ module Homebrew upload_args << "--keep-old" if args.keep_old? upload_args << "--warn-on-upload-failure" if args.warn_on_upload_failure? upload_args << "--root-url=#{args.root_url}" if args.root_url - upload_args << "--bintray-org=#{bintray_org}" + upload_args << if archive_item.present? + "--archive-item=#{archive_item}" + else + "--bintray-org=#{bintray_org}" + end safe_system HOMEBREW_BREW_FILE, *upload_args end end diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index 09fb40e08c..9a4846e35d 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -2,7 +2,10 @@ # frozen_string_literal: true require "cli/parser" +require "archive" require "bintray" +require "github_packages" +require "github_releases" module Homebrew extend T::Sig @@ -13,7 +16,7 @@ module Homebrew def pr_upload_args Homebrew::CLI::Parser.new do description <<~EOS - Apply the bottle commit and publish bottles to Bintray or GitHub Releases. + Apply the bottle commit and publish bottles to a host. EOS switch "--no-publish", description: "Apply the bottle commit and upload the bottles, but don't publish them." @@ -27,8 +30,12 @@ module Homebrew switch "--warn-on-upload-failure", description: "Warn instead of raising an error if the bottle upload fails. "\ "Useful for repairing bottle uploads that previously failed." + flag "--archive-item=", + description: "Upload to the specified Internet Archive item (default: `homebrew`)." flag "--bintray-org=", description: "Upload to the specified Bintray organisation (default: `homebrew`)." + flag "--github-org=", + description: "Upload to the specified GitHub organisation's GitHub Packages (default: `homebrew`)." flag "--root-url=", description: "Use the specified as the root of the bottle's URL instead of Homebrew's default." @@ -47,16 +54,34 @@ module Homebrew end end + def internet_archive?(bottles_hash) + @internet_archive ||= bottles_hash.values.all? do |bottle_hash| + bottle_hash["bottle"]["root_url"].start_with? "#{Archive::URL_PREFIX}/" + end + end + + def bintray?(bottles_hash) + @bintray ||= bottles_hash.values.all? do |bottle_hash| + bottle_hash["bottle"]["root_url"].match? Bintray::URL_REGEX + end + end + def github_releases?(bottles_hash) @github_releases ||= bottles_hash.values.all? do |bottle_hash| root_url = bottle_hash["bottle"]["root_url"] - url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX + url_match = root_url.match GitHubReleases::URL_REGEX _, _, _, tag = *url_match tag end end + def github_packages?(bottles_hash) + @github_packages ||= bottles_hash.values.all? do |bottle_hash| + bottle_hash["bottle"]["root_url"].match? GitHubPackages::URL_REGEX + end + end + def pr_upload args = pr_upload_args.parse @@ -76,11 +101,18 @@ module Homebrew bottle_args += json_files if args.dry_run? - service = if github_releases?(bottles_hash) - "GitHub Releases" - else - "Bintray" - end + service = + if internet_archive?(bottles_hash) + "Internet Archive" + elsif bintray?(bottles_hash) + "Bintray" + elsif github_releases?(bottles_hash) + "GitHub Releases" + elsif github_packages?(bottles_hash) + "GitHub Packages" + else + odie "Service specified by root_url is not recognized" + end puts <<~EOS brew #{bottle_args.join " "} Upload bottles described by these JSON files to #{service}: @@ -102,38 +134,26 @@ module Homebrew safe_system HOMEBREW_BREW_FILE, *audit_args end - if github_releases?(bottles_hash) - # Handle uploading to GitHub Releases. - bottles_hash.each_value do |bottle_hash| - root_url = bottle_hash["bottle"]["root_url"] - url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX - _, user, repo, tag = *url_match - - # Ensure a release is created. - release = begin - rel = GitHub.get_release user, repo, tag - odebug "Existing GitHub release \"#{tag}\" found" - rel - rescue GitHub::HTTPNotFoundError - odebug "Creating new GitHub release \"#{tag}\"" - GitHub.create_or_update_release user, repo, tag - end - - # Upload bottles as release assets. - bottle_hash["bottle"]["tags"].each_value do |tag_hash| - remote_file = tag_hash["filename"] - local_file = tag_hash["local_filename"] - odebug "Uploading #{remote_file}" - GitHub.upload_release_asset user, repo, release["id"], local_file: local_file, remote_file: remote_file - end - end - else - # Handle uploading to Bintray. + if internet_archive?(bottles_hash) + archive_item = args.archive_item || "homebrew" + archive = Archive.new(item: archive_item) + archive.upload_bottles(bottles_hash, + warn_on_error: args.warn_on_upload_failure?) + elsif bintray?(bottles_hash) bintray_org = args.bintray_org || "homebrew" bintray = Bintray.new(org: bintray_org) bintray.upload_bottles(bottles_hash, publish_package: !args.no_publish?, warn_on_error: args.warn_on_upload_failure?) + elsif github_releases?(bottles_hash) + github_releases = GitHubReleases.new + github_releases.upload_bottles(bottles_hash) + elsif github_packages?(bottles_hash) + github_org = args.github_org || "homebrew" + github_packages = GitHubPackages.new(org: github_org) + github_packages.upload_bottles(bottles_hash) + else + odie "Service specified by root_url is not recognized" end end end diff --git a/Library/Homebrew/dev-cmd/prof.rb b/Library/Homebrew/dev-cmd/prof.rb index 2f4edb2442..e1e67c2bc3 100644 --- a/Library/Homebrew/dev-cmd/prof.rb +++ b/Library/Homebrew/dev-cmd/prof.rb @@ -13,15 +13,19 @@ module Homebrew Homebrew::CLI::Parser.new do description <<~EOS Run Homebrew with a Ruby profiler. For example, `brew prof readall`. + + *Note:* Not (yet) working on Apple Silicon. EOS switch "--stackprof", description: "Use `stackprof` instead of `ruby-prof` (the default)." - named_args :command + named_args :command, min: 1 end end def prof + raise UsageError, "not (yet) working on Apple Silicon!" if Hardware::CPU.arm? + args = prof_args.parse brew_rb = (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path diff --git a/Library/Homebrew/dev-cmd/release.rb b/Library/Homebrew/dev-cmd/release.rb index a94b1e15ce..b67041c8db 100755 --- a/Library/Homebrew/dev-cmd/release.rb +++ b/Library/Homebrew/dev-cmd/release.rb @@ -39,7 +39,7 @@ module Homebrew begin latest_release = GitHub.get_latest_release "Homebrew", "brew" - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError odie "No existing releases found!" end latest_version = Version.new latest_release["tag_name"] @@ -48,7 +48,7 @@ module Homebrew one_month_ago = Date.today << 1 latest_major_minor_release = begin GitHub.get_release "Homebrew", "brew", "#{latest_version.major_minor}.0" - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError nil end @@ -89,7 +89,7 @@ module Homebrew begin release = GitHub.create_or_update_release "Homebrew", "brew", new_version, body: release_notes, draft: true - rescue *GitHub::API_ERRORS => e + rescue *GitHub::API::ERRORS => e odie "Unable to create release: #{e.message}!" end diff --git a/Library/Homebrew/dev-cmd/rubocop.sh b/Library/Homebrew/dev-cmd/rubocop.sh index b304e7168b..3351d2a245 100644 --- a/Library/Homebrew/dev-cmd/rubocop.sh +++ b/Library/Homebrew/dev-cmd/rubocop.sh @@ -18,8 +18,6 @@ homebrew-rubocop() { export GEM_HOME export PATH="$GEM_HOME/bin:$PATH" - # Unconditional -W0 to avoid printing e.g.: - # warning: parser/current is loading parser/ruby26, which recognizes - # warning: 2.6.6-compliant syntax, but you are running 2.6.3. - exec "$HOMEBREW_RUBY_PATH" "$RUBY_DISABLE_OPTIONS" -W0 -S rubocop "$@" + RUBOCOP="$HOMEBREW_LIBRARY/Homebrew/utils/rubocop.rb" + exec "$HOMEBREW_RUBY_PATH" "$RUBOCOP" "$@" } diff --git a/Library/Homebrew/dev-cmd/sponsors.rb b/Library/Homebrew/dev-cmd/sponsors.rb index 85e0daec19..bf2b9e504f 100644 --- a/Library/Homebrew/dev-cmd/sponsors.rb +++ b/Library/Homebrew/dev-cmd/sponsors.rb @@ -9,55 +9,68 @@ module Homebrew module_function + NAMED_TIER_AMOUNT = 100 + URL_TIER_AMOUNT = 1000 + sig { returns(CLI::Parser) } def sponsors_args Homebrew::CLI::Parser.new do description <<~EOS - Print a Markdown summary of Homebrew's GitHub Sponsors, suitable for pasting into a README. + Update the list of GitHub Sponsors in the `Homebrew/brew` README. EOS named_args :none end end + def sponsor_name(s) + s["name"] || s["login"] + end + + def sponsor_logo(s) + "https://github.com/#{s["login"]}.png?size=64" + end + + def sponsor_url(s) + "https://github.com/#{s["login"]}" + end + def sponsors sponsors_args.parse - sponsors = { - "named" => [], - "users" => 0, - "orgs" => 0, - } + named_sponsors = [] + logo_sponsors = [] GitHub.sponsors_by_tier("Homebrew").each do |tier| - sponsors["named"] += tier["sponsors"] if tier["tier"] >= 100 - sponsors["users"] += tier["count"] - sponsors["orgs"] += tier["sponsors"].count { |s| s["type"] == "organization" } + if tier["tier"] >= NAMED_TIER_AMOUNT + named_sponsors += tier["sponsors"].map do |s| + "[#{sponsor_name(s)}](#{sponsor_url(s)})" + end + end + + next if tier["tier"] < URL_TIER_AMOUNT + + logo_sponsors += tier["sponsors"].map do |s| + "[![#{sponsor_name(s)}](#{sponsor_logo(s)})](#{sponsor_url(s)})" + end end - items = [] - items += sponsors["named"].map { |s| "[#{s["name"]}](https://github.com/#{s["login"]})" } + named_sponsors << "many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew)" - anon_users = sponsors["users"] - sponsors["named"].length - sponsors["orgs"] + readme = HOMEBREW_REPOSITORY/"README.md" + content = readme.read + content.gsub!(/(Homebrew is generously supported by) .*\Z/m, "\\1 #{named_sponsors.to_sentence}.\n") + content << "\n#{logo_sponsors.join}\n" if logo_sponsors.presence - items << if items.length > 1 - "#{anon_users} other users" + File.open(readme, "w+") { |f| f.write(content) } + + diff = system_command "git", args: [ + "-C", HOMEBREW_REPOSITORY, "diff", "--exit-code", "README.md" + ] + if diff.status.success? + puts "No changes to list of sponsors." else - "#{anon_users} users" + puts "List of sponsors updated in the README." end - - if sponsors["orgs"] == 1 - items << "#{sponsors["orgs"]} organization" - elsif sponsors["orgs"] > 1 - items << "#{sponsors["orgs"]} organizations" - end - - sponsor_text = if items.length > 2 - items[0..-2].join(", ") + " and #{items.last}" - else - items.join(" and ") - end - - puts "Homebrew is generously supported by #{sponsor_text} via [GitHub Sponsors](https://github.com/sponsors/Homebrew)." end end diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb index e2043eeb73..fee8572a36 100644 --- a/Library/Homebrew/dev-cmd/tap-new.rb +++ b/Library/Homebrew/dev-cmd/tap-new.rb @@ -22,9 +22,8 @@ module Homebrew flag "--pull-label=", description: "Label name for pull requests ready to be pulled (default: `pr-pull`)." flag "--branch=", - description: "Initialize Git repository with the specified branch name (default: `main`)." - - conflicts "--no-git", "--branch" + description: "Initialize Git repository and setup GitHub Actions workflows with the " \ + "specified branch name (default: `main`)." named_args :tap, number: 1 end @@ -50,11 +49,13 @@ module Homebrew # #{titleized_user} #{titleized_repo} ## How do I install these formulae? + `brew install #{tap}/` Or `brew tap #{tap}` and then `brew install `. ## Documentation + `brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh). MARKDOWN write_path(tap, "README.md", readme) @@ -63,13 +64,14 @@ module Homebrew name: brew test-bot on: push: - branches: #{branch} + branches: + - #{branch} pull_request: jobs: test-bot: strategy: matrix: - os: [ubuntu-latest, macOS-latest] + os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - name: Set up Homebrew diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index 271c682b93..ccf5922536 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -35,6 +35,8 @@ module Homebrew def test args = test_args.parse + Homebrew.install_bundler_gems!(setup_path: false) + require "formula_assertions" require "formula_free_port" @@ -75,10 +77,7 @@ module Homebrew env = ENV.to_hash begin - exec_args = %W[ - #{RUBY_PATH} - #{ENV["HOMEBREW_RUBY_WARNINGS"]} - -I #{$LOAD_PATH.join(File::PATH_SEPARATOR)} + exec_args = HOMEBREW_RUBY_EXEC_ARGS + %W[ -- #{HOMEBREW_LIBRARY_PATH}/test.rb #{f.path} @@ -106,7 +105,7 @@ module Homebrew rescue Exception => e # rubocop:disable Lint/RescueException retry if retry_test?(f, args: args) ofail "#{f.full_name}: failed" - puts e, e.backtrace + $stderr.puts e, e.backtrace ensure ENV.replace(env) end diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index 46b0131457..d25d46a06e 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -78,7 +78,7 @@ module Homebrew elsif args.dependents? formulae = all_formulae = Formula.to_a - @sort = " (sorted by installs in the last 90 days)" + @sort = " (sorted by number of dependents)" else formula_installs = {} @@ -103,7 +103,7 @@ module Homebrew nil end end.compact - @sort = " (sorted by installs in the last 90 days)" + @sort = " (sorted by installs in the last 90 days; top 10,000 only)" all_formulae = Formula end @@ -154,20 +154,51 @@ module Homebrew formulae.each do |f| name = f.name.downcase - if f.bottle_specification.tag?(@bottle_tag) + if f.bottle_specification.tag?(@bottle_tag, exact: true) puts "#{Tty.bold}#{Tty.green}#{name}#{Tty.reset}: already bottled" if any_named_args next end - requirement_classes = f.recursive_requirements.map(&:class) + if f.disabled? + puts "#{Tty.bold}#{Tty.green}#{name}#{Tty.reset}: formula disabled" if any_named_args + next + end + + requirements = f.recursive_requirements if @bottle_tag.to_s.end_with?("_linux") - if requirement_classes.include?(MacOSRequirement) + if requirements.any?(MacOSRequirement) puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: requires macOS" if any_named_args next end - elsif requirement_classes.include?(LinuxRequirement) + elsif requirements.any?(LinuxRequirement) puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: requires Linux" if any_named_args next + else + macos_version = MacOS::Version.from_symbol(@bottle_tag) + macos_satisfied = requirements.all? do |r| + case r + when MacOSRequirement + next true unless r.version_specified? + + macos_version.public_send(r.comparator, r.version) + when XcodeRequirement + next true unless r.version + + Version.new(MacOS::Xcode.latest_version(macos: macos_version)) >= r.version + when ArchRequirement + arch = r.arch + arch = :intel if arch == :x86_64 + arch = :arm64 if arch == :arm + + arch == macos_version.arch + else + true + end + end + unless macos_satisfied + puts "#{Tty.bold}#{Tty.red}#{name}#{Tty.reset}: doesn't support this macOS" if any_named_args + next + end end if f.bottle_unneeded? || f.bottle_disabled? @@ -181,7 +212,7 @@ module Homebrew end deps = Array(deps_hash[f.name]).reject do |dep| - dep.bottle_specification.tag?(@bottle_tag) || dep.bottle_unneeded? + dep.bottle_specification.tag?(@bottle_tag, exact: true) || dep.bottle_unneeded? end if deps.blank? diff --git a/Library/Homebrew/dev-cmd/unpack.rb b/Library/Homebrew/dev-cmd/unpack.rb index 011b87b224..1cc12aa895 100644 --- a/Library/Homebrew/dev-cmd/unpack.rb +++ b/Library/Homebrew/dev-cmd/unpack.rb @@ -38,7 +38,7 @@ module Homebrew formulae = args.named.to_formulae - if dir = args.destdir + if (dir = args.destdir) unpack_dir = Pathname.new(dir).expand_path unpack_dir.mkpath else diff --git a/Library/Homebrew/dev-cmd/update-maintainers.rb b/Library/Homebrew/dev-cmd/update-maintainers.rb index 1ce882b7b5..923aa10edd 100644 --- a/Library/Homebrew/dev-cmd/update-maintainers.rb +++ b/Library/Homebrew/dev-cmd/update-maintainers.rb @@ -3,6 +3,7 @@ require "cli/parser" require "utils/github" +require "dev-cmd/man" module Homebrew extend T::Sig @@ -61,7 +62,8 @@ module Homebrew if diff.status.success? puts "No changes to list of maintainers." else - puts "List of maintainers updated in README." + Homebrew.regenerate_man_pages(preserve_date: true, quiet: true) + puts "List of maintainers updated in the README and the generated man pages." end end end diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb index 55e4a41082..a7b798d49e 100644 --- a/Library/Homebrew/dev-cmd/update-test.rb +++ b/Library/Homebrew/dev-cmd/update-test.rb @@ -54,9 +54,9 @@ module Homebrew start_commit, end_commit = nil cd HOMEBREW_REPOSITORY do - start_commit = if commit = args.commit + start_commit = if (commit = args.commit) commit - elsif date = args.before + elsif (date = args.before) Utils.popen_read("git", "rev-list", "-n1", "--before=#{date}", "origin/master").chomp elsif args.to_tag? tags = Utils.popen_read("git", "tag", "--list", "--sort=-version:refname") diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb index c0e0c33965..33f4cddc8e 100644 --- a/Library/Homebrew/development_tools.rb +++ b/Library/Homebrew/development_tools.rb @@ -43,7 +43,7 @@ class DevelopmentTools def clang_version @clang_version ||= begin if (path = locate("clang")) && - build_version = `#{path} --version`[/(?:clang|LLVM) version (\d+\.\d)/, 1] + (build_version = `#{path} --version`[/(?:clang|LLVM) version (\d+\.\d)/, 1]) Version.new build_version else Version::NULL @@ -54,7 +54,7 @@ class DevelopmentTools def clang_build_version @clang_build_version ||= begin if (path = locate("clang")) && - build_version = `#{path} --version`[%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2] + (build_version = `#{path} --version`[%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2]) Version.new build_version else Version::NULL @@ -66,7 +66,7 @@ class DevelopmentTools @llvm_clang_build_version ||= begin path = Formulary.factory("llvm").opt_prefix/"bin/clang" if path.executable? && - build_version = `#{path} --version`[/clang version (\d\.\d\.\d)/, 1] + (build_version = `#{path} --version`[/clang version (\d+\.\d\.\d)/, 1]) Version.new build_version else Version::NULL @@ -76,10 +76,10 @@ class DevelopmentTools def non_apple_gcc_version(cc) (@non_apple_gcc_version ||= {}).fetch(cc) do - path = HOMEBREW_PREFIX/"opt/gcc/bin"/cc + path = HOMEBREW_PREFIX/"opt/#{CompilerSelector.preferred_gcc}/bin"/cc path = locate(cc) unless path.exist? version = if path && - build_version = `#{path} --version`[/gcc(?:(?:-\d+(?:\.\d)?)? \(.+\))? (\d+\.\d\.\d)/, 1] + (build_version = `#{path} --version`[/gcc(?:(?:-\d+(?:\.\d)?)? \(.+\))? (\d+\.\d\.\d)/, 1]) Version.new build_version else Version::NULL diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 80c31d5210..76e5b5302f 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -13,6 +13,11 @@ require "mechanize/http/content_disposition_parser" require "utils/curl" +require "github_packages" + +require "extend/time" +using TimeRemaining + # @abstract Abstract superclass for all download strategies. # # @api private @@ -50,7 +55,7 @@ class AbstractDownloadStrategy # Download and cache the resource at {#cached_location}. # # @api public - def fetch; end + def fetch(timeout: nil); end # Disable any output during downloading. # @@ -66,30 +71,38 @@ class AbstractDownloadStrategy Context.current.quiet? || @quiet end - # Unpack {#cached_location} into the current working directory, and possibly - # chdir into the newly-unpacked directory. - # Unlike {Resource#stage}, this does not take a block. + # Unpack {#cached_location} into the current working directory. + # + # Additionally, if a block is given, the working directory was previously empty + # and a single directory is extracted from the archive, the block will be called + # with the working directory changed to that directory. Otherwise this method + # will return, or the block will be called, without changing the current working + # directory. # # @api public - def stage + def stage(&block) UnpackStrategy.detect(cached_location, prioritise_extension: true, ref_type: @ref_type, ref: @ref) .extract_nestedly(basename: basename, prioritise_extension: true, verbose: verbose? && !quiet?) - chdir + chdir(&block) if block end - def chdir + def chdir(&block) entries = Dir["*"] raise "Empty archive" if entries.length.zero? - return if entries.length != 1 - begin - Dir.chdir entries.first - rescue - nil + if entries.length != 1 + yield + return + end + + if File.directory? entries.first + Dir.chdir(entries.first, &block) + else + yield end end private :chdir @@ -166,18 +179,20 @@ class VCSDownloadStrategy < AbstractDownloadStrategy # Download and cache the repository at {#cached_location}. # # @api public - def fetch + def fetch(timeout: nil) + end_time = Time.now + timeout if timeout + ohai "Cloning #{url}" if cached_location.exist? && repo_valid? puts "Updating #{cached_location}" - update + update(timeout: timeout) elsif cached_location.exist? puts "Removing invalid repository from cache" clear_cache - clone_repo + clone_repo(timeout: end_time) else - clone_repo + clone_repo(timeout: end_time) end version.update_commit(last_commit) if head? @@ -222,9 +237,11 @@ class VCSDownloadStrategy < AbstractDownloadStrategy raise NotImplementedError end - def clone_repo; end + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil); end - def update; end + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil); end def current_revision; end @@ -303,7 +320,7 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy query_params = CGI.parse(uri.query) query_params["response-content-disposition"].each do |param| query_basename = param[/attachment;\s*filename=(["']?)(.+)\1/i, 2] - return query_basename if query_basename + return File.basename(query_basename) if query_basename end end @@ -343,7 +360,9 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy # Download and cache the file at {#cached_location}. # # @api public - def fetch + def fetch(timeout: nil) + end_time = Time.now + timeout if timeout + download_lock = LockFile.new(temporary_path.basename) download_lock.lock @@ -354,7 +373,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy ohai "Downloading #{url}" - resolved_url, _, url_time, = resolve_url_basename_time_file_size(url) + resolved_url, _, url_time, = resolve_url_basename_time_file_size(url, timeout: end_time&.remaining!) fresh = if cached_location.exist? && url_time url_time <= cached_location.mtime @@ -368,7 +387,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy puts "Already downloaded: #{cached_location}" else begin - _fetch(url: url, resolved_url: resolved_url) + _fetch(url: url, resolved_url: resolved_url, timeout: end_time&.remaining!) rescue ErrorDuringExecution raise CurlDownloadStrategyError, url end @@ -385,6 +404,8 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy puts "Trying a mirror..." retry + rescue Timeout::Error => e + raise Timeout::Error, "Timed out downloading #{self.url}: #{e}" end ensure download_lock&.unlock @@ -396,19 +417,19 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy rm_rf(temporary_path) end - def resolved_time_file_size - _, _, time, file_size = resolve_url_basename_time_file_size(url) + def resolved_time_file_size(timeout: nil) + _, _, time, file_size = resolve_url_basename_time_file_size(url, timeout: timeout) [time, file_size] end private - def resolved_url_and_basename - resolved_url, basename, = resolve_url_basename_time_file_size(url) + def resolved_url_and_basename(timeout: nil) + resolved_url, basename, = resolve_url_basename_time_file_size(url, timeout: nil) [resolved_url, basename] end - def resolve_url_basename_time_file_size(url) + def resolve_url_basename_time_file_size(url, timeout: nil) @resolved_info_cache ||= {} return @resolved_info_cache[url] if @resolved_info_cache.include?(url) @@ -416,7 +437,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy url = url.sub(%r{^((ht|f)tps?://)?}, "#{domain.chomp("/")}/") end - out, _, status= curl_output("--location", "--silent", "--head", "--request", "GET", url.to_s) + out, _, status= curl_output("--location", "--silent", "--head", "--request", "GET", url.to_s, timeout: timeout) lines = status.success? ? out.lines.map(&:chomp) : [] @@ -441,16 +462,19 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy content_disposition_parser = Mechanize::HTTP::ContentDispositionParser.new parse_content_disposition = lambda do |line| - next unless content_disposition = content_disposition_parser.parse(line.sub(/; *$/, ""), true) + next unless (content_disposition = content_disposition_parser.parse(line.sub(/; *$/, ""), true)) filename = nil - if filename_with_encoding = content_disposition.parameters["filename*"] + if (filename_with_encoding = content_disposition.parameters["filename*"]) encoding, encoded_filename = filename_with_encoding.split("''", 2) filename = URI.decode_www_form_component(encoded_filename).encode(encoding) if encoding && encoded_filename end - filename || content_disposition.filename + # Servers may include '/' in their Content-Disposition filename header. Take only the basename of this, because: + # - Unpacking code assumes this is a single file - not something living in a subdirectory. + # - Directory traversal attacks are possible without limiting this to just the basename. + File.basename(filename || content_disposition.filename) end filenames = lines.map(&parse_content_disposition).compact @@ -472,7 +496,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy @resolved_info_cache[url] = [redirect_url, basename, time, file_size] end - def _fetch(url:, resolved_url:) + def _fetch(url:, resolved_url:, timeout:) ohai "Downloading from #{resolved_url}" if url != resolved_url if Homebrew::EnvConfig.no_insecure_redirect? && @@ -481,7 +505,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy raise CurlDownloadStrategyError, url end - curl_download resolved_url, to: temporary_path + curl_download resolved_url, to: temporary_path, timeout: timeout end # Curl options to be always passed to curl, @@ -516,6 +540,25 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy end end +# Strategy for downloading a file from an GitHub Packages URL. +# +# @api public +class CurlGitHubPackagesDownloadStrategy < CurlDownloadStrategy + attr_accessor :checksum, :name + + private + + def _fetch(url:, resolved_url:) + raise "Empty checksum" if checksum.blank? + raise "Empty name" if name.blank? + + _, org, repo, = *url.match(GitHubPackages::URL_REGEX) + + blob_url = "https://ghcr.io/v2/#{org}/#{repo}/#{name}/blobs/sha256:#{checksum}" + curl_download(blob_url, "--header", "Authorization: Bearer", to: temporary_path) + end +end + # Strategy for downloading a file from an Apache Mirror URL. # # @api public @@ -535,9 +578,9 @@ class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy @combined_mirrors = [*@mirrors, *backup_mirrors] end - def resolve_url_basename_time_file_size(url) + def resolve_url_basename_time_file_size(url, timeout: nil) if url == self.url - super("#{apache_mirrors["preferred"]}#{apache_mirrors["path_info"]}") + super("#{apache_mirrors["preferred"]}#{apache_mirrors["path_info"]}", timeout: timeout) else super end @@ -560,7 +603,7 @@ end class CurlPostDownloadStrategy < CurlDownloadStrategy private - def _fetch(url:, resolved_url:) + def _fetch(url:, resolved_url:, timeout:) args = if meta.key?(:data) escape_data = ->(d) { ["-d", URI.encode_www_form([d])] } [url, *meta[:data].flat_map(&escape_data)] @@ -569,7 +612,7 @@ class CurlPostDownloadStrategy < CurlDownloadStrategy query.nil? ? [url, "-X", "POST"] : [url, "-d", query] end - curl_download(*args, to: temporary_path) + curl_download(*args, to: temporary_path, timeout: timeout) end end @@ -582,6 +625,7 @@ class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy UnpackStrategy::Uncompressed.new(cached_location) .extract(basename: basename, verbose: verbose? && !quiet?) + yield if block_given? end end @@ -608,7 +652,7 @@ class SubversionDownloadStrategy < VCSDownloadStrategy # Download and cache the repository at {#cached_location}. # # @api public - def fetch + def fetch(timeout: nil) if @url.chomp("/") != repo_url || !silent_command("svn", args: ["switch", @url, cached_location]).success? clear_cache end @@ -649,7 +693,11 @@ class SubversionDownloadStrategy < VCSDownloadStrategy end end - def fetch_repo(target, url, revision = nil, ignore_externals: false) + sig { + params(target: Pathname, url: String, revision: T.nilable(String), ignore_externals: T::Boolean, + timeout: T.nilable(Time)).void + } + def fetch_repo(target, url, revision = nil, ignore_externals: false, timeout: nil) # Use "svn update" when the repository already exists locally. # This saves on bandwidth and will have a similar effect to verifying the # cache as it will make any changes to get the right revision. @@ -669,9 +717,9 @@ class SubversionDownloadStrategy < VCSDownloadStrategy end if target.directory? - command!("svn", args: ["update", *args], chdir: target.to_s) + command! "svn", args: ["update", *args], chdir: target.to_s, timeout: timeout&.remaining else - command!("svn", args: ["checkout", url, target, *args]) + command! "svn", args: ["checkout", url, target, *args], timeout: timeout&.remaining end end @@ -684,20 +732,22 @@ class SubversionDownloadStrategy < VCSDownloadStrategy (cached_location/".svn").directory? end - def clone_repo + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) case @ref_type when :revision - fetch_repo cached_location, @url, @ref + fetch_repo cached_location, @url, @ref, timeout: timeout when :revisions # nil is OK for main_revision, as fetch_repo will then get latest main_revision = @ref[:trunk] - fetch_repo cached_location, @url, main_revision, ignore_externals: true + fetch_repo cached_location, @url, main_revision, ignore_externals: true, timeout: timeout externals do |external_name, external_url| - fetch_repo cached_location/external_name, external_url, @ref[external_name], ignore_externals: true + fetch_repo cached_location/external_name, external_url, @ref[external_name], ignore_externals: true, + timeout: timeout end else - fetch_repo cached_location, @url + fetch_repo cached_location, @url, timeout: timeout end end alias update clone_repo @@ -746,12 +796,13 @@ class GitDownloadStrategy < VCSDownloadStrategy 0 end - def update + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil) config_repo - update_repo - checkout + update_repo(timeout: timeout) + checkout(timeout: timeout) reset - update_submodules if submodules? + update_submodules(timeout: timeout) if submodules? end def shallow_clone? @@ -812,6 +863,7 @@ class GitDownloadStrategy < VCSDownloadStrategy end end + sig { void } def config_repo command! "git", args: ["config", "remote.origin.url", @url], @@ -824,35 +876,42 @@ class GitDownloadStrategy < VCSDownloadStrategy chdir: cached_location end - def update_repo + sig { params(timeout: T.nilable(Time)).void } + def update_repo(timeout: nil) return if @ref_type != :branch && ref? if !shallow_clone? && shallow_dir? command! "git", - args: ["fetch", "origin", "--unshallow"], - chdir: cached_location + args: ["fetch", "origin", "--unshallow"], + chdir: cached_location, + timeout: timeout&.remaining else command! "git", - args: ["fetch", "origin"], - chdir: cached_location + args: ["fetch", "origin"], + chdir: cached_location, + timeout: timeout&.remaining end end - def clone_repo - command! "git", args: clone_args + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) + command! "git", args: clone_args, timeout: timeout&.remaining command! "git", - args: ["config", "homebrew.cacheversion", cache_version], - chdir: cached_location - checkout - update_submodules if submodules? + args: ["config", "homebrew.cacheversion", cache_version], + chdir: cached_location, + timeout: timeout&.remaining + checkout(timeout: timeout) + update_submodules(timeout: timeout) if submodules? end - def checkout + sig { params(timeout: T.nilable(Time)).void } + def checkout(timeout: nil) ohai "Checking out #{@ref_type} #{@ref}" if @ref_type && @ref - command! "git", args: ["checkout", "-f", @ref, "--"], chdir: cached_location + command! "git", args: ["checkout", "-f", @ref, "--"], chdir: cached_location, timeout: timeout&.remaining end + sig { void } def reset ref = case @ref_type when :branch @@ -866,13 +925,16 @@ class GitDownloadStrategy < VCSDownloadStrategy chdir: cached_location end - def update_submodules + sig { params(timeout: T.nilable(Time)).void } + def update_submodules(timeout: nil) command! "git", - args: ["submodule", "foreach", "--recursive", "git submodule sync"], - chdir: cached_location + args: ["submodule", "foreach", "--recursive", "git submodule sync"], + chdir: cached_location, + timeout: timeout&.remaining command! "git", - args: ["submodule", "update", "--init", "--recursive"], - chdir: cached_location + args: ["submodule", "update", "--init", "--recursive"], + chdir: cached_location, + timeout: timeout&.remaining fix_absolute_submodule_gitdir_references! end @@ -1024,23 +1086,27 @@ class CVSDownloadStrategy < VCSDownloadStrategy "-Q" unless verbose? end - def clone_repo + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) # Login is only needed (and allowed) with pserver; skip for anoncvs. - command! "cvs", args: [*quiet_flag, "-d", @url, "login"] if @url.include? "pserver" + command! "cvs", args: [*quiet_flag, "-d", @url, "login"], timeout: timeout&.remaining if @url.include? "pserver" command! "cvs", - args: [*quiet_flag, "-d", @url, "checkout", "-d", cached_location.basename, @module], - chdir: cached_location.dirname + args: [*quiet_flag, "-d", @url, "checkout", "-d", cached_location.basename, @module], + chdir: cached_location.dirname, + timeout: timeout&.remaining end - def update + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil) command! "cvs", - args: [*quiet_flag, "update"], - chdir: cached_location + args: [*quiet_flag, "update"], + chdir: cached_location, + timeout: timeout&.remaining end def split_url(in_url) - parts = in_url.split(/:/) + parts = in_url.split(":") mod = parts.pop url = parts.join(":") [mod, url] @@ -1088,12 +1154,14 @@ class MercurialDownloadStrategy < VCSDownloadStrategy (cached_location/".hg").directory? end - def clone_repo - command! "hg", args: ["clone", @url, cached_location] + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) + command! "hg", args: ["clone", @url, cached_location], timeout: timeout&.remaining end - def update - command! "hg", args: ["--cwd", cached_location, "pull", "--update"] + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil) + command! "hg", args: ["--cwd", cached_location, "pull", "--update"], timeout: timeout&.remaining update_args = if @ref_type && @ref ohai "Checking out #{@ref_type} #{@ref}" @@ -1102,7 +1170,7 @@ class MercurialDownloadStrategy < VCSDownloadStrategy ["--clean"] end - command! "hg", args: ["--cwd", cached_location, "update", *update_args] + command! "hg", args: ["--cwd", cached_location, "update", *update_args], timeout: timeout&.remaining end end @@ -1151,16 +1219,20 @@ class BazaarDownloadStrategy < VCSDownloadStrategy (cached_location/".bzr").directory? end - def clone_repo + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) # "lightweight" means history-less command! "bzr", - args: ["checkout", "--lightweight", @url, cached_location] + args: ["checkout", "--lightweight", @url, cached_location], + timeout: timeout&.remaining end - def update + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil) command! "bzr", - args: ["update"], - chdir: cached_location + args: ["update"], + chdir: cached_location, + timeout: timeout&.remaining end end @@ -1203,12 +1275,14 @@ class FossilDownloadStrategy < VCSDownloadStrategy "fossil" end - def clone_repo - silent_command!("fossil", args: ["clone", @url, cached_location]) + sig { params(timeout: T.nilable(Time)).void } + def clone_repo(timeout: nil) + silent_command! "fossil", args: ["clone", @url, cached_location], timeout: timeout&.remaining end - def update - silent_command!("fossil", args: ["pull", "-R", cached_location]) + sig { params(timeout: T.nilable(Time)).void } + def update(timeout: nil) + silent_command! "fossil", args: ["pull", "-R", cached_location], timeout: timeout&.remaining end end @@ -1231,6 +1305,8 @@ class DownloadStrategyDetector def self.detect_from_url(url) case url + when GitHubPackages::URL_REGEX + CurlGitHubPackagesDownloadStrategy when %r{^https?://github\.com/[^/]+/[^/]+\.git$} GitHubGitDownloadStrategy when %r{^https?://.+\.git$}, diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index 0355cd315b..cd8ff0a1a5 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -46,8 +46,12 @@ module Homebrew }, HOMEBREW_BOTTLE_DOMAIN: { description: "Use this URL as the download mirror for bottles. " \ + "If bottles at that URL are temporarily unavailable, " \ + "the default bottle domain will be used as a fallback mirror. " \ "For example, `HOMEBREW_BOTTLE_DOMAIN=http://localhost:8080` will cause all bottles to " \ - "download from the prefix `http://localhost:8080/`.", + "download from the prefix `http://localhost:8080/`. " \ + "If bottles are not available at `HOMEBREW_BOTTLE_DOMAIN` " \ + "they will be downloaded from the default bottle domain.", default_text: "macOS: `https://homebrew.bintray.com/`, " \ "Linux: `https://linuxbrew.bintray.com/`.", default: HOMEBREW_BOTTLE_DEFAULT_DOMAIN, @@ -168,6 +172,13 @@ module Homebrew "\n\n *Note:* Homebrew doesn't require permissions for any of the scopes, but some " \ "developer commands may require additional permissions.", }, + HOMEBREW_GITHUB_PACKAGES_TOKEN: { + description: "Use this GitHub personal access token when accessing the GitHub Packages Registry "\ + "(where bottles may be stored).", + }, + HOMEBREW_GITHUB_PACKAGES_USER: { + description: "Use this username when accessing the GitHub Packages Registry (where bottles may be stored).", + }, HOMEBREW_GIT_EMAIL: { description: "Set the Git author and committer email to this value.", }, @@ -179,6 +190,10 @@ module Homebrew default_text: 'The "Beer Mug" emoji.', default: "🍺", }, + HOMEBREW_INTERNET_ARCHIVE_KEY: { + description: "Use this API key when accessing the Internet Archive S3 API, where bottles are stored. " \ + "The format is access:secret. See https://archive.org/account/s3.php", + }, HOMEBREW_LIVECHECK_WATCHLIST: { description: "Consult this file for the list of formulae to check by default when no formula argument " \ "is passed to `brew livecheck`.", @@ -204,19 +219,14 @@ module Homebrew boolean: true, }, HOMEBREW_NO_AUTO_UPDATE: { - description: "If set, do not automatically update before running " \ - "`brew install`, `brew upgrade` or `brew tap`.", + description: "If set, do not automatically update before running some commands e.g. " \ + "`brew install`, `brew upgrade` and `brew tap`.", boolean: true, }, HOMEBREW_NO_BOOTSNAP: { description: "If set, do not use Bootsnap to speed up repeated `brew` calls.", boolean: true, }, - HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: { - description: "If set, fail on the failure of installation from a bottle rather than " \ - "falling back to building from source.", - boolean: true, - }, HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: { description: "If set, do not check for broken dependents after installing, upgrading or reinstalling " \ "formulae.", @@ -257,6 +267,11 @@ module Homebrew description: "If set, use Pry for the `brew irb` command.", boolean: true, }, + HOMEBREW_SIMULATE_MACOS_ON_LINUX: { + description: "If set, running Homebrew on Linux will simulate certain macOS code paths. This is useful " \ + "when auditing macOS formulae while on Linux. Implies `HOMEBREW_FORCE_HOMEBREW_ON_LINUX`.", + boolean: true, + }, HOMEBREW_SKIP_OR_LATER_BOTTLES: { description: "If set along with `HOMEBREW_DEVELOPER`, do not use bottles from older versions " \ "of macOS. This is useful in development on new macOS versions.", diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 3c277e20c4..cadf8a5313 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -97,6 +97,25 @@ class FormulaOrCaskUnavailableError < RuntimeError end end +# Raised when a formula or cask in a specific tap is not available. +class TapFormulaOrCaskUnavailableError < FormulaOrCaskUnavailableError + extend T::Sig + + attr_reader :tap + + def initialize(tap, name) + super "#{tap}/#{name}" + @tap = tap + end + + sig { returns(String) } + def to_s + s = super + s += "\nPlease tap it and then try again: brew tap #{tap}" unless tap.installed? + s + end +end + # Raised when a formula is not available. class FormulaUnavailableError < FormulaOrCaskUnavailableError extend T::Sig @@ -423,7 +442,7 @@ class BuildError < RuntimeError def fetch_issues GitHub.issues_for_formula(formula.name, tap: formula.tap, state: "open") - rescue GitHub::RateLimitExceededError => e + rescue GitHub::API::RateLimitExceededError => e opoo e.message [] end @@ -453,7 +472,7 @@ class BuildError < RuntimeError if formula.tap && defined?(OS::ISSUES_URL) if formula.tap.official? puts Formatter.error(Formatter.url(OS::ISSUES_URL), label: "READ THIS") - elsif issues_url = formula.tap.issues_url + elsif (issues_url = formula.tap.issues_url) puts <<~EOS If reporting this issue please do so at (not Homebrew/brew or Homebrew/core): #{Formatter.url(issues_url)} @@ -579,19 +598,32 @@ class ErrorDuringExecution < RuntimeError @status = status @output = output + raise ArgumentError, "Status cannot be nil." if status.nil? + exitstatus = case status when Integer status + when Hash + status["exitstatus"] else - status&.exitstatus + status.exitstatus + end + + termsig = case status + when Integer + nil + when Hash + status["termsig"] + else + status.termsig end redacted_cmd = redact_secrets(cmd.shelljoin.gsub('\=', "="), secrets) reason = if exitstatus "exited with #{exitstatus}" - elsif (uncaught_signal = status&.termsig) - "was terminated by uncaught signal #{Signal.signame(uncaught_signal)}" + elsif termsig + "was terminated by uncaught signal #{Signal.signame(termsig)}" else raise ArgumentError, "Status neither has `exitstatus` nor `termsig`." end diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 051b6ac9e6..c0ff5610cc 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -35,7 +35,7 @@ module EnvActivation params( env: T.nilable(String), cc: T.nilable(String), - build_bottle: T.nilable(T::Boolean), + build_bottle: T::Boolean, bottle_arch: T.nilable(String), _block: T.proc.returns(T.untyped), ).returns(T.untyped) diff --git a/Library/Homebrew/extend/ENV/shared.rb b/Library/Homebrew/extend/ENV/shared.rb index d81f3328bc..2d1c85014a 100644 --- a/Library/Homebrew/extend/ENV/shared.rb +++ b/Library/Homebrew/extend/ENV/shared.rb @@ -35,13 +35,14 @@ module SharedEnvExtension sig { params( - formula: T.nilable(Formula), - cc: T.nilable(String), - build_bottle: T.nilable(T::Boolean), - bottle_arch: T.nilable(T::Boolean), + formula: T.nilable(Formula), + cc: T.nilable(String), + build_bottle: T.nilable(T::Boolean), + bottle_arch: T.nilable(String), + testing_formula: T::Boolean, ).void } - def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil) + def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) @formula = formula @cc = cc @build_bottle = build_bottle diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index b94f31533f..924155f83a 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -16,13 +16,14 @@ module Stdenv # @private sig { params( - formula: T.nilable(Formula), - cc: T.nilable(String), - build_bottle: T.nilable(T::Boolean), - bottle_arch: T.nilable(T::Boolean), + formula: T.nilable(Formula), + cc: T.nilable(String), + build_bottle: T.nilable(T::Boolean), + bottle_arch: T.nilable(String), + testing_formula: T::Boolean, ).void } - def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil) + def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) super self["HOMEBREW_ENV"] = "std" diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index aae72826bb..bacc76e7ea 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -44,13 +44,14 @@ module Superenv # @private sig { params( - formula: T.nilable(Formula), - cc: T.nilable(String), - build_bottle: T.nilable(T::Boolean), - bottle_arch: T.nilable(T::Boolean), + formula: T.nilable(Formula), + cc: T.nilable(String), + build_bottle: T.nilable(T::Boolean), + bottle_arch: T.nilable(String), + testing_formula: T::Boolean, ).void } - def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil) + def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) super send(compiler) diff --git a/Library/Homebrew/extend/git_repository.rb b/Library/Homebrew/extend/git_repository.rb index b5a54742f8..a91ec91704 100644 --- a/Library/Homebrew/extend/git_repository.rb +++ b/Library/Homebrew/extend/git_repository.rb @@ -32,14 +32,14 @@ module GitRepositoryExtension # Gets the full commit hash of the HEAD commit. sig { params(safe: T::Boolean).returns(T.nilable(String)) } def git_head(safe: false) - popen_git("rev-parse", "--verify", "-q", "HEAD", safe: safe) + popen_git("rev-parse", "--verify", "--quiet", "HEAD", safe: safe) end # Gets a short commit hash of the HEAD commit. sig { params(length: T.nilable(Integer), safe: T::Boolean).returns(T.nilable(String)) } def git_short_head(length: nil, safe: false) short_arg = length.present? ? "--short=#{length}" : "--short" - popen_git("rev-parse", short_arg, "--verify", "-q", "HEAD", safe: safe) + popen_git("rev-parse", short_arg, "--verify", "--quiet", "HEAD", safe: safe) end # Gets the relative date of the last commit, e.g. "1 hour ago" diff --git a/Library/Homebrew/extend/os/linux/extend/ENV/std.rb b/Library/Homebrew/extend/os/linux/extend/ENV/std.rb index 56d7793a57..79dba61cb4 100644 --- a/Library/Homebrew/extend/os/linux/extend/ENV/std.rb +++ b/Library/Homebrew/extend/os/linux/extend/ENV/std.rb @@ -3,7 +3,10 @@ module Stdenv def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) + generic_setup_build_environment( + formula: formula, cc: cc, build_bottle: build_bottle, + bottle_arch: bottle_arch, testing_formula: testing_formula + ) prepend_path "CPATH", HOMEBREW_PREFIX/"include" prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib" diff --git a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb index 2e6b36be95..07675d4135 100644 --- a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb @@ -11,7 +11,10 @@ module Superenv # @private def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) + generic_setup_build_environment( + formula: formula, cc: cc, build_bottle: build_bottle, + bottle_arch: bottle_arch, testing_formula: testing_formula + ) self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2" self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula) diff --git a/Library/Homebrew/extend/os/linux/keg_relocate.rb b/Library/Homebrew/extend/os/linux/keg_relocate.rb index 8a3d713abd..728f36e067 100644 --- a/Library/Homebrew/extend/os/linux/keg_relocate.rb +++ b/Library/Homebrew/extend/os/linux/keg_relocate.rb @@ -80,7 +80,11 @@ class Keg end def self.relocation_formulae - ["patchelf"] + @relocation_formulae ||= if HOMEBREW_PATCHELF_RB_WRITE + [] + else + ["patchelf"] + end.freeze end def self.bottle_dependencies diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb index f101a31056..6f25836ae3 100644 --- a/Library/Homebrew/extend/os/mac/development_tools.rb +++ b/Library/Homebrew/extend/os/mac/development_tools.rb @@ -51,10 +51,7 @@ class DevelopmentTools sig { returns(String) } def installation_instructions - <<~EOS - Install the Command Line Tools: - xcode-select --install - EOS + MacOS::CLT.installation_instructions end sig { returns(String) } diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index 71fe9f3c4a..69aa335b23 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -64,6 +64,7 @@ module Homebrew check_clt_minimum_version check_if_xcode_needs_clt_installed check_if_supported_sdk_available + check_broken_sdks ].freeze end @@ -425,7 +426,7 @@ module Homebrew source = if locator.source == :clt update_instructions = MacOS::CLT.update_instructions - "CLT" + "Command Line Tools (CLT)" else update_instructions = MacOS::Xcode.update_instructions "Xcode" @@ -438,6 +439,40 @@ module Homebrew #{update_instructions} EOS end + + # The CLT 10.x -> 11.x upgrade process on 10.14 contained a bug which broke the SDKs. + # Notably, MacOSX10.14.sdk would indirectly symlink to MacOSX10.15.sdk. + # This diagnostic was introduced to check for this and recommend a full reinstall. + def check_broken_sdks + locator = MacOS.sdk_locator + + return if locator.all_sdks.all? do |sdk| + path_version = sdk.path.basename.to_s[MacOS::SDK::VERSIONED_SDK_REGEX, 1] + next true if path_version.blank? + + sdk.version == MacOS::Version.new(path_version).strip_patch + end + + if locator.source == :clt + source = "Command Line Tools (CLT)" + path_to_remove = MacOS::CLT::PKG_PATH + installation_instructions = MacOS::CLT.installation_instructions + else + source = "Xcode" + path_to_remove = MacOS::Xcode.bundle_path + installation_instructions = MacOS::Xcode.installation_instructions + end + + <<~EOS + The contents of the SDKs in your #{source} installation do not match the SDK folder names. + A clean reinstall of #{source} should fix this. + + Remove the broken installation before reinstalling: + sudo rm -rf #{path_to_remove} + + #{installation_instructions} + EOS + end end end end diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb index a51952a508..5500df0b5a 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb @@ -11,7 +11,10 @@ module Stdenv end def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) + generic_setup_build_environment( + formula: formula, cc: cc, build_bottle: build_bottle, + bottle_arch: bottle_arch, testing_formula: testing_formula + ) # sed is strict, and errors out when it encounters files with # mixed character sets diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb index 2e3e3c13a7..e58a10e577 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb @@ -98,8 +98,6 @@ module Superenv def determine_cccfg s = +"" - # Fix issue with sed barfing on unicode characters on Mountain Lion - s << "s" # Fix issue with >= Mountain Lion apr-1-config having broken paths s << "a" s.freeze @@ -121,7 +119,10 @@ module Superenv self["HOMEBREW_SDKROOT"] = nil self["HOMEBREW_DEVELOPER_DIR"] = nil end - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) + generic_setup_build_environment( + formula: formula, cc: cc, build_bottle: build_bottle, + bottle_arch: bottle_arch, testing_formula: testing_formula + ) # Filter out symbols known not to be defined since GNU Autotools can't # reliably figure this out with Xcode 8 and above. diff --git a/Library/Homebrew/extend/os/mac/software_spec.rb b/Library/Homebrew/extend/os/mac/software_spec.rb index 221c0c4ca6..f365951271 100644 --- a/Library/Homebrew/extend/os/mac/software_spec.rb +++ b/Library/Homebrew/extend/os/mac/software_spec.rb @@ -1,6 +1,8 @@ # typed: false # frozen_string_literal: true +# The Library/Homebrew/extend/os/software_spec.rb conditional logic will need to be more nuanced +# if this file ever includes more than `uses_from_macos`. class SoftwareSpec undef uses_from_macos @@ -9,11 +11,12 @@ class SoftwareSpec if deps.is_a?(Hash) bounds = deps.dup - deps = Hash[*bounds.shift] + deps = bounds.shift end bounds = bounds.transform_values { |v| MacOS::Version.from_symbol(v) } - if MacOS.version >= bounds[:since] + if MacOS.version >= bounds[:since] || + (Homebrew::EnvConfig.simulate_macos_on_linux? && !bounds.key?(:since)) @uses_from_macos_elements << deps else depends_on deps diff --git a/Library/Homebrew/extend/os/mac/utils/bottles.rb b/Library/Homebrew/extend/os/mac/utils/bottles.rb index 75023c1473..61141336a1 100644 --- a/Library/Homebrew/extend/os/mac/utils/bottles.rb +++ b/Library/Homebrew/extend/os/mac/utils/bottles.rb @@ -20,10 +20,10 @@ module Utils alias generic_find_matching_tag find_matching_tag - def find_matching_tag(tag) + def find_matching_tag(tag, exact: false) # Used primarily by developers testing beta macOS releases. - if OS::Mac.prerelease? && Homebrew::EnvConfig.developer? && - Homebrew::EnvConfig.skip_or_later_bottles? + if exact || (OS::Mac.prerelease? && Homebrew::EnvConfig.developer? && + Homebrew::EnvConfig.skip_or_later_bottles?) generic_find_matching_tag(tag) else generic_find_matching_tag(tag) || diff --git a/Library/Homebrew/extend/os/on_os.rb b/Library/Homebrew/extend/os/on_os.rb index 38e1bce2e1..c74ea9d459 100644 --- a/Library/Homebrew/extend/os/on_os.rb +++ b/Library/Homebrew/extend/os/on_os.rb @@ -1,7 +1,7 @@ # typed: strict # frozen_string_literal: true -if OS.mac? +if OS.mac? || Homebrew::EnvConfig.simulate_macos_on_linux? require "extend/os/mac/on_os" elsif OS.linux? require "extend/os/linux/on_os" diff --git a/Library/Homebrew/extend/os/software_spec.rb b/Library/Homebrew/extend/os/software_spec.rb index 15da2d0e5a..32f46468f7 100644 --- a/Library/Homebrew/extend/os/software_spec.rb +++ b/Library/Homebrew/extend/os/software_spec.rb @@ -1,8 +1,9 @@ # typed: strict # frozen_string_literal: true -if OS.linux? - require "extend/os/linux/software_spec" -elsif OS.mac? +# This logic will need to be more nuanced if this file includes more than `uses_from_macos`. +if OS.mac? || Homebrew::EnvConfig.simulate_macos_on_linux? require "extend/os/mac/software_spec" +elsif OS.linux? + require "extend/os/linux/software_spec" end diff --git a/Library/Homebrew/extend/time.rb b/Library/Homebrew/extend/time.rb new file mode 100644 index 0000000000..81779cd8dc --- /dev/null +++ b/Library/Homebrew/extend/time.rb @@ -0,0 +1,18 @@ +# typed: false +# frozen_string_literal: true + +module TimeRemaining + refine Time do + def remaining + [0, self - Time.now].max + end + + def remaining! + r = remaining + + raise Timeout::Error if r <= 0 + + r + end + end +end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 9ffd65f6f9..71f79ce207 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2061,7 +2061,7 @@ class Formula if verbose_using_dots last_dot = Time.at(0) - while buf = rd.gets + while (buf = rd.gets) log.puts buf # make sure dots printed with interval of at least 1 min. next unless (Time.now - last_dot) > 60 @@ -2072,7 +2072,7 @@ class Formula end puts else - while buf = rd.gets + while (buf = rd.gets) log.puts buf puts buf end diff --git a/Library/Homebrew/formula_assertions.rb b/Library/Homebrew/formula_assertions.rb index 2ab9bfc036..08eb5117df 100644 --- a/Library/Homebrew/formula_assertions.rb +++ b/Library/Homebrew/formula_assertions.rb @@ -8,8 +8,54 @@ module Homebrew module Assertions include Context - require "test/unit/assertions" - include ::Test::Unit::Assertions + require "minitest" + require "minitest/assertions" + include ::Minitest::Assertions + + attr_writer :assertions + + def assertions + @assertions ||= 0 + end + + # Test::Unit backwards compatibility methods + { + assert_include: :assert_includes, + assert_path_exist: :assert_path_exists, + assert_raise: :assert_raises, + assert_throw: :assert_throws, + assert_not_empty: :refute_empty, + assert_not_equal: :refute_equal, + assert_not_in_delta: :refute_in_delta, + assert_not_in_epsilon: :refute_in_epsilon, + assert_not_include: :refute_includes, + assert_not_includes: :refute_includes, + assert_not_instance_of: :refute_instance_of, + assert_not_kind_of: :refute_kind_of, + assert_not_match: :refute_match, + assert_no_match: :refute_match, + assert_not_nil: :refute_nil, + assert_not_operator: :refute_operator, + assert_path_not_exist: :refute_path_exists, + assert_not_predicate: :refute_predicate, + assert_not_respond_to: :refute_respond_to, + assert_not_same: :refute_same, + }.each do |old_method, new_method| + define_method(old_method) do |*args| + # odeprecated old_method, new_method + send(new_method, *args) + end + end + + def assert_true(act, msg = nil) + # odeprecated "assert_true", "assert(...) or assert_equal(true, ...)" + assert_equal(true, act, msg) + end + + def assert_false(act, msg = nil) + # odeprecated "assert_false", "assert(!...) or assert_equal(false, ...)" + assert_equal(false, act, msg) + end # Returns the output of running cmd, and asserts the exit status. # @api public @@ -18,7 +64,7 @@ module Homebrew output = `#{cmd}` assert_equal result, $CHILD_STATUS.exitstatus output - rescue Test::Unit::AssertionFailedError + rescue Minitest::Assertion puts output if verbose? raise end @@ -35,7 +81,7 @@ module Homebrew end assert_equal result, $CHILD_STATUS.exitstatus unless result.nil? output - rescue Test::Unit::AssertionFailedError + rescue Minitest::Assertion puts output if verbose? raise end diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index 761d921710..f044ec817f 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -133,7 +133,7 @@ module Homebrew return end - if oldname = CoreTap.instance.formula_renames[name] + if (oldname = CoreTap.instance.formula_renames[name]) problem "'#{name}' is reserved as the old name of #{oldname} in homebrew/core." return end @@ -282,7 +282,7 @@ module Homebrew # The number of conflicts on Linux is absurd. # TODO: remove this and check these there too. - return if OS.linux? + return if OS.linux? && !Homebrew::EnvConfig.simulate_macos_on_linux? recursive_runtime_formulae = formula.runtime_formula_dependencies(undeclared: false) version_hash = {} @@ -339,6 +339,18 @@ module Homebrew end end + def audit_glibc + return if formula.name != "glibc" + return unless @core_tap + + version = formula.version.to_s + return if version == "2.23" + + problem "The glibc version must be #{version}, as this is the version used by our CI on Linux. " \ + "Glibc is for users who have a system Glibc with a lower version, " \ + "which allows them to use our Linux bottles, which were compiled against system Glibc on CI." + end + def audit_versioned_keg_only return unless @versioned_formula return unless @core_tap @@ -367,10 +379,10 @@ module Homebrew return unless DevelopmentTools.curl_handles_most_https_certificates? - if http_content_problem = curl_check_http_content(homepage, - user_agents: [:browser, :default], - check_content: true, - strict: @strict) + if (http_content_problem = curl_check_http_content(homepage, + user_agents: [:browser, :default], + check_content: true, + strict: @strict)) problem http_content_problem end end @@ -472,7 +484,7 @@ module Homebrew %w[Stable HEAD].each do |name| spec_name = name.downcase.to_sym - next unless spec = formula.send(spec_name) + next unless (spec = formula.send(spec_name)) ra = ResourceAuditor.new(spec, spec_name, online: @online, strict: @strict).audit ra.problems.each do |message| @@ -497,7 +509,7 @@ module Homebrew ) end - if stable = formula.stable + if (stable = formula.stable) version = stable.version problem "Stable: version (#{version}) is set to a string without a digit" if version.to_s !~ /\d/ if version.to_s.start_with?("HEAD") diff --git a/Library/Homebrew/formula_creator.rb b/Library/Homebrew/formula_creator.rb index 16e4a6f95c..81f6414dac 100644 --- a/Library/Homebrew/formula_creator.rb +++ b/Library/Homebrew/formula_creator.rb @@ -79,7 +79,7 @@ module Homebrew @desc = metadata["description"] @homepage = metadata["homepage"] @license = metadata["license"]["spdx_id"] if metadata["license"] - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError # If there was no repository found assume the network connection is at # fault rather than the input URL. nil @@ -153,13 +153,14 @@ module Homebrew def install # ENV.deparallelize # if your formula fails when building in parallel <% if mode == :cmake %> - system "cmake", ".", *std_cmake_args + system "cmake", "-S", ".", "-B", "build", *std_cmake_args + system "cmake", "--build", "build" + system "cmake", "--install", "build" <% elsif mode == :autotools %> # Remove unrecognized options if warned by configure - system "./configure", "--disable-debug", - "--disable-dependency-tracking", - "--disable-silent-rules", - "--prefix=\#{prefix}" + # https://rubydoc.brew.sh/Formula.html#std_configure_args-instance_method + system "./configure", *std_configure_args, "--disable-silent-rules" + system "make", "install" # if this fails, try separate make/make install steps <% elsif mode == :crystal %> system "shards", "build", "--release" bin.install "bin/#{name}" @@ -206,14 +207,9 @@ module Homebrew system "cargo", "install", *std_cargo_args <% else %> # Remove unrecognized options if warned by configure - system "./configure", "--disable-debug", - "--disable-dependency-tracking", - "--disable-silent-rules", - "--prefix=\#{prefix}" - # system "cmake", ".", *std_cmake_args - <% end %> - <% if mode == :autotools || mode == :cmake %> - system "make", "install" # if this fails, try separate make/make install steps + # https://rubydoc.brew.sh/Formula.html#std_configure_args-instance_method + system "./configure", *std_configure_args, "--disable-silent-rules" + # system "cmake", "-S", ".", "-B", "build", *std_cmake_args <% end %> end diff --git a/Library/Homebrew/formula_info.rb b/Library/Homebrew/formula_info.rb index ad8035172b..1059fb5c2a 100644 --- a/Library/Homebrew/formula_info.rb +++ b/Library/Homebrew/formula_info.rb @@ -16,13 +16,11 @@ class FormulaInfo # Returns nil if formula is absent or if there was an error reading it. def self.lookup(name) json = Utils.popen_read( - RUBY_PATH, - ENV["HOMEBREW_RUBY_WARNINGS"], - "-I", $LOAD_PATH.join(File::PATH_SEPARATOR), + *HOMEBREW_RUBY_EXEC_ARGS, HOMEBREW_LIBRARY_PATH/"brew.rb", "info", "--json=v1", - name + name, ) return unless $CHILD_STATUS.success? diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 8c04ac78f3..6526256604 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -94,7 +94,6 @@ class FormulaInstaller @options = options @requirement_messages = [] @poured_bottle = false - @pour_failed = false @start_time = nil end @@ -154,8 +153,6 @@ class FormulaInstaller sig { params(output_warning: T::Boolean).returns(T::Boolean) } def pour_bottle?(output_warning: false) - return false if @pour_failed - return false if !formula.bottle_tag? && !formula.local_bottle_path return true if force_bottle? return false if build_from_source? || build_bottle? || interactive? @@ -230,13 +227,12 @@ class FormulaInstaller raise CannotInstallFormulaError, "--force-bottle passed but #{formula.full_name} has no bottle!" end - if Homebrew.default_prefix? && !Homebrew::EnvConfig.developer? && + if Homebrew.default_prefix? && # TODO: re-enable this on Linux when we merge linuxbrew-core into # homebrew-core and have full bottle coverage. (OS.mac? || ENV["CI"]) && - !build_from_source? && !build_bottle? && - !installed_as_dependency? && - formula.tap&.core_tap? && !formula.bottle_unneeded? && !formula.any_version_installed? && + !build_from_source? && !build_bottle? && !formula.head? && + formula.tap&.core_tap? && !formula.bottle_unneeded? && # Integration tests override homebrew-core locations ENV["HOMEBREW_TEST_TMPDIR"].nil? && !pour_bottle? @@ -244,21 +240,31 @@ class FormulaInstaller formula_message = formula.pour_bottle_check_unsatisfied_reason formula_message[0] = formula_message[0].downcase - "#{formula}: #{formula_message}" - else + <<~EOS + #{formula}: #{formula_message} + EOS + # don't want to complain about no bottle available if doing an + # upgrade/reinstall/dependency install (but do in the case the bottle + # check fails) + elsif !Homebrew::EnvConfig.developer? && + (!installed_as_dependency? || !formula.any_version_installed?) && + (!OS.mac? || !OS::Mac.outdated_release?) <<~EOS #{formula}: no bottle available! EOS end - message += <<~EOS - You can try to install from source with: - brew install --build-from-source #{formula} - Please note building from source is unsupported. You will encounter build - failures with some formulae. If you experience any issues please create pull - requests instead of asking for help on Homebrew's GitHub, Twitter or any other - official channels. - EOS - raise CannotInstallFormulaError, message + + if message + message += <<~EOS + You can try to install from source with: + brew install --build-from-source #{formula} + Please note building from source is unsupported. You will encounter build + failures with some formulae. If you experience any issues please create pull + requests instead of asking for help on Homebrew's GitHub, Twitter or any other + official channels. + EOS + raise CannotInstallFormulaError, message + end end type, reason = DeprecateDisable.deprecate_disable_info formula @@ -282,49 +288,51 @@ class FormulaInstaller return if ignore_deps? - recursive_deps = formula.recursive_dependencies - recursive_formulae = recursive_deps.map(&:to_formula) + if Homebrew::EnvConfig.developer? + # `recursive_dependencies` trims cyclic dependencies, so we do one level and take the recursive deps of that. + # Mapping direct dependencies to deeper dependencies in a hash is also useful for the cyclic output below. + recursive_dep_map = formula.deps.to_h { |dep| [dep, dep.to_formula.recursive_dependencies] } - recursive_dependencies = [] - invalid_arch_dependencies = [] - recursive_formulae.each do |dep| - dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s) - if dep_recursive_dependencies.include?(formula.name) - recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}" - recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}" + cyclic_dependencies = [] + recursive_dep_map.each do |dep, recursive_deps| + if [formula.name, formula.full_name].include?(dep.name) + cyclic_dependencies << "#{formula.full_name} depends on itself directly" + elsif recursive_deps.any? { |rdep| [formula.name, formula.full_name].include?(rdep.name) } + cyclic_dependencies << "#{formula.full_name} depends on itself via #{dep.name}" + end end - if (tab = Tab.for_formula(dep)) && tab.arch.present? && tab.arch.to_s != Hardware::CPU.arch.to_s + if cyclic_dependencies.present? + raise CannotInstallFormulaError, <<~EOS + #{formula.full_name} contains a recursive dependency on itself: + #{cyclic_dependencies.join("\n ")} + EOS + end + + # Merge into one list + recursive_deps = recursive_dep_map.flat_map { |dep, rdeps| [dep] + rdeps } + Dependency.merge_repeats(recursive_deps) + else + recursive_deps = formula.recursive_dependencies + end + + invalid_arch_dependencies = [] + pinned_unsatisfied_deps = [] + recursive_deps.each do |dep| + if (tab = Tab.for_formula(dep.to_formula)) && tab.arch.present? && tab.arch.to_s != Hardware::CPU.arch.to_s invalid_arch_dependencies << "#{dep} was built for #{tab.arch}" end + + pinned_unsatisfied_deps << dep if dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep)) end - unless recursive_dependencies.empty? - raise CannotInstallFormulaError, <<~EOS - #{formula.full_name} contains a recursive dependency on itself: - #{recursive_dependencies.join("\n ")} - EOS - end - - if recursive_formulae.flat_map(&:recursive_dependencies) - .map(&:to_s) - .include?(formula.name) - raise CannotInstallFormulaError, <<~EOS - #{formula.full_name} contains a recursive dependency on itself! - EOS - end - - unless invalid_arch_dependencies.empty? + if invalid_arch_dependencies.present? raise CannotInstallFormulaError, <<~EOS #{formula.full_name} dependencies not built for the #{Hardware::CPU.arch} CPU architecture: #{invalid_arch_dependencies.join("\n ")} EOS end - pinned_unsatisfied_deps = recursive_deps.select do |dep| - dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep)) - end - return if pinned_unsatisfied_deps.empty? raise CannotInstallFormulaError, @@ -429,7 +437,7 @@ class FormulaInstaller if pour_bottle? begin pour - rescue Exception => e # rubocop:disable Lint/RescueException + rescue Exception # rubocop:disable Lint/RescueException # any exceptions must leave us with nothing installed ignore_interrupts do begin @@ -442,17 +450,7 @@ class FormulaInstaller end formula.rack.rmdir_if_possible end - raise if Homebrew::EnvConfig.developer? || - Homebrew::EnvConfig.no_bottle_source_fallback? || - force_bottle? || - e.is_a?(Interrupt) - - @pour_failed = true - onoe e.message - opoo "Bottle installation failed: building from source." - raise UnbottledError, [formula] unless DevelopmentTools.installed? - - compute_and_install_dependencies unless ignore_deps? + raise else @poured_bottle = true end @@ -513,7 +511,7 @@ class FormulaInstaller $stderr.puts "Please report this issue to the #{formula.tap} tap (not Homebrew/brew or Homebrew/core)!" false - else # rubocop:disable Layout/ElseAlignment + else f.linked_keg.exist? && f.opt_prefix.exist? end @@ -523,9 +521,11 @@ class FormulaInstaller # Compute and collect the dependencies needed by the formula currently # being installed. def compute_dependencies - req_map, req_deps = expand_requirements - check_requirements(req_map) - expand_dependencies(req_deps + formula.deps) + @compute_dependencies ||= begin + req_map, req_deps = expand_requirements + check_requirements(req_map) + expand_dependencies(req_deps + formula.deps) + end end def unbottled_dependencies(deps) @@ -575,7 +575,7 @@ class FormulaInstaller formula_deps_map = Dependency.expand(formula) .index_by(&:name) - while f = formulae.pop + while (f = formulae.pop) runtime_requirements = runtime_requirements(f) f.recursive_requirements do |dependent, req| build = effective_build_options_for(dependent) @@ -707,16 +707,17 @@ class FormulaInstaller quiet: quiet?, verbose: verbose?, ) + fi.prelude fi.fetch end sig { params(dep: Dependency, inherited_options: Options).void } def install_dependency(dep, inherited_options) df = dep.to_formula - tab = Tab.for_formula(df) if df.linked_keg.directory? linked_keg = Keg.new(df.linked_keg.resolved_path) + tab = Tab.for_keg(linked_keg) keg_had_linked_keg = true keg_was_linked = linked_keg.linked? linked_keg.unlink @@ -724,12 +725,13 @@ class FormulaInstaller if df.latest_version_installed? installed_keg = Keg.new(df.prefix) + tab ||= Tab.for_keg(installed_keg) tmp_keg = Pathname.new("#{installed_keg}.tmp") installed_keg.rename(tmp_keg) end - tab_tap = tab.source["tap"] - if tab_tap.present? && df.tap.present? && df.tap.to_s != tab_tap.to_s + if df.tap.present? && tab.present? && (tab_tap = tab.source["tap"].presence) && + df.tap.to_s != tab_tap.to_s odie <<~EOS #{df} is already installed from #{tab_tap}! Please `brew uninstall #{df}` first." @@ -737,7 +739,7 @@ class FormulaInstaller end options = Options.new - options |= tab.used_options + options |= tab.used_options if tab.present? options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options) options |= inherited_options options &= df.options @@ -748,7 +750,7 @@ class FormulaInstaller options: options, link_keg: keg_had_linked_keg ? keg_was_linked : nil, installed_as_dependency: true, - installed_on_request: df.any_version_installed? && tab.installed_on_request, + installed_on_request: df.any_version_installed? && tab.present? && tab.installed_on_request, force_bottle: false, include_test_formulae: @include_test_formulae, build_from_source_formulae: @build_from_source_formulae, @@ -759,7 +761,6 @@ class FormulaInstaller verbose: verbose?, }, ) - fi.prelude oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}" fi.install fi.finish @@ -901,13 +902,12 @@ class FormulaInstaller # 1. formulae can modify ENV, so we must ensure that each # installation has a pristine ENV when it starts, forking now is # the easiest way to do this - args = %W[ - nice #{RUBY_PATH} - #{ENV["HOMEBREW_RUBY_WARNINGS"]} - -I #{$LOAD_PATH.join(File::PATH_SEPARATOR)} - -- - #{HOMEBREW_LIBRARY_PATH}/build.rb - #{formula.specified_path} + args = [ + "nice", + *HOMEBREW_RUBY_EXEC_ARGS, + "--", + HOMEBREW_LIBRARY_PATH/"build.rb", + formula.specified_path, ].concat(build_argv) Utils.safe_fork do @@ -1123,25 +1123,10 @@ class FormulaInstaller return if only_deps? - if pour_bottle?(output_warning: true) - begin - downloader.fetch - rescue Exception => e # rubocop:disable Lint/RescueException - raise if Homebrew::EnvConfig.developer? || - Homebrew::EnvConfig.no_bottle_source_fallback? || - force_bottle? || - e.is_a?(Interrupt) - - @pour_failed = true - onoe e.message - opoo "Bottle installation failed: building from source." - fetch_dependencies - end + unless pour_bottle?(output_warning: true) + formula.fetch_patches + formula.resources.each(&:fetch) end - return if pour_bottle? - - formula.fetch_patches - formula.resources.each(&:fetch) downloader.fetch end @@ -1170,10 +1155,12 @@ class FormulaInstaller tab = Tab.for_keg(keg) - CxxStdlib.check_compatibility( - formula, formula.recursive_dependencies, - Keg.new(formula.prefix), tab.compiler - ) + unless ignore_deps? + CxxStdlib.check_compatibility( + formula, formula.recursive_dependencies, + Keg.new(formula.prefix), tab.compiler + ) + end tab.tap = formula.tap tab.poured_from_bottle = true @@ -1253,10 +1240,9 @@ class FormulaInstaller end return if forbidden_licenses.blank? + return if ignore_deps? compute_dependencies.each do |dep, _| - next if @ignore_deps - dep_f = dep.to_formula next unless SPDX.licenses_forbid_installation? dep_f.license, forbidden_licenses @@ -1265,7 +1251,8 @@ class FormulaInstaller #{SPDX.license_expression_to_string dep_f.license}. EOS end - return if @only_deps + + return if only_deps? return unless SPDX.licenses_forbid_installation? formula.license, forbidden_licenses diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 52f18dbef7..52734a8d0c 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -33,6 +33,19 @@ module Formulary cache.fetch(path) end + def self.clear_cache + cache.each do |key, klass| + next if key == :formulary_factory + + namespace = klass.name.deconstantize + next if namespace.deconstantize != name + + remove_const(namespace.demodulize) + end + + super + end + def self.load_formula(name, path, contents, namespace, flags:) raise "Formula loading disabled by HOMEBREW_DISABLE_LOAD_FORMULA!" if Homebrew::EnvConfig.disable_load_formula? @@ -47,6 +60,7 @@ module Formulary mod.const_set(:BUILD_FLAGS, flags) mod.module_eval(contents, path) rescue NameError, ArgumentError, ScriptError, MethodDeprecatedError => e + remove_const(namespace) raise FormulaUnreadableError.new(name, e) end class_name = class_s(name) @@ -58,6 +72,7 @@ module Formulary .map { |const_name| mod.const_get(const_name) } .select { |const| const.is_a?(Class) } new_exception = FormulaClassUnavailableError.new(name, path, class_name, class_list) + remove_const(namespace) raise new_exception, "", e.backtrace end end @@ -467,14 +482,14 @@ module Formulary return FormulaLoader.new(name, path) end - if newref = CoreTap.instance.formula_renames[ref] + if (newref = CoreTap.instance.formula_renames[ref]) formula_with_that_oldname = core_path(newref) return FormulaLoader.new(newref, formula_with_that_oldname) if formula_with_that_oldname.file? end possible_tap_newname_formulae = [] Tap.each do |tap| - if newref = tap.formula_renames[ref] + if (newref = tap.formula_renames[ref]) possible_tap_newname_formulae << "#{tap.name}/#{newref}" end end @@ -502,11 +517,11 @@ module Formulary name = name.to_s.downcase taps.map do |tap| Pathname.glob([ - "#{tap}Formula/#{name}.rb", - "#{tap}HomebrewFormula/#{name}.rb", - "#{tap}#{name}.rb", - "#{tap}Aliases/#{name}", - ]).find(&:file?) + "#{tap}Formula/#{name}.rb", + "#{tap}HomebrewFormula/#{name}.rb", + "#{tap}#{name}.rb", + "#{tap}Aliases/#{name}", + ]).find(&:file?) end.compact end end diff --git a/Library/Homebrew/github_packages.rb b/Library/Homebrew/github_packages.rb new file mode 100644 index 0000000000..ff54e49282 --- /dev/null +++ b/Library/Homebrew/github_packages.rb @@ -0,0 +1,185 @@ +# typed: false +# frozen_string_literal: true + +require "utils/curl" +require "json" + +# GitHub Packages client. +# +# @api private +class GitHubPackages + extend T::Sig + + include Context + include Utils::Curl + + URL_DOMAIN = "ghcr.io" + URL_PREFIX = "https://#{URL_DOMAIN}/v2/" + URL_REGEX = %r{#{Regexp.escape(URL_PREFIX)}([\w-]+)/([\w-]+)}.freeze + + sig { returns(String) } + def inspect + "#" + end + + sig { params(org: T.nilable(String)).void } + def initialize(org: "homebrew") + @github_org = org + + raise UsageError, "Must set a GitHub organisation!" unless @github_org + + ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"] = "1" if @github_org == "homebrew" && !OS.mac? + end + + sig { params(bottles_hash: T::Hash[String, T.untyped]).void } + def upload_bottles(bottles_hash) + user = Homebrew::EnvConfig.github_packages_user + token = Homebrew::EnvConfig.github_packages_token + + raise UsageError, "HOMEBREW_GITHUB_PACKAGES_USER is unset." if user.blank? + raise UsageError, "HOMEBREW_GITHUB_PACKAGES_TOKEN is unset." if token.blank? + + docker = HOMEBREW_PREFIX/"bin/docker" + unless docker.exist? + ohai "Installing `docker` for upload..." + safe_system HOMEBREW_BREW_FILE, "install", "--formula", "docker" + docker = Formula["docker"].opt_bin/"docker" + end + + puts + system_command!(docker, verbose: true, print_stdout: true, input: token, args: [ + "login", "--username", user, "--password-stdin", URL_DOMAIN + ]) + + oras = HOMEBREW_PREFIX/"bin/oras" + unless oras.exist? + ohai "Installing `oras` for upload..." + safe_system HOMEBREW_BREW_FILE, "install", "oras" + oras = Formula["oras"].opt_bin/"oras" + end + + bottles_hash.each do |formula_name, bottle_hash| + _, org, repo, = *bottle_hash["bottle"]["root_url"].match(URL_REGEX) + + # docker CLI insists on lowercase org ("repository name") + org = org.downcase + image = "#{URL_DOMAIN}/#{org}/#{repo}/#{formula_name}" + + version = bottle_hash["formula"]["pkg_version"] + rebuild = if (rebuild = bottle_hash["bottle"]["rebuild"]).positive? + ".#{rebuild}" + end + + formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"] + formula = Formulary.factory(formula_path) + + image_tags = bottle_hash["bottle"]["tags"].map do |bottle_tag, tag_hash| + local_file = tag_hash["local_filename"] + odebug "Uploading #{local_file}" + + tag = "#{version}.#{bottle_tag}#{rebuild}" + + tab = Tab.from_file_content( + Utils.safe_popen_read("tar", "xfO", local_file, "#{formula_name}/#{version}/INSTALL_RECEIPT.json"), + "#{local_file}/#{formula_name}/#{version}", + ) + created_time = tab.source_modified_time + created_time ||= Time.now + + # TODO: ideally most/all of these attributes would be stored in the + # bottle JSON rather than reading them from the formula. + git_revision = formula.tap.git_head + git_path = formula_path.to_s.delete_prefix("#{formula.tap.path}/") + manifest_hash = { + "org.opencontainers.image.title" => formula.full_name, + "org.opencontainers.image.url" => formula.homepage, + "org.opencontainers.image.version" => version, + "org.opencontainers.image.revision" => git_revision, + "org.opencontainers.image.source" => "https://github.com/#{org}/#{repo}/blob/#{git_revision}/#{git_path}", + "org.opencontainers.image.created" => created_time.strftime("%F"), + } + manifest_hash["org.opencontainers.image.description"] = formula.desc if formula.desc.present? + manifest_hash["org.opencontainers.image.license"] = formula.license if formula.license.present? + + manifest_annotations = Pathname("#{formula_name}.#{tag}.annotations.json") + manifest_annotations.unlink if manifest_annotations.exist? + manifest_annotations.write({ "$manifest" => manifest_hash }.to_json) + + os_version = if tab.built_on.present? + /(\d+\.)*\d+/ =~ tab.built_on["os_version"] + Regexp.last_match(0) + end + + # TODO: ideally most/all of these attributes would be stored in the + # bottle JSON rather than reading them from the formula. + os, arch = if @bottle_tag.to_s.end_with?("_linux") + ["linux", "amd64"] + else + os = "darwin" + macos_version = MacOS::Version.from_symbol(bottle_tag.to_sym) + os_version ||= macos_version.to_f.to_s + arch = if macos_version.arch == :arm64 + "arm64" + else + "amd64" + end + [os, arch] + end + + tar_sha256 = Digest::SHA256.hexdigest( + Utils.safe_popen_read("gunzip", "--stdout", "--decompress", local_file), + ) + + config_hash = { + "architecture" => arch, + "os" => os, + "os.version" => os_version, + "rootfs" => { + "type" => "layers", + "diff_ids" => ["sha256:#{tar_sha256}"], + }, + } + + manifest_config = Pathname("#{formula_name}.#{tag}.config.json") + manifest_config.unlink if manifest_config.exist? + manifest_config.write(config_hash.to_json) + + # TODO: If we push the architecture-specific images to the tag :latest, + # then we don't need to delete the architecture-specific tags. + image_tag = "#{image}:#{tag}" + puts + system_command!(oras, verbose: true, print_stdout: true, args: [ + "push", image_tag, + "--verbose", + "--manifest-annotations=#{manifest_annotations}", + "--manifest-config=#{manifest_config}:application/vnd.oci.image.config.v1+json", + "--username", user, + "--password", token, + "#{local_file}:application/vnd.oci.image.layer.v1.tar+gzip" + ]) + + image_tag + end + + image_tag = "#{image}:#{version}#{rebuild}" + puts + system_command!(docker, verbose: true, print_stdout: true, args: [ + "buildx", "imagetools", "create", "--tag", image_tag, *image_tags + ]) + + # TODO: once the main image metadata is working correctly delete the package using: + # `curl -X DELETE -u $HOMEBREW_GITHUB_PACKAGES_USER:$HOMEBREW_GITHUB_PACKAGES_TOKEN + # https://api.github.com/orgs/Homebrew/packages/container/homebrew-core%2F$PACKAGE/versions/$VERSION` + # Alternatively, if we push the architecture-specific images to the tag :latest, + # then we don't need to delete the architecture-specific tags. + # Alternatively, remove all usage of `docker` here instead. + end + ensure + if docker + puts + system_command!(docker, verbose: true, print_stdout: true, args: [ + "logout", URL_DOMAIN + ]) + end + end +end diff --git a/Library/Homebrew/github_releases.rb b/Library/Homebrew/github_releases.rb new file mode 100644 index 0000000000..ae97fba4cb --- /dev/null +++ b/Library/Homebrew/github_releases.rb @@ -0,0 +1,44 @@ +# typed: false +# frozen_string_literal: true + +require "utils/github" +require "json" + +# GitHub Releases client. +# +# @api private +class GitHubReleases + extend T::Sig + + include Context + include Utils::Curl + + URL_REGEX = %r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze + + sig { params(bottles_hash: T::Hash[String, T.untyped]).void } + def upload_bottles(bottles_hash) + bottles_hash.each_value do |bottle_hash| + root_url = bottle_hash["bottle"]["root_url"] + url_match = root_url.match URL_REGEX + _, user, repo, tag = *url_match + + # Ensure a release is created. + release = begin + rel = GitHub.get_release user, repo, tag + odebug "Existing GitHub release \"#{tag}\" found" + rel + rescue GitHub::API::HTTPNotFoundError + odebug "Creating new GitHub release \"#{tag}\"" + GitHub.create_or_update_release user, repo, tag + end + + # Upload bottles as release assets. + bottle_hash["bottle"]["tags"].each_value do |tag_hash| + remote_file = tag_hash["filename"] + local_file = tag_hash["local_filename"] + odebug "Uploading #{remote_file}" + GitHub.upload_release_asset user, repo, release["id"], local_file: local_file, remote_file: remote_file + end + end + end +end diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index 6f738cd419..567b0d6f13 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -16,7 +16,6 @@ require "rbconfig" RUBY_PATH = Pathname.new(RbConfig.ruby).freeze RUBY_BIN = RUBY_PATH.dirname.freeze -require "rubygems" # Only require "core_ext" here to ensure we're only requiring the minimum of # what we need. require "active_support/core_ext/object/blank" @@ -72,8 +71,6 @@ HOMEBREW_PULL_API_REGEX = %r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze HOMEBREW_PULL_OR_COMMIT_URL_REGEX = %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze -HOMEBREW_RELEASES_URL_REGEX = - %r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze require "fileutils" diff --git a/Library/Homebrew/homebrew_bootsnap.rb b/Library/Homebrew/homebrew_bootsnap.rb index 398018bb01..f115b62875 100644 --- a/Library/Homebrew/homebrew_bootsnap.rb +++ b/Library/Homebrew/homebrew_bootsnap.rb @@ -1,22 +1,27 @@ # typed: false # frozen_string_literal: true -if !ENV["HOMEBREW_NO_BOOTSNAP"] && - ENV["HOMEBREW_BOOTSNAP"] && - # portable ruby doesn't play nice with bootsnap - !ENV["HOMEBREW_FORCE_VENDOR_RUBY"] && - (!ENV["HOMEBREW_MACOS_VERSION"] || ENV["HOMEBREW_MACOS_SYSTEM_RUBY_NEW_ENOUGH"]) && - # Apple Silicon doesn't play nice with bootsnap - (ENV["HOMEBREW_PROCESSOR"] == "Intel") +homebrew_bootsnap_enabled = !ENV["HOMEBREW_NO_BOOTSNAP"] && ENV["HOMEBREW_BOOTSNAP"] - require "rubygems" +# portable ruby doesn't play nice with bootsnap +# Can't use .exclude? here because we haven't required active_support yet. +homebrew_bootsnap_enabled &&= !ENV["HOMEBREW_RUBY_PATH"].to_s.include?("/vendor/portable-ruby/") # rubocop:disable Rails/NegateInclude +homebrew_bootsnap_enabled &&= if ENV["HOMEBREW_MACOS_VERSION"] + # Apple Silicon doesn't play nice with bootsnap + ENV["HOMEBREW_PROCESSOR"] == "Intel" && + # we need some development tools to build bootsnap native code + (File.directory?("/Applications/Xcode.app") || File.directory?("/Library/Developer/CommandLineTools")) +else + File.executable?("/usr/bin/clang") || File.executable?("/usr/bin/gcc") +end + +if homebrew_bootsnap_enabled begin require "bootsnap" rescue LoadError unless ENV["HOMEBREW_BOOTSNAP_RETRY"] - require "utils/gems" - Homebrew.install_bundler_gems! + Homebrew.install_bundler_gems!(only_warn_on_failure: true) ENV["HOMEBREW_BOOTSNAP_RETRY"] = "1" exec ENV["HOMEBREW_BREW_FILE"], *ARGV diff --git a/Library/Homebrew/installed_dependents.rb b/Library/Homebrew/installed_dependents.rb new file mode 100644 index 0000000000..20a7440e7d --- /dev/null +++ b/Library/Homebrew/installed_dependents.rb @@ -0,0 +1,74 @@ +# typed: false +# frozen_string_literal: true + +require "cask_dependent" + +# Helper functions for installed dependents. +# +# @api private +module InstalledDependents + extend T::Sig + + module_function + + # Given an array of kegs, this method will try to find some other kegs + # or casks that depend on them. If it does, it returns: + # + # - some kegs in the passed array that have installed dependents + # - some installed dependents of those kegs. + # + # If it doesn't, it returns nil. + # + # Note that nil will be returned if the only installed dependents of the + # passed kegs are other kegs in the array or casks present in the casks + # parameter. + # + # For efficiency, we don't bother trying to get complete data. + def find_some_installed_dependents(kegs, casks: []) + keg_names = kegs.select(&:optlinked?).map(&:name) + keg_formulae = [] + kegs_by_source = kegs.group_by do |keg| + # First, attempt to resolve the keg to a formula + # to get up-to-date name and tap information. + f = keg.to_formula + keg_formulae << f + [f.name, f.tap] + rescue + # If the formula for the keg can't be found, + # fall back to the information in the tab. + [keg.name, keg.tab.tap] + end + + all_required_kegs = Set.new + all_dependents = [] + + # Don't include dependencies of kegs that were in the given array. + dependents_to_check = (Formula.installed - keg_formulae) + (Cask::Caskroom.casks - casks) + + dependents_to_check.each do |dependent| + required = case dependent + when Formula + dependent.missing_dependencies(hide: keg_names) + when Cask::Cask + CaskDependent.new(dependent).runtime_dependencies.map(&:to_formula) + end + + required_kegs = required.map do |f| + f_kegs = kegs_by_source[[f.name, f.tap]] + next unless f_kegs + + f_kegs.max_by(&:version) + end.compact + + next if required_kegs.empty? + + all_required_kegs += required_kegs + all_dependents << dependent.to_s + end + + return if all_required_kegs.empty? + return if all_dependents.empty? + + [all_required_kegs.to_a, all_dependents.sort] + end +end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 8b7089bb57..c5bad0889b 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -136,60 +136,6 @@ class Keg PYC_EXTENSIONS = %w[.pyc .pyo].freeze LIBTOOL_EXTENSIONS = %w[.la .lai].freeze - # Given an array of kegs, this method will try to find some other kegs - # that depend on them. If it does, it returns: - # - # - some kegs in the passed array that have installed dependents - # - some installed dependents of those kegs. - # - # If it doesn't, it returns nil. - # - # Note that nil will be returned if the only installed dependents - # in the passed kegs are other kegs in the array. - # - # For efficiency, we don't bother trying to get complete data. - def self.find_some_installed_dependents(kegs) - keg_names = kegs.select(&:optlinked?).map(&:name) - keg_formulae = [] - kegs_by_source = kegs.group_by do |keg| - # First, attempt to resolve the keg to a formula - # to get up-to-date name and tap information. - f = keg.to_formula - keg_formulae << f - [f.name, f.tap] - rescue - # If the formula for the keg can't be found, - # fall back to the information in the tab. - [keg.name, keg.tab.tap] - end - - all_required_kegs = Set.new - all_dependents = [] - - # Don't include dependencies of kegs that were in the given array. - formulae_to_check = Formula.installed - keg_formulae - - formulae_to_check.each do |dependent| - required = dependent.missing_dependencies(hide: keg_names) - required_kegs = required.map do |f| - f_kegs = kegs_by_source[[f.name, f.tap]] - next unless f_kegs - - f_kegs.max_by(&:version) - end.compact - - next if required_kegs.empty? - - all_required_kegs += required_kegs - all_dependents << dependent.to_s - end - - return if all_required_kegs.empty? - return if all_dependents.empty? - - [all_required_kegs.to_a, all_dependents.sort] - end - # @param path if this is a file in a keg, returns the containing {Keg} object. def self.for(path) original_path = path diff --git a/Library/Homebrew/language/node.rb b/Library/Homebrew/language/node.rb index d59d433295..524e5c3e16 100644 --- a/Library/Homebrew/language/node.rb +++ b/Library/Homebrew/language/node.rb @@ -30,7 +30,7 @@ module Language prepack_removed = pkg_json["scripts"]&.delete("prepack") package.atomic_write(JSON.pretty_generate(pkg_json)) if prepare_removed || prepack_removed end - output = Utils.popen_read("npm pack --ignore-scripts") + output = Utils.popen_read("npm", "pack", "--ignore-scripts") raise "npm failed to pack #{Dir.pwd}" if !$CHILD_STATUS.exitstatus.zero? || output.lines.empty? output.lines.last.chomp diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 9e12305926..7ba9fbd731 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -256,8 +256,6 @@ module Language targets = Array(targets) targets.each do |t| if t.respond_to? :stage - next if t.name.start_with? "homebrew-" - t.stage { do_install Pathname.pwd } else t = t.lines.map(&:strip) if t.respond_to?(:lines) && t.include?("\n") @@ -287,7 +285,7 @@ module Language targets = Array(targets) @formula.system @venv_root/"bin/pip", "install", "-v", "--no-deps", "--no-binary", ":all:", - "--no-user", "--ignore-installed", *targets + "--ignore-installed", *targets end end end diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4ff07d864b..92097bb711 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -63,7 +63,7 @@ module Homebrew # Uses `formulae_and_casks_to_check` to identify taps in use other than # homebrew/core and homebrew/cask and loads strategies from them. - sig { params(formulae_and_casks_to_check: T::Enumerable[T.any(Formula, Cask::Cask)]).void } + sig { params(formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)]).void } def load_other_tap_strategies(formulae_and_casks_to_check) other_taps = {} formulae_and_casks_to_check.each do |formula_or_cask| @@ -86,8 +86,9 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Enumerable[T.any(Formula, Cask::Cask)], + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], full_name: T::Boolean, + handle_name_conflict: T::Boolean, json: T::Boolean, newer_only: T::Boolean, debug: T::Boolean, @@ -97,10 +98,29 @@ module Homebrew } def run_checks( formulae_and_casks_to_check, - full_name: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false + full_name: false, handle_name_conflict: false, json: false, newer_only: false, + debug: false, quiet: false, verbose: false ) load_other_tap_strategies(formulae_and_casks_to_check) + ambiguous_casks = [] + if handle_name_conflict + ambiguous_casks = formulae_and_casks_to_check.group_by { |item| formula_or_cask_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } + end + + ambiguous_names = [] + unless full_name + ambiguous_names = + (formulae_and_casks_to_check - ambiguous_casks).group_by { |item| formula_or_cask_name(item) } + .values + .select { |items| items.length > 1 } + .flatten + end + has_a_newer_upstream_version = T.let(false, T::Boolean) if json && !quiet && $stderr.tty? @@ -122,7 +142,9 @@ module Homebrew formulae_checked = formulae_and_casks_to_check.map.with_index do |formula_or_cask, i| formula = formula_or_cask if formula_or_cask.is_a?(Formula) cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) - name = formula_or_cask_name(formula_or_cask, full_name: full_name) + + use_full_name = full_name || ambiguous_names.include?(formula_or_cask) + name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) if debug && i.positive? puts <<~EOS @@ -130,9 +152,11 @@ module Homebrew ---------- EOS + elsif debug + puts end - skip_info = SkipConditions.skip_information(formula_or_cask, full_name: full_name, verbose: verbose) + skip_info = SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) if skip_info.present? next skip_info if json @@ -164,7 +188,7 @@ module Homebrew else version_info = latest_version( formula_or_cask, - json: json, full_name: full_name, verbose: verbose, debug: debug, + json: json, full_name: use_full_name, verbose: verbose, debug: debug, ) version_info[:latest] if version_info.present? end @@ -175,7 +199,7 @@ module Homebrew next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages] - next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: full_name, verbose: verbose) + next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose) end if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/) @@ -220,15 +244,19 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) nil rescue => e Homebrew.failed = true + use_full_name = full_name || ambiguous_names.include?(formula_or_cask) if json progress&.increment - status_hash(formula_or_cask, "error", [e.to_s], full_name: full_name, verbose: verbose) + status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, verbose: verbose) elsif !quiet + name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name += " (cask)" if ambiguous_casks.include?(formula_or_cask) + onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) nil @@ -306,9 +334,10 @@ module Homebrew end # Formats and prints the livecheck result for a formula. - sig { params(info: Hash, verbose: T::Boolean).void } - def print_latest_version(info, verbose:) + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } + def print_latest_version(info, verbose:, ambiguous_cask: false) formula_or_cask_s = "#{Tty.blue}#{info[:formula] || info[:cask]}#{Tty.reset}" + formula_or_cask_s += " (cask)" if ambiguous_cask formula_or_cask_s += " (guessed)" if !info[:meta][:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] @@ -438,7 +467,6 @@ module Homebrew urls ||= checkable_urls(formula_or_cask) if debug - puts if formula puts "Formula: #{formula_name(formula, full_name: full_name)}" puts "Head only?: true" if formula.head_only? diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index 2fc284f3eb..cf2c7b6a12 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -25,7 +25,7 @@ module Homebrew def formula_or_cask_skip(formula_or_cask, livecheckable, full_name: false, verbose: false) formula = formula_or_cask if formula_or_cask.is_a?(Formula) - if stable_url = formula&.stable&.url + if (stable_url = formula&.stable&.url) stable_is_gist = stable_url.match?(%r{https?://gist\.github(?:usercontent)?\.com/}i) stable_from_google_code_archive = stable_url.match?( %r{https?://storage\.googleapis\.com/google-code-archive-downloads/}i, diff --git a/Library/Homebrew/livecheck/strategy/sparkle.rb b/Library/Homebrew/livecheck/strategy/sparkle.rb index 97dbbcd2c8..eaa3660637 100644 --- a/Library/Homebrew/livecheck/strategy/sparkle.rb +++ b/Library/Homebrew/livecheck/strategy/sparkle.rb @@ -61,7 +61,7 @@ module Homebrew title = (item > "title").first&.text&.strip - if match = title&.match(/(\d+(?:\.\d+)*)\s*(\([^)]+\))?\Z/) + if (match = title&.match(/(\d+(?:\.\d+)*)\s*(\([^)]+\))?\Z/)) short_version ||= match[1] version ||= match[2] end diff --git a/Library/Homebrew/load_path.rb b/Library/Homebrew/load_path.rb index 10aa74784c..a5c65fb680 100644 --- a/Library/Homebrew/load_path.rb +++ b/Library/Homebrew/load_path.rb @@ -5,12 +5,21 @@ require "pathname" HOMEBREW_LIBRARY_PATH = Pathname(__dir__).realpath.freeze -$LOAD_PATH.push HOMEBREW_LIBRARY_PATH.to_s +require_relative "utils/gems" +Homebrew.setup_gem_environment!(setup_path: false) -require "vendor/bundle/bundler/setup" -require "homebrew_bootsnap" +$LOAD_PATH.push HOMEBREW_LIBRARY_PATH.to_s unless $LOAD_PATH.include?(HOMEBREW_LIBRARY_PATH.to_s) +require_relative "vendor/bundle/bundler/setup" +$LOAD_PATH.uniq! -unless defined?(Bootsnap) - $LOAD_PATH.select! { |d| Pathname(d).directory? } - $LOAD_PATH.uniq! +# Block any gem loading by bypassing rubygem's `require`. +# Helps make sure we don't accidentally use things not in bundler's load path. +# Bundler 2.2.7+ and non-standalone mode both do this automatically. +# https://github.com/rubygems/rubygems/blob/5841761974bef324a33ef1cb650bbf8a2457805b/bundler/lib/bundler/installer/standalone.rb#L55-L63 +if Kernel.private_method_defined?(:gem_original_require) + Kernel.send(:remove_method, :require) + Kernel.send(:define_method, :require, Kernel.instance_method(:gem_original_require)) + Kernel.send(:private, :require) end + +require_relative "homebrew_bootsnap" diff --git a/Library/Homebrew/locale.rb b/Library/Homebrew/locale.rb index fcfa56f80f..eefbc464f8 100644 --- a/Library/Homebrew/locale.rb +++ b/Library/Homebrew/locale.rb @@ -29,7 +29,7 @@ class Locale private_constant :LOCALE_REGEX def self.parse(string) - if locale = try_parse(string) + if (locale = try_parse(string)) return locale end @@ -42,12 +42,12 @@ class Locale scanner = StringScanner.new(string) - if language = scanner.scan(LANGUAGE_REGEX) + if (language = scanner.scan(LANGUAGE_REGEX)) sep = scanner.scan(/-/) return if (sep && scanner.eos?) || (sep.nil? && !scanner.eos?) end - if region = scanner.scan(REGION_REGEX) + if (region = scanner.scan(REGION_REGEX)) sep = scanner.scan(/-/) return if (sep && scanner.eos?) || (sep.nil? && !scanner.eos?) end diff --git a/Library/Homebrew/metafiles.rb b/Library/Homebrew/metafiles.rb index 2e4034706d..e7e71963df 100644 --- a/Library/Homebrew/metafiles.rb +++ b/Library/Homebrew/metafiles.rb @@ -8,9 +8,9 @@ module Metafiles LICENSES = Set.new(%w[copying copyright license licence]).freeze # {https://github.com/github/markup#markups} EXTENSIONS = Set.new(%w[ - .adoc .asc .asciidoc .creole .html .markdown .md .mdown .mediawiki .mkdn - .org .pod .rdoc .rst .rtf .textile .txt .wiki - ]).freeze + .adoc .asc .asciidoc .creole .html .markdown .md .mdown .mediawiki .mkdn + .org .pod .rdoc .rst .rtf .textile .txt .wiki + ]).freeze BASENAMES = Set.new(%w[about authors changelog changes history news notes notice readme todo]).freeze module_function diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 67bff176ad..53d7742ede 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -138,7 +138,7 @@ class Migrator @new_cellar = HOMEBREW_CELLAR/formula.name @new_cellar_existed = @new_cellar.exist? - if @old_linked_keg = linked_old_linked_keg + if (@old_linked_keg = linked_old_linked_keg) @old_linked_keg_record = old_linked_keg.linked_keg_record if old_linked_keg.linked? @old_opt_record = old_linked_keg.opt_record if old_linked_keg.optlinked? @new_linked_keg_record = HOMEBREW_CELLAR/"#{newname}/#{File.basename(old_linked_keg)}" @@ -165,7 +165,7 @@ class Migrator new_tap = if old_tap old_tap_user, = old_tap.user - if migrate_tap = old_tap.tap_migrations[formula.oldname] + if (migrate_tap = old_tap.tap_migrations[formula.oldname]) new_tap_user, new_tap_repo = migrate_tap.split("/") "#{new_tap_user}/#{new_tap_repo}" end diff --git a/Library/Homebrew/os/linux.rb b/Library/Homebrew/os/linux.rb index 5436d6f00a..25a1291d07 100644 --- a/Library/Homebrew/os/linux.rb +++ b/Library/Homebrew/os/linux.rb @@ -11,7 +11,7 @@ module OS sig { returns(String) } def os_version if which("lsb_release") - lsb_info = Utils.popen_read("lsb_release -a") + lsb_info = Utils.popen_read("lsb_release", "-a") description = lsb_info[/^Description:\s*(.*)$/, 1] codename = lsb_info[/^Codename:\s*(.*)$/, 1] if codename.blank? || (codename == "n/a") diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index 0a95677a3b..d6253593bc 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -25,7 +25,7 @@ module OS # This can be compared to numerics, strings, or symbols # using the standard Ruby Comparable methods. def version - @version ||= Version.from_symbol(full_version.to_sym) + @version ||= full_version.strip_patch end # This can be compared to numerics, strings, or symbols diff --git a/Library/Homebrew/os/mac/keg.rb b/Library/Homebrew/os/mac/keg.rb index 2e2e24dccc..901c4dc7ee 100644 --- a/Library/Homebrew/os/mac/keg.rb +++ b/Library/Homebrew/os/mac/keg.rb @@ -57,13 +57,17 @@ class Keg # Try signing again odebug "Codesigning (2nd try) #{file}" - return if quiet_system("codesign", "--sign", "-", "--force", - "--preserve-metadata=entitlements,requirements,flags,runtime", - file) + result = system_command("codesign", args: [ + "--sign", "-", "--force", + "--preserve-metadata=entitlements,requirements,flags,runtime", + file + ], print_stderr: false) + return if result.success? # If it fails again, error out onoe <<~EOS - Failed applying an ad-hoc signature to #{file} + Failed applying an ad-hoc signature to #{file}: + #{result.stderr} EOS end end diff --git a/Library/Homebrew/os/mac/sdk.rb b/Library/Homebrew/os/mac/sdk.rb index 4b6f893efb..f39d9e527d 100644 --- a/Library/Homebrew/os/mac/sdk.rb +++ b/Library/Homebrew/os/mac/sdk.rb @@ -9,6 +9,8 @@ module OS # # @api private class SDK + VERSIONED_SDK_REGEX = /MacOSX(\d+\.\d+)\.sdk$/.freeze + attr_reader :version, :path, :source def initialize(version, path, source) @@ -25,14 +27,39 @@ module OS class NoSDKError < StandardError; end def sdk_for(v) - path = sdk_paths[v] - raise NoSDKError if path.nil? + sdk = all_sdks.find { |s| s.version == v } + raise NoSDKError if sdk.nil? - SDK.new v, path, source + sdk end def all_sdks - sdk_paths.map { |v, p| SDK.new v, p, source } + return @all_sdks if @all_sdks + + @all_sdks = [] + + # Bail out if there is no SDK prefix at all + return @all_sdks unless File.directory? sdk_prefix + + # Use unversioned SDK path on Big Sur to avoid issues such as: + # https://github.com/Homebrew/homebrew-core/issues/67075 + unversioned_sdk_path = Pathname.new("#{sdk_prefix}/MacOSX.sdk") + version = read_sdk_version(unversioned_sdk_path) + if version && version >= :big_sur + unversioned_sdk_version = version + @all_sdks << SDK.new(unversioned_sdk_version, unversioned_sdk_path, source) + end + + Dir["#{sdk_prefix}/MacOSX*.sdk"].each do |sdk_path| + next unless sdk_path.match?(SDK::VERSIONED_SDK_REGEX) + + version = read_sdk_version(Pathname.new(sdk_path)) + next if version.nil? || version == unversioned_sdk_version + + @all_sdks << SDK.new(version, sdk_path, source) + end + + @all_sdks end def sdk_if_applicable(v = nil) @@ -64,43 +91,34 @@ module OS "" end - def sdk_paths - @sdk_paths ||= begin - # Bail out if there is no SDK prefix at all - if File.directory? sdk_prefix - paths = {} - - Dir[File.join(sdk_prefix, "MacOSX*.sdk")].each do |sdk_path| - version = sdk_path[/MacOSX(\d+\.\d+)u?\.sdk$/, 1] - paths[OS::Mac::Version.new(version)] = sdk_path if version.present? - end - - # Use unversioned SDK path on Big Sur to avoid issues such as: - # https://github.com/Homebrew/homebrew-core/issues/67075 - # This creates an entry in `paths` whose key is the OS major version - sdk_path = Pathname.new("#{sdk_prefix}/MacOSX.sdk") - sdk_settings = sdk_path/"SDKSettings.json" - if sdk_settings.exist? && - (sdk_settings_string = sdk_settings.read.presence) && - (sdk_settings_json = JSON.parse(sdk_settings_string).presence) && - (version_string = sdk_settings_json.fetch("Version", nil).presence) && - (version = version_string[/(\d+)\./, 1].presence) - paths[OS::Mac::Version.new(version)] = sdk_path - end - - paths - else - {} - end - end + def latest_sdk + all_sdks.max_by(&:version) end - # NOTE: This returns a versioned SDK path, even on Big Sur - def latest_sdk - return if sdk_paths.empty? + def read_sdk_version(sdk_path) + sdk_settings = sdk_path/"SDKSettings.json" + sdk_settings_string = sdk_settings.read if sdk_settings.exist? - v, path = sdk_paths.max { |(v1, _), (v2, _)| v1 <=> v2 } - SDK.new v, path, source + # Pre-10.14 SDKs + sdk_settings = sdk_path/"SDKSettings.plist" + if sdk_settings_string.blank? && sdk_settings.exist? + result = system_command("plutil", args: ["-convert", "json", "-o", "-", sdk_settings]) + sdk_settings_string = result.stdout if result.success? + end + + return if sdk_settings_string.blank? + + sdk_settings_json = JSON.parse(sdk_settings_string) + return if sdk_settings_json.blank? + + version_string = sdk_settings_json.fetch("Version", nil) + return if version_string.blank? + + begin + OS::Mac::Version.new(version_string).strip_patch + rescue MacOSVersionError + nil + end end end private_constant :BaseSDKLocator diff --git a/Library/Homebrew/os/mac/version.rb b/Library/Homebrew/os/mac/version.rb index 0244607383..389b3d739d 100644 --- a/Library/Homebrew/os/mac/version.rb +++ b/Library/Homebrew/os/mac/version.rb @@ -78,17 +78,19 @@ module OS end end + sig { returns(T.self_type) } + def strip_patch + # Big Sur is 11.x but Catalina is 10.15.x. + if major >= 11 + self.class.new(major.to_s) + else + major_minor + end + end + sig { returns(Symbol) } def to_sym - @to_sym ||= begin - # Big Sur is 11.x but Catalina is 10.15. - major_macos = if major >= 11 - major - else - major_minor - end.to_s - SYMBOLS.invert.fetch(major_macos, :dunno) - end + @to_sym ||= SYMBOLS.invert.fetch(strip_patch.to_s, :dunno) end sig { returns(String) } diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 9a5f765800..0edc942ae4 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -18,10 +18,10 @@ module OS # Bump these when a new version is available from the App Store and our # CI systems have been updated. # This may be a beta version for a beta macOS. - sig { returns(String) } - def latest_version + sig { params(macos: MacOS::Version).returns(String) } + def latest_version(macos: MacOS.version) latest_stable = "12.4" - case MacOS.version + case macos when "11" then latest_stable when "10.15" then "12.4" when "10.14" then "11.3.1" @@ -134,6 +134,19 @@ module OS sdk(v)&.path end + def installation_instructions + if OS::Mac.prerelease? + <<~EOS + Xcode can be installed from: + #{Formatter.url("https://developer.apple.com/download/more/")} + EOS + else + <<~EOS + Xcode can be installed from the App Store. + EOS + end + end + sig { returns(String) } def update_instructions if OS::Mac.prerelease? @@ -254,6 +267,21 @@ module OS sdk(v)&.path end + def installation_instructions + if MacOS.version == "10.14" + # This is not available from `xcode-select` + <<~EOS + Install the Command Line Tools for Xcode 11.3.1 from: + #{Formatter.url("https://developer.apple.com/download/more/")} + EOS + else + <<~EOS + Install the Command Line Tools: + xcode-select --install + EOS + end + end + sig { returns(String) } def update_instructions software_update_location = if MacOS.version >= "10.14" @@ -320,7 +348,7 @@ module OS end def detect_clang_version - version_output = Utils.popen_read("#{PKG_PATH}/usr/bin/clang --version") + version_output = Utils.popen_read("#{PKG_PATH}/usr/bin/clang", "--version") version_output[/clang-(\d+\.\d+\.\d+(\.\d+)?)/, 1] end diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index cb242aa0c7..01cae78d8e 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -84,7 +84,7 @@ class DATAPatch < EmbeddedPatch line = f.gets break if line.nil? || line =~ /^__END__$/ end - while line = f.gets + while (line = f.gets) data << line end end diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 6856fa07ed..bd836db12a 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -3,7 +3,7 @@ old_trap = trap("INT") { exit! 130 } -require "global" +require_relative "global" require "debrew" require "fcntl" require "socket" diff --git a/Library/Homebrew/prefix.sh b/Library/Homebrew/prefix.sh new file mode 100644 index 0000000000..1bc902b6d9 --- /dev/null +++ b/Library/Homebrew/prefix.sh @@ -0,0 +1,32 @@ +# does the quickest output of brew --prefix possible for the basic cases: +# - `brew --prefix` (output HOMEBREW_PREFIX) +# - `brew --prefix ` (output HOMEBREW_PREFIX/opt/) +# anything else? delegate to the slower cmd/--prefix.rb + +homebrew-prefix() { + while [[ "$#" -gt 0 ]]; do + case $1 in + # check we actually have --prefix and not e.g. --prefixsomething + --prefix) local prefix="1"; shift ;; + # reject all other flags + -*) return 1 ;; + *) [ -n "$formula" ] && return 1; local formula="$1"; shift ;; + esac + done + [ -z "$prefix" ] && return 1 + [ -z "$formula" ] && echo "$HOMEBREW_PREFIX" && return 0 + + local formula_path + if [ -f "$HOMEBREW_REPOSITORY/Library/Taps/homebrew/homebrew-core/Formula/${formula}.rb" ]; then + formula_path="$HOMEBREW_REPOSITORY/Library/Taps/homebrew/homebrew-core/Formula/${formula}.rb" + else + formula_path="$( + shopt -s nullglob + echo "$HOMEBREW_REPOSITORY/Library/Taps"/*/*/{Formula/,HomebrewFormula/,}"${formula}.rb" + )" + fi + [ -z "$formula_path" ] && return 1 + + echo "$HOMEBREW_PREFIX/opt/$formula" + return 0 +} diff --git a/Library/Homebrew/requirements/x11_requirement.rb b/Library/Homebrew/requirements/x11_requirement.rb index f33946f3ec..64c1057650 100644 --- a/Library/Homebrew/requirements/x11_requirement.rb +++ b/Library/Homebrew/requirements/x11_requirement.rb @@ -31,12 +31,12 @@ class X11Requirement < Requirement end satisfy build_env: false do - if which_xorg = which("Xorg") + if (which_xorg = which("Xorg")) version = Utils.popen_read(which_xorg, "-version", err: :out)[/X Server (\d+\.\d+\.\d+)/, 1] next true if $CHILD_STATUS.success? && version && Version.new(version) >= min_version end - if which_xdpyinfo = which("xdpyinfo") + if (which_xdpyinfo = which("xdpyinfo")) version = Utils.popen_read(which_xdpyinfo, "-version")[/^xdpyinfo (\d+\.\d+\.\d+)/, 1] next true if $CHILD_STATUS.success? && version && Version.new(version) >= min_xdpyinfo_version end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 47920e13c8..bcd4a97ef2 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -114,14 +114,15 @@ class Resource # A target or a block must be given, but not both. def unpack(target = nil) mktemp(download_name) do |staging| - downloader.stage - @source_modified_time = downloader.source_modified_time - apply_patches - if block_given? - yield ResourceStageContext.new(self, staging) - elsif target - target = Pathname(target) - target.install Pathname.pwd.children + downloader.stage do + @source_modified_time = downloader.source_modified_time + apply_patches + if block_given? + yield ResourceStageContext.new(self, staging) + elsif target + target = Pathname(target) + target.install Pathname.pwd.children + end end end end diff --git a/Library/Homebrew/resource_auditor.rb b/Library/Homebrew/resource_auditor.rb index 187d1a2065..87fc4d2688 100644 --- a/Library/Homebrew/resource_auditor.rb +++ b/Library/Homebrew/resource_auditor.rb @@ -105,7 +105,7 @@ module Homebrew # pull request. next if url.match?(%r{^https://dl.bintray.com/homebrew/mirror/}) - if http_content_problem = curl_check_http_content(url, specs: specs) + if (http_content_problem = curl_check_http_content(url, specs: specs)) problem http_content_problem end elsif strategy <= GitDownloadStrategy diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 794be945d0..aeff5d68a2 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -12,7 +12,7 @@ require "rubocop-rails" require "rubocop-rspec" require "rubocop-sorbet" -require "rubocops/unless_multiple_conditions" +require "rubocops/shell_commands" require "rubocops/formula_desc" require "rubocops/components_order" diff --git a/Library/Homebrew/rubocops/class.rb b/Library/Homebrew/rubocops/class.rb index 5e1fa9ddf7..bea3bc055f 100644 --- a/Library/Homebrew/rubocops/class.rb +++ b/Library/Homebrew/rubocops/class.rb @@ -47,7 +47,7 @@ module RuboCop test_calls(test) do |node, params| p1, p2 = params - if match = string_content(p1).match(%r{(/usr/local/(s?bin))}) + if (match = string_content(p1).match(%r{(/usr/local/(s?bin))})) offending_node(p1) problem "use \#{#{match[2]}} instead of #{match[1]} in #{node}" do |corrector| corrector.replace(p1.source_range, p1.source.sub(match[1], "\#{#{match[2]}}")) diff --git a/Library/Homebrew/rubocops/extend/formula.rb b/Library/Homebrew/rubocops/extend/formula.rb index bc52687969..9fa05c03cb 100644 --- a/Library/Homebrew/rubocops/extend/formula.rb +++ b/Library/Homebrew/rubocops/extend/formula.rb @@ -155,7 +155,7 @@ module RuboCop # Returns the formula tap. def formula_tap - return unless match_obj = @file_path.match(%r{/(homebrew-\w+)/}) + return unless (match_obj = @file_path.match(%r{/(homebrew-\w+)/})) match_obj[1] end diff --git a/Library/Homebrew/rubocops/lines.rb b/Library/Homebrew/rubocops/lines.rb index fba426055f..3bc725df76 100644 --- a/Library/Homebrew/rubocops/lines.rb +++ b/Library/Homebrew/rubocops/lines.rb @@ -162,7 +162,7 @@ module RuboCop find_instance_method_call(body_node, :build, :without?) do |method| arg = parameters(method).first - next unless match = regex_match_group(arg, /^-?-?without-(.*)/) + next unless (match = regex_match_group(arg, /^-?-?without-(.*)/)) problem "Don't duplicate 'without': " \ "Use `build.without? \"#{match[1]}\"` to check for \"--without-#{match[1]}\"" @@ -170,7 +170,7 @@ module RuboCop find_instance_method_call(body_node, :build, :with?) do |method| arg = parameters(method).first - next unless match = regex_match_group(arg, /^-?-?with-(.*)/) + next unless (match = regex_match_group(arg, /^-?-?with-(.*)/)) problem "Don't duplicate 'with': Use `build.with? \"#{match[1]}\"` to check for \"--with-#{match[1]}\"" end @@ -258,7 +258,7 @@ module RuboCop popen_commands.each do |command| find_instance_method_call(body_node, "Utils", command) do |method| - next unless match = regex_match_group(parameters(method).first, /^([^"' ]+)=([^"' ]+)(?: (.*))?$/) + next unless (match = regex_match_group(parameters(method).first, /^([^"' ]+)=([^"' ]+)(?: (.*))?$/)) good_args = "Utils.#{command}({ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\")" @@ -329,7 +329,7 @@ module RuboCop find_strings(body_node).each do |str| content = string_content(str) - next unless match = content.match(/^python(@)?(\d\.\d+)$/) + next unless (match = content.match(/^python(@)?(\d\.\d+)$/)) next if python_version == match[2] fix = if match[1] @@ -385,7 +385,7 @@ module RuboCop end find_instance_method_call(body_node, :man, :+) do |method| - next unless match = regex_match_group(parameters(method).first, /^man[1-8]$/) + next unless (match = regex_match_group(parameters(method).first, /^man[1-8]$/)) problem "\"#{method.source}\" should be \"#{match[0]}\"" end @@ -393,37 +393,37 @@ module RuboCop # Avoid hard-coding compilers find_every_method_call_by_name(body_node, :system).each do |method| param = parameters(method).first - if match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)(\s|$)}) + if (match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)(\s|$)})) problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" - elsif match = regex_match_group(param, %r{^(/usr/bin/)?((g|llvm-g|clang)\+\+)(\s|$)}) + elsif (match = regex_match_group(param, %r{^(/usr/bin/)?((g|llvm-g|clang)\+\+)(\s|$)})) problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" end end find_instance_method_call(body_node, "ENV", :[]=) do |method| param = parameters(method)[1] - if match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)(\s|$)}) + if (match = regex_match_group(param, %r{^(/usr/bin/)?(gcc|llvm-gcc|clang)(\s|$)})) problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{match[2]}\"" - elsif match = regex_match_group(param, %r{^(/usr/bin/)?((g|llvm-g|clang)\+\+)(\s|$)}) + elsif (match = regex_match_group(param, %r{^(/usr/bin/)?((g|llvm-g|clang)\+\+)(\s|$)})) problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{match[2]}\"" end end # Prefer formula path shortcuts in strings formula_path_strings(body_node, :share) do |p| - next unless match = regex_match_group(p, %r{^(/(man))/?}) + next unless (match = regex_match_group(p, %r{^(/(man))/?})) problem "\"\#{share}#{match[1]}\" should be \"\#{#{match[2]}}\"" end formula_path_strings(body_node, :prefix) do |p| - if match = regex_match_group(p, %r{^(/share/(info|man))$}) + if (match = regex_match_group(p, %r{^(/share/(info|man))$})) problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2]}}\"" end - if match = regex_match_group(p, %r{^((/share/man/)(man[1-8]))}) + if (match = regex_match_group(p, %r{^((/share/man/)(man[1-8]))})) problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[3]}}\"" end - if match = regex_match_group(p, %r{^(/(bin|include|libexec|lib|sbin|share|Frameworks))}i) + if (match = regex_match_group(p, %r{^(/(bin|include|libexec|lib|sbin|share|Frameworks))}i)) problem "\"\#\{prefix}#{match[1]}\" should be \"\#{#{match[2].downcase}}\"" end end @@ -431,13 +431,13 @@ module RuboCop find_every_method_call_by_name(body_node, :depends_on).each do |method| key, value = destructure_hash(parameters(method).first) next if key.nil? || value.nil? - next unless match = regex_match_group(value, /^(lua|perl|python|ruby)(\d*)/) + next unless (match = regex_match_group(value, /^(lua|perl|python|ruby)(\d*)/)) problem "#{match[1]} modules should be vendored rather than use deprecated `#{method.source}`" end find_every_method_call_by_name(body_node, :system).each do |method| - next unless match = regex_match_group(parameters(method).first, /^(env|export)(\s+)?/) + next unless (match = regex_match_group(parameters(method).first, /^(env|export)(\s+)?/)) problem "Use ENV instead of invoking '#{match[1]}' to modify the environment" end @@ -449,7 +449,7 @@ module RuboCop option_child_nodes.each do |option| find_strings(option).each do |dependency| - next unless match = regex_match_group(dependency, /(with(out)?-\w+|c\+\+11)/) + next unless (match = regex_match_group(dependency, /(with(out)?-\w+|c\+\+11)/)) problem "Dependency #{string_content(dep)} should not use option #{match[0]}" end @@ -546,12 +546,21 @@ module RuboCop problem "`depends_on` can take requirement classes instead of instances" end + find_instance_method_call(body_node, "ENV", :[]) do |method| + next unless modifier?(method.parent) + + param = parameters(method).first + next unless node_equals?(param, "CI") + + problem 'Don\'t use ENV["CI"] for Homebrew CI checks.' + end + find_instance_method_call(body_node, "Dir", :[]) do |method| next unless parameters(method).size == 1 path = parameters(method).first next unless path.str_type? - next unless match = regex_match_group(path, /^[^*{},]+$/) + next unless (match = regex_match_group(path, /^[^*{},]+$/)) problem "Dir([\"#{string_content(path)}\"]) is unnecessary; just use \"#{match[0]}\"" end @@ -563,7 +572,7 @@ module RuboCop ) find_every_method_call_by_name(body_node, :system).each do |method| param = parameters(method).first - next unless match = regex_match_group(param, fileutils_methods) + next unless (match = regex_match_group(param, fileutils_methods)) problem "Use the `#{match}` Ruby method instead of `#{method.source}`" end @@ -639,58 +648,6 @@ module RuboCop problem "Formulae should not depend on :tuntap" if depends_on? :tuntap end end - - # This cop makes sure that shell command arguments are separated. - # - # @api private - class ShellCommands < FormulaCop - extend AutoCorrector - - def audit_formula(_node, _class_node, _parent_class_node, body_node) - # Match shell commands separated by spaces in the same string - shell_cmd_with_spaces_regex = /[^"' ]*(?:\s[^"' ]*)+/ - - popen_commands = [ - :popen_read, - :safe_popen_read, - :popen_write, - :safe_popen_write, - ] - - shell_metacharacters = %w[> < < | ; : & * $ ? : ~ + @ !` ( ) [ ]] - - find_every_method_call_by_name(body_node, :system).each do |method| - # Only separate when no shell metacharacters are present - next if shell_metacharacters.any? { |meta| string_content(parameters(method).first).include?(meta) } - - next unless match = regex_match_group(parameters(method).first, shell_cmd_with_spaces_regex) - - good_args = match[0].gsub(" ", "\", \"") - offending_node(parameters(method).first) - problem "Separate `system` commands into `\"#{good_args}\"`" do |corrector| - corrector.replace(@offensive_node.source_range, @offensive_node.source.gsub(" ", "\", \"")) - end - end - - popen_commands.each do |command| - find_instance_method_call(body_node, "Utils", command) do |method| - index = parameters(method).first.hash_type? ? 1 : 0 - - # Only separate when no shell metacharacters are present - next if shell_metacharacters.any? { |meta| string_content(parameters(method)[index]).include?(meta) } - - next unless match = regex_match_group(parameters(method)[index], shell_cmd_with_spaces_regex) - - good_args = match[0].gsub(" ", "\", \"") - offending_node(parameters(method)[index]) - problem "Separate `Utils.#{command}` commands into `\"#{good_args}\"`" do |corrector| - good_args = @offensive_node.source.gsub(" ", "\", \"") - corrector.replace(@offensive_node.source_range, good_args) - end - end - end - end - end end end end diff --git a/Library/Homebrew/rubocops/patches.rb b/Library/Homebrew/rubocops/patches.rb index 10692a497f..605683eacf 100644 --- a/Library/Homebrew/rubocops/patches.rb +++ b/Library/Homebrew/rubocops/patches.rb @@ -11,6 +11,7 @@ module RuboCop # TODO: Many of these could be auto-corrected. class Patches < FormulaCop extend T::Sig + extend AutoCorrector def audit_formula(node, _class_node, _parent_class_node, body) @full_source_content = source_buffer(node).source @@ -40,37 +41,36 @@ module RuboCop private - def patch_problems(patch) - patch_url = string_content(patch) + def patch_problems(patch_url_node) + patch_url = string_content(patch_url_node) - if regex_match_group(patch, %r{https://github.com/[^/]*/[^/]*/pull}) + if regex_match_group(patch_url_node, %r{https://github.com/[^/]*/[^/]*/pull}) problem "Use a commit hash URL rather than an unstable pull request URL: #{patch_url}" end - if regex_match_group(patch, %r{.*gitlab.*/merge_request.*}) + if regex_match_group(patch_url_node, %r{.*gitlab.*/merge_request.*}) problem "Use a commit hash URL rather than an unstable merge request URL: #{patch_url}" end - if regex_match_group(patch, %r{https://github.com/[^/]*/[^/]*/commit/[a-fA-F0-9]*\.diff}) - problem <<~EOS.chomp - GitHub patches should end with .patch, not .diff: - #{patch_url} - EOS + if regex_match_group(patch_url_node, %r{https://github.com/[^/]*/[^/]*/commit/[a-fA-F0-9]*\.diff}) + problem "GitHub patches should end with .patch, not .diff: #{patch_url}" do |corrector| + correct = patch_url_node.source.gsub(/\.diff/, ".patch") + corrector.replace(patch_url_node.source_range, correct) + end end - if regex_match_group(patch, %r{.*gitlab.*/commit/[a-fA-F0-9]*\.diff}) - problem <<~EOS.chomp - GitLab patches should end with .patch, not .diff: - #{patch_url} - EOS + if regex_match_group(patch_url_node, %r{.*gitlab.*/commit/[a-fA-F0-9]*\.diff}) + problem "GitLab patches should end with .patch, not .diff: #{patch_url}" do |corrector| + correct = patch_url_node.source.gsub(/\.diff/, ".patch") + corrector.replace(patch_url_node.source_range, correct) + end end gh_patch_param_pattern = %r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)} - if regex_match_group(patch, gh_patch_param_pattern) && !patch_url.match?(/\?full_index=\w+$/) - problem <<~EOS - GitHub patches should use the full_index parameter: - #{patch_url}?full_index=1 - EOS + if regex_match_group(patch_url_node, gh_patch_param_pattern) && !patch_url.match?(/\?full_index=\w+$/) + problem "GitHub patches should use the full_index parameter: #{patch_url}?full_index=1" do |corrector| + corrector.replace(patch_url_node.source_range, "#{patch_url}?full_index=1") + end end gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/}, @@ -78,39 +78,33 @@ module RuboCop %r{gist\.github\.com/raw}, %r{gist\.github\.com/.+/raw}, %r{gist\.githubusercontent\.com/.+/raw}]) - if regex_match_group(patch, gh_patch_patterns) && !patch_url.match?(%r{/[a-fA-F0-9]{6,40}/}) - problem <<~EOS.chomp - GitHub/Gist patches should specify a revision: - #{patch_url} - EOS + if regex_match_group(patch_url_node, gh_patch_patterns) && !patch_url.match?(%r{/[a-fA-F0-9]{6,40}/}) + problem "GitHub/Gist patches should specify a revision: #{patch_url}" end gh_patch_diff_pattern = %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} - if regex_match_group(patch, gh_patch_diff_pattern) + if regex_match_group(patch_url_node, gh_patch_diff_pattern) problem "Use a commit hash URL rather than patch-diff: #{patch_url}" end - if regex_match_group(patch, %r{macports/trunk}) - problem <<~EOS.chomp - MacPorts patches should specify a revision instead of trunk: - #{patch_url} - EOS + if regex_match_group(patch_url_node, %r{macports/trunk}) + problem "MacPorts patches should specify a revision instead of trunk: #{patch_url}" end - if regex_match_group(patch, %r{^http://trac\.macports\.org}) - problem <<~EOS.chomp - Patches from MacPorts Trac should be https://, not http: - #{patch_url} - EOS + if regex_match_group(patch_url_node, %r{^http://trac\.macports\.org}) + problem "Patches from MacPorts Trac should be https://, not http: #{patch_url}" do |corrector| + correct = patch_url_node.source.gsub(%r{^http://}, "https://") + corrector.replace(patch_url_node.source_range, correct) + end end - return unless regex_match_group(patch, %r{^http://bugs\.debian\.org}) + return unless regex_match_group(patch_url_node, %r{^http://bugs\.debian\.org}) - problem <<~EOS.chomp - Patches from Debian should be https://, not http: - #{patch_url} - EOS + problem "Patches from Debian should be https://, not http: #{patch_url}" do |corrector| + correct = patch_url_node.source.gsub(%r{^http://}, "https://") + corrector.replace(patch_url_node.source_range, correct) + end end def inline_patch_problems(patch) diff --git a/Library/Homebrew/rubocops/shared/desc_helper.rb b/Library/Homebrew/rubocops/shared/desc_helper.rb index 5e14114b70..4ca9d5f9f1 100644 --- a/Library/Homebrew/rubocops/shared/desc_helper.rb +++ b/Library/Homebrew/rubocops/shared/desc_helper.rb @@ -44,7 +44,7 @@ module RuboCop desc_problem "Description shouldn't have trailing spaces." if regex_match_group(desc, /\s+$/) # Check if "command-line" is spelled incorrectly in the desc. - if match = regex_match_group(desc, /(command ?line)/i) + if (match = regex_match_group(desc, /(command ?line)/i)) c = match.to_s[0] desc_problem "Description should use \"#{c}ommand-line\" instead of \"#{match}\"." end diff --git a/Library/Homebrew/rubocops/shared/helper_functions.rb b/Library/Homebrew/rubocops/shared/helper_functions.rb index 63858e3697..34ef119114 100644 --- a/Library/Homebrew/rubocops/shared/helper_functions.rb +++ b/Library/Homebrew/rubocops/shared/helper_functions.rb @@ -68,6 +68,15 @@ module RuboCop end end content + when :send + if node.method?(:+) && (node.receiver.str_type? || node.receiver.dstr_type?) + content = string_content(node.receiver) + arg = node.arguments.first + content += string_content(arg) if arg + content + else + "" + end when :const node.const_name when :sym diff --git a/Library/Homebrew/rubocops/shell_commands.rb b/Library/Homebrew/rubocops/shell_commands.rb new file mode 100644 index 0000000000..2a6646557b --- /dev/null +++ b/Library/Homebrew/rubocops/shell_commands.rb @@ -0,0 +1,73 @@ +# typed: true +# frozen_string_literal: true + +require "active_support/core_ext/array/access" +require "rubocops/shared/helper_functions" + +module RuboCop + module Cop + module Style + # This cop makes sure that shell command arguments are separated. + # + # @api private + class ShellCommands < Base + include HelperFunctions + extend AutoCorrector + + MSG = "Separate `%s` commands into `%s`" + + TARGET_METHODS = [ + [nil, :system], + [nil, :safe_system], + [nil, :quiet_system], + [:Utils, :popen_read], + [:Utils, :safe_popen_read], + [:Utils, :popen_write], + [:Utils, :safe_popen_write], + ].freeze + RESTRICT_ON_SEND = TARGET_METHODS.map(&:second).uniq.freeze + + SHELL_METACHARACTERS = %w[> < < | ; : & * $ ? : ~ + @ ! ` ( ) [ ]].freeze + + def on_send(node) + TARGET_METHODS.each do |target_class, target_method| + next unless node.method_name == target_method + + target_receivers = if target_class.nil? + [nil, s(:const, nil, :Kernel), s(:const, nil, :Homebrew)] + else + [s(:const, nil, target_class)] + end + next unless target_receivers.include?(node.receiver) + + first_arg = node.arguments.first + arg_count = node.arguments.count + if first_arg&.hash_type? # popen methods allow env hash + first_arg = node.arguments.second + arg_count -= 1 + end + next if first_arg.nil? || arg_count >= 2 + + first_arg_str = string_content(first_arg) + + # Only separate when no shell metacharacters are present + next if SHELL_METACHARACTERS.any? { |meta| first_arg_str.include?(meta) } + + split_args = first_arg_str.shellsplit + next if split_args.count <= 1 + + good_args = split_args.map { |arg| "\"#{arg}\"" }.join(", ") + method_string = if target_class + "#{target_class}.#{target_method}" + else + target_method.to_s + end + add_offense(first_arg, message: format(MSG, method: method_string, good_args: good_args)) do |corrector| + corrector.replace(first_arg.source_range, good_args) + end + end + end + end + end + end +end diff --git a/Library/Homebrew/rubocops/text.rb b/Library/Homebrew/rubocops/text.rb index 82df0a41ab..b61f25010f 100644 --- a/Library/Homebrew/rubocops/text.rb +++ b/Library/Homebrew/rubocops/text.rb @@ -15,7 +15,7 @@ module RuboCop def audit_formula(node, _class_node, _parent_class_node, body_node) full_source_content = source_buffer(node).source - if match = full_source_content.match(/^require ['"]formula['"]$/) + if (match = full_source_content.match(/^require ['"]formula['"]$/)) range = source_range(source_buffer(node), match.pre_match.count("\n") + 1, 0, match[0].length) add_offense(range, message: "`#{match}` is now unnecessary") do |corrector| corrector.remove(range_with_surrounding_space(range: range)) @@ -95,7 +95,7 @@ module RuboCop end prefix_path(body_node) do |prefix_node, path| - next unless match = path.match(%r{^(bin|include|libexec|lib|sbin|share|Frameworks)(?:/| |$)}) + next unless (match = path.match(%r{^(bin|include|libexec|lib|sbin|share|Frameworks)(?:/| |$)})) offending_node(prefix_node) problem "Use `#{match[1].downcase}` instead of `prefix + \"#{match[1]}\"`" diff --git a/Library/Homebrew/rubocops/unless_multiple_conditions.rb b/Library/Homebrew/rubocops/unless_multiple_conditions.rb deleted file mode 100644 index 4e4d673e47..0000000000 --- a/Library/Homebrew/rubocops/unless_multiple_conditions.rb +++ /dev/null @@ -1,35 +0,0 @@ -# typed: strict -# frozen_string_literal: true - -module RuboCop - module Cop - module Style - # This cop checks that `unless` is not used with multiple conditions. - # - # @api private - class UnlessMultipleConditions < Base - extend T::Sig - extend AutoCorrector - - MSG = "Avoid using `unless` with multiple conditions." - - sig { params(node: RuboCop::AST::IfNode).void } - def on_if(node) - return if !node.unless? || (!node.condition.and_type? && !node.condition.or_type?) - - add_offense(node.condition.source_range.with(begin_pos: node.loc.keyword.begin_pos)) do |corrector| - corrector.replace(node.loc.keyword, "if") - corrector.replace(node.condition.loc.operator, node.condition.inverse_operator) - [node.condition.lhs, node.condition.rhs].each do |subcondition| - if !subcondition.source.start_with?("(") || !subcondition.source.end_with?(")") - corrector.insert_before(subcondition, "(") - corrector.insert_after(subcondition, ")") - end - corrector.insert_before(subcondition, "!") - end - end - end - end - end - end -end diff --git a/Library/Homebrew/rubocops/uses_from_macos.rb b/Library/Homebrew/rubocops/uses_from_macos.rb index 393e99558e..ee4001d197 100644 --- a/Library/Homebrew/rubocops/uses_from_macos.rb +++ b/Library/Homebrew/rubocops/uses_from_macos.rb @@ -15,6 +15,7 @@ module RuboCop bzip2 cups curl + cyrus-sasl dyld-headers ed expat @@ -42,6 +43,7 @@ module RuboCop netcat openldap openlibm + pcsc-lite pod2man rpcgen ruby diff --git a/Library/Homebrew/search.rb b/Library/Homebrew/search.rb index fe37e97254..773579de0b 100644 --- a/Library/Homebrew/search.rb +++ b/Library/Homebrew/search.rb @@ -10,7 +10,7 @@ module Homebrew # @api private module Search def query_regexp(query) - if m = query.match(%r{^/(.*)/$}) + if (m = query.match(%r{^/(.*)/$})) Regexp.new(m[1]) else query @@ -48,7 +48,7 @@ module Homebrew filename: query, extension: "rb", ) - rescue GitHub::Error => e + rescue GitHub::API::Error => e opoo "Error searching on GitHub: #{e}\n" nil end diff --git a/Library/Homebrew/shims/mac/super/gem b/Library/Homebrew/shims/mac/super/gem new file mode 120000 index 0000000000..a38a43ef7a --- /dev/null +++ b/Library/Homebrew/shims/mac/super/gem @@ -0,0 +1 @@ +ruby \ No newline at end of file diff --git a/Library/Homebrew/shims/mac/super/rake b/Library/Homebrew/shims/mac/super/rake new file mode 120000 index 0000000000..a38a43ef7a --- /dev/null +++ b/Library/Homebrew/shims/mac/super/rake @@ -0,0 +1 @@ +ruby \ No newline at end of file diff --git a/Library/Homebrew/shims/mac/super/ruby b/Library/Homebrew/shims/mac/super/ruby new file mode 100755 index 0000000000..91921781ff --- /dev/null +++ b/Library/Homebrew/shims/mac/super/ruby @@ -0,0 +1,12 @@ +#!/bin/bash +# System Ruby's mkmf on Mojave (10.14) and later require SDKROOT set to work correctly. + +source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh" + +try_exec_non_system "$SHIM_FILE" "$@" + +if [[ -z "$SDKROOT" && -n "$HOMEBREW_SDKROOT" ]]; then + export SDKROOT=$HOMEBREW_SDKROOT +fi + +safe_exec "/usr/bin/$SHIM_FILE" "$@" diff --git a/Library/Homebrew/shims/mac/super/sed b/Library/Homebrew/shims/mac/super/sed deleted file mode 100755 index 7b1313dac0..0000000000 --- a/Library/Homebrew/shims/mac/super/sed +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -if [[ "$HOMEBREW_CCCFG" = *s* ]] -then - # Fix issue with sed barfing on unicode characters on Mountain Lion - unset LC_ALL - export LC_CTYPE="C" -fi -exec /usr/bin/sed "$@" diff --git a/Library/Homebrew/shims/scm/git b/Library/Homebrew/shims/scm/git index 65ecc55237..788b1cbb07 100755 --- a/Library/Homebrew/shims/scm/git +++ b/Library/Homebrew/shims/scm/git @@ -3,87 +3,15 @@ # This script because we support $HOMEBREW_GIT, $HOMEBREW_SVN, etc., Xcode-only and # no Xcode/CLT configurations. Order is careful to be what the user would want. -set +o posix - -quiet_safe_cd() { - cd "$1" >/dev/null || { echo "Error: failed to cd to $1" >&2; exit 1; } -} - -absdir() { - quiet_safe_cd "${1%/*}/" && pwd -P -} - -dirbasepath() { - local dir="$1" - local base="${2##*/}" - echo "$dir/$base" -} - -realpath() { - local path="$1" - local dir - local dest - - dir="$(absdir "$path")" - path="$(dirbasepath "$dir" "$path")" - - while [[ -L "$path" ]] - do - dest="$(readlink "$path")" - if [[ "$dest" = "/"* ]] - then - path="$dest" - else - path="$dir/$dest" - fi - dir="$(absdir "$path")" - path="$(dirbasepath "$dir" "$path")" - done - - echo "$path" -} - -executable() { - local file="$1" - [[ -f "$file" && -x "$file" ]] -} - -lowercase() { - echo "$1" | tr "[:upper:]" "[:lower:]" -} - -safe_exec() { - local arg0="$1" - if ! executable "$arg0" - then - return - fi - # prevent fork-bombs - if [[ "$(lowercase "$arg0")" = "$SCM_FILE" || "$(realpath "$arg0")" = "$SCM_REAL" ]] - then - return - fi - if [[ "$HOMEBREW" = "print-path" ]] - then - local dir="$(quiet_safe_cd "${arg0%/*}/" && pwd)" - local path="$(dirbasepath "$dir" "$arg0")" - echo "$path" - exit - fi - exec "$@" -} - -SCM_FILE="${0##*/}" -SCM_REAL="$(realpath "$0")" -SCM_DIR="$(quiet_safe_cd "${SCM_REAL%/*}/" && pwd -P)" - -if [[ "$1" = --homebrew=* ]] +if [ -z "$HOMEBREW_LIBRARY" ] then - HOMEBREW="${1:11}" - shift + echo "${0##*/}: This shim is internal and must be run via brew." >&2 + exit 1 fi -case "$(lowercase "$SCM_FILE")" in +source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh" + +case "$(lowercase "$SHIM_FILE")" in git) if [[ -n "$HOMEBREW_GIT" && "$HOMEBREW_GIT" != git ]] then @@ -98,21 +26,10 @@ case "$(lowercase "$SCM_FILE")" in ;; esac -brew_prefix_version="$(quiet_safe_cd "$SCM_DIR/../../../../../bin" 2>/dev/null && pwd -P)/$SCM_FILE" +brew_prefix_version="$HOMEBREW_PREFIX/bin/$SHIM_FILE" safe_exec "$brew_prefix_version" "$@" -brew_repo_version="$(quiet_safe_cd "$SCM_DIR/../../../../bin" && pwd -P)/$SCM_FILE" -safe_exec "$brew_repo_version" "$@" - -IFS=$'\n' -for path in $(type -aP "$SCM_FILE") -do - if [[ "$path" != "/usr/bin/$SCM_FILE" ]] - then - safe_exec "$path" "$@" - fi -done -unset IFS +try_exec_non_system "$SHIM_FILE" "$@" if executable "/usr/bin/xcode-select" then @@ -129,19 +46,19 @@ then fi if [[ -z "$popup_stub" && "$xcode_path" != "/" ]] then - path="$(/usr/bin/xcrun -find "$SCM_FILE" 2>/dev/null)" + path="$(/usr/bin/xcrun -find "$SHIM_FILE" 2>/dev/null)" safe_exec "$path" "$@" fi fi -path="/Applications/Xcode.app/Contents/Developer/usr/bin/$SCM_FILE" +path="/Applications/Xcode.app/Contents/Developer/usr/bin/$SHIM_FILE" safe_exec "$path" "$@" if [[ -z "$popup_stub" && "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101500" ]] then - path="/usr/bin/$SCM_FILE" + path="/usr/bin/$SHIM_FILE" safe_exec "$path" "$@" fi -echo "You must: brew install $SCM_FILE" >&2 +echo "You must: brew install $SHIM_FILE" >&2 exit 1 diff --git a/Library/Homebrew/shims/utils.sh b/Library/Homebrew/shims/utils.sh new file mode 100644 index 0000000000..7d90d7b697 --- /dev/null +++ b/Library/Homebrew/shims/utils.sh @@ -0,0 +1,94 @@ +set +o posix + +quiet_safe_cd() { + cd "$1" >/dev/null || { echo "Error: failed to cd to $1" >&2; exit 1; } +} + +absdir() { + quiet_safe_cd "${1%/*}/" && pwd -P +} + +dirbasepath() { + local dir="$1" + local base="${2##*/}" + echo "$dir/$base" +} + +realpath() { + local path="$1" + local dir + local dest + + dir="$(absdir "$path")" + path="$(dirbasepath "$dir" "$path")" + + while [[ -L "$path" ]] + do + dest="$(readlink "$path")" + if [[ "$dest" = "/"* ]] + then + path="$dest" + else + path="$dir/$dest" + fi + dir="$(absdir "$path")" + path="$(dirbasepath "$dir" "$path")" + done + + echo "$path" +} + +executable() { + local file="$1" + [[ -f "$file" && -x "$file" ]] +} + +lowercase() { + echo "$1" | tr "[:upper:]" "[:lower:]" +} + +safe_exec() { + local arg0="$1" + if ! executable "$arg0" + then + return + fi + # prevent fork-bombs + if [[ "$(lowercase "$arg0")" = "$SHIM_FILE" || "$(realpath "$arg0")" = "$SHIM_REAL" ]] + then + return + fi + if [[ "$HOMEBREW" = "print-path" ]] + then + local dir="$(quiet_safe_cd "${arg0%/*}/" && pwd)" + local path="$(dirbasepath "$dir" "$arg0")" + echo "$path" + exit + fi + exec "$@" +} + +try_exec_non_system() { + local file="$1" + shift + + IFS=$'\n' + for path in $(type -aP "$file") + do + if [[ "$path" != "/usr/bin/$file" ]] + then + safe_exec "$path" "$@" + fi + done + unset IFS +} + + +SHIM_FILE="${0##*/}" +SHIM_REAL="$(realpath "$0")" + +if [[ "$1" = --homebrew=* ]] +then + HOMEBREW="${1:11}" + shift +fi diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 7ea09450bf..51839f3d88 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "resource" +require "download_strategy" require "checksum" require "version" require "options" @@ -10,7 +11,6 @@ require "dependency_collector" require "utils/bottles" require "patch" require "compilers" -require "global" require "os/mac/version" require "extend/on_os" @@ -178,7 +178,7 @@ class SoftwareSpec end def uses_from_macos(spec, _bounds = {}) - spec = Hash[*spec.first] if spec.is_a?(Hash) + spec = spec.dup.shift if spec.is_a?(Hash) depends_on(spec) end @@ -292,7 +292,7 @@ class Bottle attr_reader :name, :resource, :prefix, :cellar, :rebuild - def_delegators :resource, :url, :fetch, :verify_download_integrity + def_delegators :resource, :url, :verify_download_integrity def_delegators :resource, :cached_download, :clear_cache def initialize(formula, spec) @@ -314,6 +314,22 @@ class Bottle @rebuild = spec.rebuild end + def fetch(verify_download_integrity: true) + # add the default bottle domain as a fallback mirror + # TODO: this may need adjusted when if we use GitHub Packages by default + if @resource.download_strategy == CurlDownloadStrategy && + @resource.url.start_with?(Homebrew::EnvConfig.bottle_domain) + fallback_url = @resource.url + .sub(/^#{Regexp.escape(Homebrew::EnvConfig.bottle_domain)}/, + HOMEBREW_BOTTLE_DEFAULT_DOMAIN) + @resource.mirror(fallback_url) if [@resource.url, *@resource.mirrors].exclude?(fallback_url) + elsif @resource.download_strategy == CurlGitHubPackagesDownloadStrategy + @resource.downloader.name = @name + @resource.downloader.checksum = @resource.checksum.hexdigest + end + @resource.fetch(verify_download_integrity: verify_download_integrity) + end + def compatible_locations? @spec.compatible_locations? end @@ -363,7 +379,11 @@ class BottleSpecification def root_url(var = nil, specs = {}) if var.nil? - @root_url ||= "#{Homebrew::EnvConfig.bottle_domain}/#{Utils::Bottles::Bintray.repository(tap)}" + @root_url ||= if Homebrew::EnvConfig.bottle_domain.start_with?(GitHubPackages::URL_PREFIX) + "#{GitHubPackages::URL_PREFIX}#{tap.full_name}" + else + "#{Homebrew::EnvConfig.bottle_domain}/#{Utils::Bottles::Bintray.repository(tap)}" + end else @root_url = var @root_url_specs.merge!(specs) @@ -402,9 +422,9 @@ class BottleSpecification cellar == :any_skip_relocation end - sig { params(tag: Symbol).returns(T::Boolean) } - def tag?(tag) - checksum_for(tag) ? true : false + sig { params(tag: Symbol, exact: T::Boolean).returns(T::Boolean) } + def tag?(tag, exact: false) + checksum_for(tag, exact: exact) ? true : false end # Checksum methods in the DSL's bottle block take @@ -444,9 +464,9 @@ class BottleSpecification collector[tag] = { checksum: Checksum.new(digest), cellar: cellar } end - sig { params(tag: Symbol).returns(T.nilable([Checksum, Symbol, T.any(Symbol, String)])) } - def checksum_for(tag) - collector.fetch_checksum_for(tag) + sig { params(tag: Symbol, exact: T::Boolean).returns(T.nilable([Checksum, Symbol, T.any(Symbol, String)])) } + def checksum_for(tag, exact: false) + collector.fetch_checksum_for(tag, exact: exact) end def checksums diff --git a/Library/Homebrew/sorbet/plugins/using.rb b/Library/Homebrew/sorbet/plugins/using.rb index e1bf761b29..288c4c6c44 100644 --- a/Library/Homebrew/sorbet/plugins/using.rb +++ b/Library/Homebrew/sorbet/plugins/using.rb @@ -28,4 +28,16 @@ when "HashValidator" def assert_valid_keys!(*valid_keys); end end RUBY +when "TimeRemaining" + puts <<-RUBY + # typed: strict + + class ::Time + sig { returns(T.any(Integer, Float)) } + def remaining; end + + sig { returns(T.any(Integer, Float)) } + def remaining!; end + end + RUBY end diff --git a/Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.2.rbi b/Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.3.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.2.rbi rename to Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.3.rbi index ec457767be..86c93ee7a9 100644 --- a/Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.2.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/activesupport@6.1.3.rbi @@ -518,10 +518,10 @@ end class String include(::Comparable) - include(::JSON::Ext::Generator::GeneratorMethods::String) include(::Colorize::InstanceMethods) - extend(::JSON::Ext::Generator::GeneratorMethods::String::Extend) + include(::JSON::Ext::Generator::GeneratorMethods::String) extend(::Colorize::ClassMethods) + extend(::JSON::Ext::Generator::GeneratorMethods::String::Extend) def acts_like_string?; end def as_json(options = T.unsafe(nil)); end diff --git a/Library/Homebrew/sorbet/rbi/gems/codecov@0.4.3.rbi b/Library/Homebrew/sorbet/rbi/gems/codecov@0.5.1.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/codecov@0.4.3.rbi rename to Library/Homebrew/sorbet/rbi/gems/codecov@0.5.1.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/i18n@1.8.8.rbi b/Library/Homebrew/sorbet/rbi/gems/i18n@1.8.9.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/i18n@1.8.8.rbi rename to Library/Homebrew/sorbet/rbi/gems/i18n@1.8.9.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/mime-types-data@3.2020.1104.rbi b/Library/Homebrew/sorbet/rbi/gems/mime-types-data@3.2021.0212.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/mime-types-data@3.2020.1104.rbi rename to Library/Homebrew/sorbet/rbi/gems/mime-types-data@3.2021.0212.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/minitest@5.14.3.rbi b/Library/Homebrew/sorbet/rbi/gems/minitest@5.14.4.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/minitest@5.14.3.rbi rename to Library/Homebrew/sorbet/rbi/gems/minitest@5.14.4.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.1.rbi b/Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.2.rbi similarity index 99% rename from Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.2.rbi index 9125a0e52a..6c4c5e5df4 100644 --- a/Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/nokogiri@1.11.2.rbi @@ -621,9 +621,11 @@ class Nokogiri::VersionInfo def libxml2_using_system?; end def loaded_libxml_version; end def loaded_libxslt_version; end + def ruby_minor; end def to_hash; end def to_markdown; end def warnings; end + def windows?; end class << self def instance; end @@ -1405,10 +1407,6 @@ class Nokogiri::XML::Reader def value?; end def xml_version; end - private - - def attr_nodes; end - class << self def from_io(*_arg0); end def from_memory(*_arg0); end @@ -1620,9 +1618,7 @@ Nokogiri::XML::XML_C14N_1_1 = T.let(T.unsafe(nil), Integer) Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 = T.let(T.unsafe(nil), Integer) -class Nokogiri::XML::XPath - def document; end - def document=(_arg0); end +module Nokogiri::XML::XPath end class Nokogiri::XML::XPath::SyntaxError < ::Nokogiri::XML::SyntaxError diff --git a/Library/Homebrew/sorbet/rbi/gems/parallel_tests@3.4.0.rbi b/Library/Homebrew/sorbet/rbi/gems/parallel_tests@3.5.2.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/parallel_tests@3.4.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/parallel_tests@3.5.2.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/parlour@5.0.0.rbi b/Library/Homebrew/sorbet/rbi/gems/parlour@6.0.0.rbi similarity index 99% rename from Library/Homebrew/sorbet/rbi/gems/parlour@5.0.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/parlour@6.0.0.rbi index df31c31f07..52fa968137 100644 --- a/Library/Homebrew/sorbet/rbi/gems/parlour@5.0.0.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/parlour@6.0.0.rbi @@ -420,8 +420,8 @@ class Parlour::RbiGenerator::Namespace < ::Parlour::RbiGenerator::RbiObject def merge_into_self(others); end sig { overridable.override.params(others: T::Array[Parlour::RbiGenerator::RbiObject]).returns(T::Boolean) } def mergeable?(others); end - sig { params(object: T.untyped, block: T.proc.params(x: Parlour::RbiGenerator::Namespace).void).void } - def path(object, &block); end + sig { params(constant: Module, block: T.proc.params(x: Parlour::RbiGenerator::Namespace).void).void } + def path(constant, &block); end sig { returns(T::Boolean) } def sealed; end def type_aliases(*args, &blk); end diff --git a/Library/Homebrew/sorbet/rbi/gems/pry@0.13.1.rbi b/Library/Homebrew/sorbet/rbi/gems/pry@0.13.1.rbi deleted file mode 100644 index 666a7ad3ef..0000000000 --- a/Library/Homebrew/sorbet/rbi/gems/pry@0.13.1.rbi +++ /dev/null @@ -1,7 +0,0 @@ -# DO NOT EDIT MANUALLY -# This is an autogenerated file for types exported from the `pry` gem. -# Please instead update this file by running `tapioca generate --exclude json`. - -# typed: true - - diff --git a/Library/Homebrew/sorbet/rbi/gems/pry@0.14.0.rbi b/Library/Homebrew/sorbet/rbi/gems/pry@0.14.0.rbi new file mode 100644 index 0000000000..dc1730cdc0 --- /dev/null +++ b/Library/Homebrew/sorbet/rbi/gems/pry@0.14.0.rbi @@ -0,0 +1,8 @@ +# DO NOT EDIT MANUALLY +# This is an autogenerated file for types exported from the `pry` gem. +# Please instead update this file by running `tapioca sync`. + +# typed: true + +# THIS IS AN EMPTY RBI FILE. +# see https://github.com/Shopify/tapioca/blob/master/README.md#manual-gem-requires diff --git a/Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.0.3.rbi b/Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.1.1.rbi similarity index 98% rename from Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.0.3.rbi rename to Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.1.1.rbi index bb6f3dbb0f..2fa7ded968 100644 --- a/Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.0.3.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/regexp_parser@2.1.1.rbi @@ -84,6 +84,10 @@ class Regexp::Expression::Backreference::Base < ::Regexp::Expression::Base def match_length; end def referenced_expression; end def referenced_expression=(_arg0); end + + private + + def initialize_copy(orig); end end class Regexp::Expression::Backreference::Name < ::Regexp::Expression::Backreference::Base @@ -198,7 +202,7 @@ class Regexp::Expression::Base private - def initialize_clone(orig); end + def initialize_copy(orig); end end class Regexp::Expression::CharacterSet < ::Regexp::Expression::Subexpression @@ -292,6 +296,10 @@ class Regexp::Expression::Conditional::Condition < ::Regexp::Expression::Base def reference; end def referenced_expression; end def referenced_expression=(_arg0); end + + private + + def initialize_copy(orig); end end class Regexp::Expression::Conditional::Expression < ::Regexp::Expression::Subexpression @@ -306,9 +314,13 @@ class Regexp::Expression::Conditional::Expression < ::Regexp::Expression::Subexp def referenced_expression; end def referenced_expression=(_arg0); end def to_s(format = T.unsafe(nil)); end + + private + + def initialize_copy(orig); end end -class Regexp::Expression::Conditional::TooManyBranches < ::StandardError +class Regexp::Expression::Conditional::TooManyBranches < ::Regexp::Parser::Error def initialize; end end @@ -431,12 +443,16 @@ class Regexp::Expression::Group::Named < ::Regexp::Expression::Group::Capture private - def initialize_clone(orig); end + def initialize_copy(orig); end end class Regexp::Expression::Group::Options < ::Regexp::Expression::Group::Base def option_changes; end def option_changes=(_arg0); end + + private + + def initialize_copy(orig); end end class Regexp::Expression::Group::Passive < ::Regexp::Expression::Group::Base @@ -486,7 +502,7 @@ class Regexp::Expression::Quantifier private - def initialize_clone(orig); end + def initialize_copy(orig); end end Regexp::Expression::Quantifier::MODES = T.let(T.unsafe(nil), Array) @@ -553,7 +569,7 @@ class Regexp::Expression::Subexpression < ::Regexp::Expression::Base private - def initialize_clone(orig); end + def initialize_copy(orig); end end module Regexp::Expression::UnicodeProperty @@ -867,7 +883,6 @@ end class Regexp::Parser include(::Regexp::Expression) - include(::Regexp::Syntax) include(::Regexp::Expression::UnicodeProperty) def parse(input, syntax = T.unsafe(nil), options: T.unsafe(nil), &block); end @@ -898,6 +913,7 @@ class Regexp::Parser def intersection(token); end def interval(target_node, token); end def keep(token); end + def literal(token); end def meta(token); end def negate_set; end def nest(exp); end @@ -933,11 +949,16 @@ end Regexp::Parser::ENC_FLAGS = T.let(T.unsafe(nil), Array) +class Regexp::Parser::Error < ::StandardError +end + Regexp::Parser::MOD_FLAGS = T.let(T.unsafe(nil), Array) -class Regexp::Parser::ParserError < ::StandardError +class Regexp::Parser::ParserError < ::Regexp::Parser::Error end +Regexp::Parser::UPTokens = Regexp::Syntax::Token::UnicodeProperty + class Regexp::Parser::UnknownTokenError < ::Regexp::Parser::ParserError def initialize(type, token); end end @@ -1005,20 +1026,18 @@ class Regexp::Scanner::InvalidSequenceError < ::Regexp::Scanner::ValidationError def initialize(what = T.unsafe(nil), where = T.unsafe(nil)); end end -Regexp::Scanner::PROP_MAPS_DIR = T.let(T.unsafe(nil), String) - class Regexp::Scanner::PrematureEndError < ::Regexp::Scanner::ScannerError def initialize(where = T.unsafe(nil)); end end -class Regexp::Scanner::ScannerError < ::StandardError +class Regexp::Scanner::ScannerError < ::Regexp::Parser::Error end class Regexp::Scanner::UnknownUnicodePropertyError < ::Regexp::Scanner::ValidationError def initialize(name); end end -class Regexp::Scanner::ValidationError < ::StandardError +class Regexp::Scanner::ValidationError < ::Regexp::Parser::Error def initialize(reason); end end @@ -1088,7 +1107,7 @@ class Regexp::Syntax::NotImplementedError < ::Regexp::Syntax::SyntaxError def initialize(syntax, type, token); end end -class Regexp::Syntax::SyntaxError < ::StandardError +class Regexp::Syntax::SyntaxError < ::Regexp::Parser::Error end module Regexp::Syntax::Token diff --git a/Library/Homebrew/sorbet/rbi/gems/rspec-core@3.10.0.rbi b/Library/Homebrew/sorbet/rbi/gems/rspec-core@3.10.1.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/rspec-core@3.10.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/rspec-core@3.10.1.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/rspec-expectations@3.10.0.rbi b/Library/Homebrew/sorbet/rbi/gems/rspec-expectations@3.10.1.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/rspec-expectations@3.10.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/rspec-expectations@3.10.1.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/rspec-mocks@3.10.0.rbi b/Library/Homebrew/sorbet/rbi/gems/rspec-mocks@3.10.2.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/rspec-mocks@3.10.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/rspec-mocks@3.10.2.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/rspec-support@3.10.0.rbi b/Library/Homebrew/sorbet/rbi/gems/rspec-support@3.10.2.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/rspec-support@3.10.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/rspec-support@3.10.2.rbi diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.9.2.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.10.1.rbi similarity index 94% rename from Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.9.2.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.10.1.rbi index 98883cd1fa..e55e9889d6 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.9.2.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop-performance@1.10.1.rbi @@ -238,7 +238,7 @@ class RuboCop::Cop::Performance::ConstantRegexp < ::RuboCop::Cop::Base private def include_interpolated_const?(node); end - def within_const_assignment?(node); end + def within_allowed_assignment?(node); end end RuboCop::Cop::Performance::ConstantRegexp::MSG = T.let(T.unsafe(nil), String) @@ -482,6 +482,28 @@ RuboCop::Cop::Performance::RedundantBlockCall::SPACE = T.let(T.unsafe(nil), Stri RuboCop::Cop::Performance::RedundantBlockCall::YIELD = T.let(T.unsafe(nil), String) +class RuboCop::Cop::Performance::RedundantEqualityComparisonBlock < ::RuboCop::Cop::Base + extend(::RuboCop::Cop::AutoCorrector) + extend(::RuboCop::Cop::TargetRubyVersion) + + def on_block(node); end + + private + + def new_argument(block_argument, block_body); end + def offense_range(node); end + def same_block_argument_and_is_a_argument?(block_body, block_argument); end + def use_equality_comparison_block?(block_body); end +end + +RuboCop::Cop::Performance::RedundantEqualityComparisonBlock::COMPARISON_METHODS = T.let(T.unsafe(nil), Array) + +RuboCop::Cop::Performance::RedundantEqualityComparisonBlock::IS_A_METHODS = T.let(T.unsafe(nil), Array) + +RuboCop::Cop::Performance::RedundantEqualityComparisonBlock::MSG = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Performance::RedundantEqualityComparisonBlock::TARGET_METHODS = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Performance::RedundantMatch < ::RuboCop::Cop::Base extend(::RuboCop::Cop::AutoCorrector) @@ -561,6 +583,26 @@ end RuboCop::Cop::Performance::RedundantSortBlock::MSG = T.let(T.unsafe(nil), String) +class RuboCop::Cop::Performance::RedundantSplitRegexpArgument < ::RuboCop::Cop::Base + extend(::RuboCop::Cop::AutoCorrector) + + def on_send(node); end + def split_call_with_regexp?(param0 = T.unsafe(nil)); end + + private + + def determinist_regexp?(regexp_node); end + def replacement(regexp_node); end +end + +RuboCop::Cop::Performance::RedundantSplitRegexpArgument::DETERMINISTIC_REGEX = T.let(T.unsafe(nil), Regexp) + +RuboCop::Cop::Performance::RedundantSplitRegexpArgument::MSG = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Performance::RedundantSplitRegexpArgument::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) + +RuboCop::Cop::Performance::RedundantSplitRegexpArgument::STR_SPECIAL_CHARS = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Performance::RedundantStringChars < ::RuboCop::Cop::Base include(::RuboCop::Cop::RangeHelp) extend(::RuboCop::Cop::AutoCorrector) diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.5.1.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.6.1.rbi similarity index 81% rename from Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.5.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.6.1.rbi index 6fffaa4442..7494411ca6 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.5.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop-sorbet@0.6.1.rbi @@ -72,17 +72,20 @@ RuboCop::Cop::Sorbet::EnforceSigilOrder::MAGIC_REGEX = T.let(T.unsafe(nil), Rege RuboCop::Cop::Sorbet::EnforceSigilOrder::PREFERRED_ORDER = T.let(T.unsafe(nil), Hash) class RuboCop::Cop::Sorbet::EnforceSignatures < ::RuboCop::Cop::Sorbet::SignatureCop + def initialize(config = T.unsafe(nil), options = T.unsafe(nil)); end + def accessor?(param0 = T.unsafe(nil)); end def autocorrect(node); end + def on_block(node); end def on_def(node); end def on_defs(node); end def on_send(node); end + def scope(node); end private def check_node(node); end def param_type_placeholder; end - def previous_node(node); end def return_type_placeholder; end end @@ -90,9 +93,9 @@ class RuboCop::Cop::Sorbet::EnforceSignatures::SigSuggestion def initialize(indent, param_placeholder, return_placeholder); end def params; end - def params=(_); end + def params=(_arg0); end def returns; end - def returns=(_); end + def returns=(_arg0); end def to_autocorrect; end private @@ -105,13 +108,26 @@ class RuboCop::Cop::Sorbet::FalseSigil < ::RuboCop::Cop::Sorbet::HasSigil def minimum_strictness; end end +class RuboCop::Cop::Sorbet::ForbidExtendTSigHelpersInShims < ::RuboCop::Cop::Cop + include(::RuboCop::Cop::RangeHelp) + + def autocorrect(node); end + def extend_t_helpers?(param0 = T.unsafe(nil)); end + def extend_t_sig?(param0 = T.unsafe(nil)); end + def on_send(node); end +end + +RuboCop::Cop::Sorbet::ForbidExtendTSigHelpersInShims::MSG = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Sorbet::ForbidExtendTSigHelpersInShims::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Sorbet::ForbidIncludeConstLiteral < ::RuboCop::Cop::Cop - def initialize(*_); end + def initialize(*_arg0); end def not_lit_const_include?(param0 = T.unsafe(nil)); end def on_send(node); end def used_names; end - def used_names=(_); end + def used_names=(_arg0); end end RuboCop::Cop::Sorbet::ForbidIncludeConstLiteral::MSG = T.let(T.unsafe(nil), String) @@ -150,6 +166,22 @@ class RuboCop::Cop::Sorbet::KeywordArgumentOrdering < ::RuboCop::Cop::Sorbet::Si def check_order_for_kwoptargs(parameters); end end +class RuboCop::Cop::Sorbet::OneAncestorPerLine < ::RuboCop::Cop::Cop + def abstract?(param0); end + def autocorrect(node); end + def more_than_one_ancestor(param0 = T.unsafe(nil)); end + def on_class(node); end + def on_module(node); end + def requires_ancestors(param0); end + + private + + def new_ra_line(indent_count); end + def process_node(node); end +end + +RuboCop::Cop::Sorbet::OneAncestorPerLine::MSG = T.let(T.unsafe(nil), String) + class RuboCop::Cop::Sorbet::ParametersOrderingInSignature < ::RuboCop::Cop::Sorbet::SignatureCop def on_signature(node); end def signature_params(param0); end @@ -169,7 +201,7 @@ class RuboCop::Cop::Sorbet::SignatureBuildOrder < ::RuboCop::Cop::Sorbet::Signat def call_chain(sig_child_node); end def can_autocorrect?; end - def node_with_index_sends(node); end + def node_reparsed_with_modern_features(node); end end RuboCop::Cop::Sorbet::SignatureBuildOrder::ORDER = T.let(T.unsafe(nil), Hash) @@ -180,6 +212,19 @@ class RuboCop::Cop::Sorbet::SignatureCop < ::RuboCop::Cop::Cop def signature?(param0 = T.unsafe(nil)); end end +class RuboCop::Cop::Sorbet::SingleLineRbiClassModuleDefinitions < ::RuboCop::Cop::Cop + def autocorrect(node); end + def on_class(node); end + def on_module(node); end + + protected + + def convert_newlines(source); end + def process_node(node); end +end + +RuboCop::Cop::Sorbet::SingleLineRbiClassModuleDefinitions::MSG = T.let(T.unsafe(nil), String) + class RuboCop::Cop::Sorbet::StrictSigil < ::RuboCop::Cop::Sorbet::HasSigil def minimum_strictness; end end diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop@1.9.1.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop@1.11.0.rbi similarity index 99% rename from Library/Homebrew/sorbet/rbi/gems/rubocop@1.9.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop@1.11.0.rbi index fd3552670f..69c2cc7222 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop@1.9.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop@1.11.0.rbi @@ -1451,6 +1451,16 @@ RuboCop::Cop::FrozenStringLiteral::FROZEN_STRING_LITERAL_TYPES = T.let(T.unsafe( module RuboCop::Cop::Gemspec end +class RuboCop::Cop::Gemspec::DateAssignment < ::RuboCop::Cop::Base + include(::RuboCop::Cop::RangeHelp) + extend(::RuboCop::Cop::AutoCorrector) + + def gem_specification(param0 = T.unsafe(nil)); end + def on_block(block_node); end +end + +RuboCop::Cop::Gemspec::DateAssignment::MSG = T.let(T.unsafe(nil), String) + class RuboCop::Cop::Gemspec::DuplicatedAssignment < ::RuboCop::Cop::Base include(::RuboCop::Cop::RangeHelp) @@ -2562,6 +2572,7 @@ class RuboCop::Cop::Layout::FirstArgumentIndentation < ::RuboCop::Cop::Cop private def argument_alignment_config; end + def bare_operator?(node); end def base_indentation(node); end def base_range(send_node, arg_node); end def column_of(range); end @@ -4019,12 +4030,14 @@ end RuboCop::Cop::Lint::ConstantResolution::MSG = T.let(T.unsafe(nil), String) class RuboCop::Cop::Lint::Debugger < ::RuboCop::Cop::Base + def kernel?(param0 = T.unsafe(nil)); end def on_send(node); end + def valid_receiver?(param0 = T.unsafe(nil), param1); end private - def debugger_method?(name); end - def debugger_receiver?(node); end + def debugger_method?(send_node); end + def debugger_methods; end def message(node); end end @@ -4089,7 +4102,7 @@ class RuboCop::Cop::Lint::DeprecatedOpenSSLConstant < ::RuboCop::Cop::Base def algorithm_name(node); end def autocorrect(corrector, node); end - def build_cipher_arguments(node, algorithm_name); end + def build_cipher_arguments(node, algorithm_name, no_arguments); end def correction_range(node); end def message(node); end def openssl_class(node); end @@ -4099,6 +4112,8 @@ end RuboCop::Cop::Lint::DeprecatedOpenSSLConstant::MSG = T.let(T.unsafe(nil), String) +RuboCop::Cop::Lint::DeprecatedOpenSSLConstant::NO_ARG_ALGORITHM = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Lint::DisjunctiveAssignmentInConstructor < ::RuboCop::Cop::Base extend(::RuboCop::Cop::AutoCorrector) @@ -4208,9 +4223,9 @@ end RuboCop::Cop::Lint::DuplicateRequire::MSG = T.let(T.unsafe(nil), String) -RuboCop::Cop::Lint::DuplicateRequire::REQUIRE_METHODS = T.let(T.unsafe(nil), Array) +RuboCop::Cop::Lint::DuplicateRequire::REQUIRE_METHODS = T.let(T.unsafe(nil), Set) -RuboCop::Cop::Lint::DuplicateRequire::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) +RuboCop::Cop::Lint::DuplicateRequire::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Set) class RuboCop::Cop::Lint::DuplicateRescueException < ::RuboCop::Cop::Base include(::RuboCop::Cop::RescueNode) @@ -4687,6 +4702,8 @@ RuboCop::Cop::Lint::MultipleComparison::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Lint::MultipleComparison::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) +RuboCop::Cop::Lint::MultipleComparison::SET_OPERATION_OPERATORS = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Lint::NestedMethodDefinition < ::RuboCop::Cop::Base def class_or_module_or_struct_new_call?(param0 = T.unsafe(nil)); end def eval_call?(param0 = T.unsafe(nil)); end @@ -7765,8 +7782,10 @@ class RuboCop::Cop::Style::ConstantVisibility < ::RuboCop::Cop::Base private def class_or_module_scope?(node); end + def ignore_modules?; end def match_name?(name, constant_name); end def message(node); end + def module?(node); end def visibility_declaration?(node); end end @@ -8148,6 +8167,8 @@ RuboCop::Cop::Style::EndlessMethod::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Style::EndlessMethod::MSG_MULTI_LINE = T.let(T.unsafe(nil), String) class RuboCop::Cop::Style::EvalWithLocation < ::RuboCop::Cop::Base + extend(::RuboCop::Cop::AutoCorrector) + def line_with_offset?(param0 = T.unsafe(nil), param1, param2); end def on_send(node); end def valid_eval_receiver?(param0 = T.unsafe(nil)); end @@ -8155,15 +8176,22 @@ class RuboCop::Cop::Style::EvalWithLocation < ::RuboCop::Cop::Base private def add_offense_for_different_line(node, line_node, line_diff); end + def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff); end + def add_offense_for_missing_line(node, code); end + def add_offense_for_missing_location(node, code); end def add_offense_for_same_line(node, line_node); end def check_file(node, file_node); end def check_line(node, code); end + def check_location(node, code); end + def expected_line(sign, line_diff); end def file_and_line(node); end - def message_incorrect_line(method_name, actual, sign, line_diff); end - def register_offense(node); end + def line_difference(line_node, code); end + def missing_line(node, code); end + def register_offense(node, &block); end def special_file_keyword?(node); end def special_line_keyword?(node); end def string_first_line(str_node); end + def with_binding?(node); end def with_lineno?(node); end end @@ -8447,6 +8475,31 @@ class RuboCop::Cop::Style::HashAsLastArrayItem < ::RuboCop::Cop::Base def last_array_item?(array, node); end end +class RuboCop::Cop::Style::HashConversion < ::RuboCop::Cop::Base + extend(::RuboCop::Cop::AutoCorrector) + + def hash_from_array?(param0 = T.unsafe(nil)); end + def on_send(node); end + + private + + def allowed_splat_argument?; end + def args_to_hash(args); end + def multi_argument(node); end + def requires_parens?(node); end + def single_argument(node); end +end + +RuboCop::Cop::Style::HashConversion::MSG_LITERAL_HASH_ARG = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Style::HashConversion::MSG_LITERAL_MULTI_ARG = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Style::HashConversion::MSG_SPLAT = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Style::HashConversion::MSG_TO_H = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Style::HashConversion::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array) + class RuboCop::Cop::Style::HashEachMethods < ::RuboCop::Cop::Base include(::RuboCop::Cop::Lint::UnusedArgument) extend(::RuboCop::Cop::AutoCorrector) @@ -9245,7 +9298,9 @@ class RuboCop::Cop::Style::MultipleComparison < ::RuboCop::Cop::Base def comparison?(node); end def nested_comparison?(node); end def nested_variable_comparison?(node); end + def reset_comparison; end def root_of_or_node(or_node); end + def switch_comparison?(node); end def variable_name(node); end def variables_in_node(node); end def variables_in_simple_node(node); end @@ -9969,6 +10024,7 @@ class RuboCop::Cop::Style::RedundantBegin < ::RuboCop::Cop::Base private def contain_rescue_or_ensure?(node); end + def empty_begin?(node); end def register_offense(node); end def valid_context_using_only_begin?(node); end end @@ -10970,6 +11026,7 @@ class RuboCop::Cop::Style::SymbolProc < ::RuboCop::Cop::Base private + def allow_if_method_has_argument?(node); end def autocorrect(corrector, node); end def autocorrect_with_args(corrector, node, args, method_name); end def autocorrect_without_args(corrector, node); end @@ -11209,6 +11266,25 @@ end RuboCop::Cop::Style::UnlessElse::MSG = T.let(T.unsafe(nil), String) +class RuboCop::Cop::Style::UnlessLogicalOperators < ::RuboCop::Cop::Base + include(::RuboCop::Cop::ConfigurableEnforcedStyle) + + def and_with_or?(param0 = T.unsafe(nil)); end + def logical_operator?(param0 = T.unsafe(nil)); end + def on_if(node); end + def or_with_and?(param0 = T.unsafe(nil)); end + + private + + def mixed_logical_operator?(node); end + def mixed_precedence_and?(node); end + def mixed_precedence_or?(node); end +end + +RuboCop::Cop::Style::UnlessLogicalOperators::FORBID_LOGICAL_OPERATORS = T.let(T.unsafe(nil), String) + +RuboCop::Cop::Style::UnlessLogicalOperators::FORBID_MIXED_LOGICAL_OPERATORS = T.let(T.unsafe(nil), String) + class RuboCop::Cop::Style::UnpackFirst < ::RuboCop::Cop::Base extend(::RuboCop::Cop::AutoCorrector) @@ -12811,12 +12887,13 @@ class RuboCop::TargetRuby::GemspecFile < ::RuboCop::TargetRuby::Source private + def find_minimal_known_ruby(right_hand_side); end def find_version; end def gemspec_filename; end def gemspec_filepath; end def version_from_array(array); end def version_from_gemspec_file(file); end - def version_from_str(str); end + def version_from_right_hand_side(right_hand_side); end end RuboCop::TargetRuby::GemspecFile::GEMSPEC_EXTENSION = T.let(T.unsafe(nil), String) diff --git a/Library/Homebrew/sorbet/rbi/gems/spoom@1.0.7.rbi b/Library/Homebrew/sorbet/rbi/gems/spoom@1.0.9.rbi similarity index 91% rename from Library/Homebrew/sorbet/rbi/gems/spoom@1.0.7.rbi rename to Library/Homebrew/sorbet/rbi/gems/spoom@1.0.9.rbi index e436e13e91..52c85a0222 100644 --- a/Library/Homebrew/sorbet/rbi/gems/spoom@1.0.7.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/spoom@1.0.9.rbi @@ -5,6 +5,10 @@ # typed: true module Spoom + class << self + sig { params(cmd: String, arg: String, path: String, capture_err: T::Boolean).returns([String, T::Boolean]) } + def exec(cmd, *arg, path: T.unsafe(nil), capture_err: T.unsafe(nil)); end + end end module Spoom::Cli @@ -15,7 +19,10 @@ class Spoom::Cli::Bump < ::Thor sig { params(directory: String).void } def bump(directory = T.unsafe(nil)); end + def config_files(path: T.unsafe(nil)); end def help(command = T.unsafe(nil), subcommand = T.unsafe(nil)); end + def print_changes(files, command:, from: T.unsafe(nil), to: T.unsafe(nil), dry: T.unsafe(nil), path: T.unsafe(nil)); end + def undo_changes(files, from_strictness); end end class Spoom::Cli::Config < ::Thor @@ -43,22 +50,40 @@ Spoom::Cli::Coverage::DATA_DIR = T.let(T.unsafe(nil), String) module Spoom::Cli::Helper include(::Thor::Shell) + sig { params(string: String).returns(String) } + def blue(string); end sig { returns(T::Boolean) } def color?; end sig { params(string: String, color: Symbol).returns(String) } def colorize(string, color); end sig { returns(String) } def exec_path; end + sig { params(string: String).returns(String) } + def gray(string); end + sig { params(string: String).returns(String) } + def green(string); end + sig { params(string: String).returns(String) } + def highlight(string); end sig { void } def in_sorbet_project!; end sig { returns(T::Boolean) } def in_sorbet_project?; end - sig { params(message: String, status: String).void } - def say_error(message, status = T.unsafe(nil)); end - sig { returns(String) } + sig { params(string: String).returns(String) } + def red(string); end + sig { params(message: String).void } + def say(message); end + sig { params(message: String, status: T.nilable(String), nl: T::Boolean).void } + def say_error(message, status: T.unsafe(nil), nl: T.unsafe(nil)); end + sig { returns(Spoom::Sorbet::Config) } def sorbet_config; end + sig { returns(String) } + def sorbet_config_file; end + sig { params(string: String).returns(String) } + def yellow(string); end end +Spoom::Cli::Helper::HIGHLIGHT_COLOR = T.let(T.unsafe(nil), Symbol) + class Spoom::Cli::LSP < ::Thor include(::Spoom::Cli::Helper) @@ -97,22 +122,19 @@ end class Spoom::Cli::Run < ::Thor include(::Spoom::Cli::Helper) - def colorize_code(code, colors = T.unsafe(nil)); end - def colorize_message(message, colors = T.unsafe(nil)); end + def colorize_message(message); end + def format_error(error, format); end def help(command = T.unsafe(nil), subcommand = T.unsafe(nil)); end - def tc; end + def tc(*arg); end end -module Spoom::Config -end +Spoom::Cli::Run::DEFAULT_FORMAT = T.let(T.unsafe(nil), String) -Spoom::Config::SORBET_CONFIG = T.let(T.unsafe(nil), String) +Spoom::Cli::Run::SORT_CODE = T.let(T.unsafe(nil), String) -Spoom::Config::SORBET_GEM_PATH = T.let(T.unsafe(nil), String) +Spoom::Cli::Run::SORT_ENUM = T.let(T.unsafe(nil), Array) -Spoom::Config::SORBET_PATH = T.let(T.unsafe(nil), String) - -Spoom::Config::SPOOM_PATH = T.let(T.unsafe(nil), String) +Spoom::Cli::Run::SORT_LOC = T.let(T.unsafe(nil), String) module Spoom::Coverage class << self @@ -120,8 +142,10 @@ module Spoom::Coverage def report(snapshots, palette:, path: T.unsafe(nil)); end sig { params(path: String).returns(Spoom::FileTree) } def sigils_tree(path: T.unsafe(nil)); end - sig { params(path: String).returns(Spoom::Coverage::Snapshot) } - def snapshot(path: T.unsafe(nil)); end + sig { params(path: String, rbi: T::Boolean, sorbet_bin: T.nilable(String)).returns(Spoom::Coverage::Snapshot) } + def snapshot(path: T.unsafe(nil), rbi: T.unsafe(nil), sorbet_bin: T.unsafe(nil)); end + sig { params(path: String).returns(Spoom::Sorbet::Config) } + def sorbet_config(path: T.unsafe(nil)); end end end @@ -548,7 +572,7 @@ class Spoom::FileTree private - sig { params(node: Spoom::FileTree::Node, collected_nodes: T::Array[Spoom::FileTree::Node]).returns(T::Array[String]) } + sig { params(node: Spoom::FileTree::Node, collected_nodes: T::Array[Spoom::FileTree::Node]).returns(T::Array[Spoom::FileTree::Node]) } def collect_nodes(node, collected_nodes = T.unsafe(nil)); end end @@ -619,7 +643,7 @@ module Spoom::LSP end class Spoom::LSP::Client - def initialize(sorbet_cmd, *sorbet_args, path: T.unsafe(nil)); end + def initialize(sorbet_bin, *sorbet_args, path: T.unsafe(nil)); end def close; end def definitions(uri, line, column); end @@ -866,29 +890,39 @@ class Spoom::Printer def printt; end end +Spoom::SPOOM_PATH = T.let(T.unsafe(nil), String) + module Spoom::Sorbet class << self - sig { params(arg: String, path: String, capture_err: T::Boolean).returns([String, T::Boolean]) } - def srb(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil)); end + sig { params(arg: String, path: String, capture_err: T::Boolean, sorbet_bin: T.nilable(String)).returns([String, T::Boolean]) } + def srb(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil), sorbet_bin: T.unsafe(nil)); end sig { params(config: Spoom::Sorbet::Config, path: String).returns(T::Array[String]) } def srb_files(config, path: T.unsafe(nil)); end - sig { params(arg: String, path: String, capture_err: T::Boolean).returns(T.nilable(T::Hash[String, Integer])) } - def srb_metrics(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil)); end - sig { params(arg: String, path: String, capture_err: T::Boolean).returns([String, T::Boolean]) } - def srb_tc(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil)); end - sig { params(arg: String, path: String, capture_err: T::Boolean).returns(T.nilable(String)) } - def srb_version(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil)); end + sig { params(arg: String, path: String, capture_err: T::Boolean, sorbet_bin: T.nilable(String)).returns(T.nilable(T::Hash[String, Integer])) } + def srb_metrics(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil), sorbet_bin: T.unsafe(nil)); end + sig { params(arg: String, path: String, capture_err: T::Boolean, sorbet_bin: T.nilable(String)).returns([String, T::Boolean]) } + def srb_tc(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil), sorbet_bin: T.unsafe(nil)); end + sig { params(arg: String, path: String, capture_err: T::Boolean, sorbet_bin: T.nilable(String)).returns(T.nilable(String)) } + def srb_version(*arg, path: T.unsafe(nil), capture_err: T.unsafe(nil), sorbet_bin: T.unsafe(nil)); end sig { params(gem: String, path: String).returns(T.nilable(String)) } def version_from_gemfile_lock(gem: T.unsafe(nil), path: T.unsafe(nil)); end end end +Spoom::Sorbet::BIN_PATH = T.let(T.unsafe(nil), String) + +Spoom::Sorbet::CONFIG_PATH = T.let(T.unsafe(nil), String) + class Spoom::Sorbet::Config sig { void } def initialize; end def allowed_extensions; end + sig { returns(Spoom::Sorbet::Config) } + def copy; end def ignore; end + sig { returns(String) } + def options_string; end sig { returns(T::Array[String]) } def paths; end @@ -906,6 +940,10 @@ class Spoom::Sorbet::Config end module Spoom::Sorbet::Errors + class << self + sig { params(errors: T::Array[Spoom::Sorbet::Errors::Error]).returns(T::Array[Spoom::Sorbet::Errors::Error]) } + def sort_errors_by_code(errors); end + end end class Spoom::Sorbet::Errors::Error @@ -956,6 +994,8 @@ Spoom::Sorbet::Errors::Parser::ERROR_LINE_MATCH_REGEX = T.let(T.unsafe(nil), Reg Spoom::Sorbet::Errors::Parser::HEADER = T.let(T.unsafe(nil), Array) +Spoom::Sorbet::GEM_PATH = T.let(T.unsafe(nil), String) + module Spoom::Sorbet::MetricsParser class << self sig { params(path: String, prefix: String).returns(T::Hash[String, Integer]) } @@ -978,7 +1018,7 @@ module Spoom::Sorbet::Sigils sig { params(path: T.any(Pathname, String)).returns(T.nilable(String)) } def file_strictness(path); end sig { params(directory: T.any(Pathname, String), strictness: String, extension: String).returns(T::Array[String]) } - def files_with_sigil_strictness(directory, strictness, extension = T.unsafe(nil)); end + def files_with_sigil_strictness(directory, strictness, extension: T.unsafe(nil)); end sig { params(strictness: String).returns(String) } def sigil_string(strictness); end sig { params(content: String).returns(T.nilable(String)) } diff --git a/Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.13.rbi b/Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.17.rbi similarity index 96% rename from Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.13.rbi rename to Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.17.rbi index 005993524d..02ca0cc6a4 100644 --- a/Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.13.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/tapioca@0.4.17.rbi @@ -126,6 +126,8 @@ module Tapioca::Compilers::Sorbet end end +Tapioca::Compilers::Sorbet::EXE_PATH_ENV_VAR = T.let(T.unsafe(nil), String) + Tapioca::Compilers::Sorbet::SORBET = T.let(T.unsafe(nil), Pathname) module Tapioca::Compilers::SymbolTable @@ -162,6 +164,8 @@ class Tapioca::Compilers::SymbolTable::SymbolGenerator def compile_constant(name, constant); end sig { params(module_name: String, mod: Module, for_visibility: T::Array[Symbol]).returns(String) } def compile_directly_owned_methods(module_name, mod, for_visibility = T.unsafe(nil)); end + sig { params(constant: Module).returns(String) } + def compile_enums(constant); end sig { params(symbol_name: String, constant: Module, method: T.nilable(UnboundMethod)).returns(T.nilable(String)) } def compile_method(symbol_name, constant, method); end sig { params(name: String, constant: Module).returns(T.nilable(String)) } @@ -362,23 +366,27 @@ class Tapioca::Gemfile sig { void } def initialize; end + sig { returns(Bundler::Definition) } + def definition; end sig { returns(T::Array[Tapioca::Gemfile::Gem]) } def dependencies; end sig { params(gem_name: String).returns(T.nilable(Tapioca::Gemfile::Gem)) } def gem(gem_name); end + sig { returns(T::Array[String]) } + def missing_specs; end sig { void } def require; end private - sig { returns(Bundler::Definition) } - def definition; end sig { returns(String) } def dir; end sig { returns(File) } def gemfile; end sig { returns(T::Array[Symbol]) } def groups; end + sig { returns([T::Array[Tapioca::Gemfile::Gem], T::Array[String]]) } + def load_dependencies; end def lockfile; end sig { returns(Bundler::Runtime) } def runtime; end @@ -445,7 +453,7 @@ class Tapioca::Generator < ::Thor::Shell::Color def added_rbis; end sig { returns(Tapioca::Gemfile) } def bundle; end - sig { params(constant: Module, contents: String).void } + sig { params(constant: Module, contents: String).returns(T.nilable(Pathname)) } def compile_dsl_rbi(constant, contents); end sig { params(gem: Tapioca::Gemfile::Gem).void } def compile_gem_rbi(gem); end @@ -453,8 +461,12 @@ class Tapioca::Generator < ::Thor::Shell::Color def compiler; end sig { params(constant_names: T::Array[String]).returns(T::Array[Module]) } def constantize(constant_names); end + sig { params(constant_name: String).returns(Pathname) } + def dsl_rbi_filename(constant_name); end sig { params(gem_name: String).returns(Pathname) } def existing_rbi(gem_name); end + sig { params(requested_constants: T::Array[String]).returns(T::Set[Pathname]) } + def existing_rbi_filenames(requested_constants); end sig { returns(T::Hash[String, String]) } def existing_rbis; end sig { params(gem_name: String).returns(Pathname) } diff --git a/Library/Homebrew/sorbet/rbi/gems/thor@1.0.1.rbi b/Library/Homebrew/sorbet/rbi/gems/thor@1.1.0.rbi similarity index 97% rename from Library/Homebrew/sorbet/rbi/gems/thor@1.0.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/thor@1.1.0.rbi index a623054e22..392c72ab72 100644 --- a/Library/Homebrew/sorbet/rbi/gems/thor@1.0.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/thor@1.1.0.rbi @@ -1,6 +1,6 @@ # DO NOT EDIT MANUALLY # This is an autogenerated file for types exported from the `thor` gem. -# Please instead update this file by running `tapioca generate --exclude json`. +# Please instead update this file by running `tapioca sync`. # typed: true @@ -77,7 +77,7 @@ module Thor::Actions def append_to_file(path, *args, &block); end def apply(path, config = T.unsafe(nil)); end def behavior; end - def behavior=(_); end + def behavior=(_arg0); end def chmod(path, mode, config = T.unsafe(nil)); end def comment_lines(path, flag, *args); end def copy_file(source, *args, &block); end @@ -119,7 +119,7 @@ module Thor::Actions def capture(*args); end def concat(string); end def output_buffer; end - def output_buffer=(_); end + def output_buffer=(_arg0); end def with_output_buffer(buf = T.unsafe(nil)); end class << self @@ -280,17 +280,17 @@ module Thor::Base def initialize(args = T.unsafe(nil), local_options = T.unsafe(nil), config = T.unsafe(nil)); end def args; end - def args=(_); end + def args=(_arg0); end def options; end - def options=(_); end + def options=(_arg0); end def parent_options; end - def parent_options=(_); end + def parent_options=(_arg0); end class << self def included(base); end def register_klass_file(klass); end def shell; end - def shell=(_); end + def shell=(_arg0); end def subclass_files; end def subclasses; end end @@ -302,9 +302,9 @@ module Thor::Base::ClassMethods def allow_incompatible_default_type!; end def argument(name, options = T.unsafe(nil)); end def arguments; end - def attr_accessor(*_); end - def attr_reader(*_); end - def attr_writer(*_); end + def attr_accessor(*_arg0); end + def attr_reader(*_arg0); end + def attr_writer(*_arg0); end def check_default_type; end def check_default_type!; end def check_unknown_options; end @@ -443,8 +443,8 @@ class Thor::Group def invocations; end def invoke(*names, &block); end def invoke_from_option(*names, &block); end - def printable_commands(*_); end - def printable_tasks(*_); end + def printable_commands(*_arg0); end + def printable_tasks(*_arg0); end def remove_invocation(*names); end protected @@ -660,7 +660,7 @@ module Thor::Shell def say_status(*args, &block); end def set_color(*args, &block); end def shell; end - def shell=(_); end + def shell=(_arg0); end def terminal_width(*args, &block); end def with_padding; end def yes?(*args, &block); end @@ -675,7 +675,7 @@ class Thor::Shell::Basic def ask(statement, *args); end def base; end - def base=(_); end + def base=(_arg0); end def error(statement); end def file_collision(destination); end def indent(count = T.unsafe(nil)); end @@ -689,7 +689,7 @@ class Thor::Shell::Basic def print_wrapped(message, options = T.unsafe(nil)); end def say(message = T.unsafe(nil), color = T.unsafe(nil), force_new_line = T.unsafe(nil)); end def say_status(status, message, log_status = T.unsafe(nil)); end - def set_color(string, *_); end + def set_color(string, *_arg1); end def terminal_width; end def yes?(statement, color = T.unsafe(nil)); end @@ -726,6 +726,7 @@ class Thor::Shell::Color < ::Thor::Shell::Basic protected def are_colors_disabled?; end + def are_colors_supported?; end def can_display_colors?; end def diff_lcs_loaded?; end def output_diff_line(diff); end diff --git a/Library/Homebrew/sorbet/rbi/gems/warning@1.2.0.rbi b/Library/Homebrew/sorbet/rbi/gems/warning@1.2.0.rbi new file mode 100644 index 0000000000..e75b6f9072 --- /dev/null +++ b/Library/Homebrew/sorbet/rbi/gems/warning@1.2.0.rbi @@ -0,0 +1,8 @@ +# DO NOT EDIT MANUALLY +# This is an autogenerated file for types exported from the `warning` gem. +# Please instead update this file by running `tapioca sync`. + +# typed: true + +# THIS IS AN EMPTY RBI FILE. +# see https://github.com/Shopify/tapioca/blob/master/README.md#manual-gem-requires diff --git a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi index da74c99c25..fcef5a6ace 100644 --- a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi +++ b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi @@ -2689,6 +2689,11 @@ class Addrinfo def connect_internal(local_addrinfo, timeout=T.unsafe(nil)); end end +class Archive + extend ::T::Private::Methods::MethodHooks + extend ::T::Private::Methods::SingletonMethodHooks +end + class Array include ::MessagePack::CoreExt def compact_blank!(); end @@ -7886,6 +7891,11 @@ end module GetText end +module GitHub::API + extend ::T::Private::Methods::MethodHooks + extend ::T::Private::Methods::SingletonMethodHooks +end + class GitHub::Actions::Annotation extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::SingletonMethodHooks @@ -7896,7 +7906,12 @@ module GitHub::Actions extend ::T::Private::Methods::SingletonMethodHooks end -module GitHub +class GitHubPackages + extend ::T::Private::Methods::MethodHooks + extend ::T::Private::Methods::SingletonMethodHooks +end + +class GitHubReleases extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::SingletonMethodHooks end @@ -7966,6 +7981,49 @@ module Homebrew MIN_PORT = ::T.let(nil, ::T.untyped) end +module Homebrew::Assertions + include ::Minitest::Assertions + def assert_include(*args); end + + def assert_no_match(*args); end + + def assert_not_empty(*args); end + + def assert_not_equal(*args); end + + def assert_not_in_delta(*args); end + + def assert_not_in_epsilon(*args); end + + def assert_not_include(*args); end + + def assert_not_includes(*args); end + + def assert_not_instance_of(*args); end + + def assert_not_kind_of(*args); end + + def assert_not_match(*args); end + + def assert_not_nil(*args); end + + def assert_not_operator(*args); end + + def assert_not_predicate(*args); end + + def assert_not_respond_to(*args); end + + def assert_not_same(*args); end + + def assert_path_exist(*args); end + + def assert_path_not_exist(*args); end + + def assert_raise(*args); end + + def assert_throw(*args); end +end + class Homebrew::BundleVersion extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::SingletonMethodHooks @@ -8066,12 +8124,18 @@ module Homebrew::EnvConfig def self.github_api_token(); end + def self.github_packages_token(); end + + def self.github_packages_user(); end + def self.http_proxy(); end def self.https_proxy(); end def self.install_badge(); end + def self.internet_archive_key(); end + def self.livecheck_watchlist(); end def self.logs(); end @@ -8082,8 +8146,6 @@ module Homebrew::EnvConfig def self.no_bootsnap?(); end - def self.no_bottle_source_fallback?(); end - def self.no_color?(); end def self.no_compat?(); end @@ -8102,6 +8164,8 @@ module Homebrew::EnvConfig def self.pry?(); end + def self.simulate_macos_on_linux?(); end + def self.skip_or_later_bottles?(); end def self.sorbet_runtime?(); end @@ -12479,9 +12543,9 @@ class Object HOMEBREW_PRODUCT = ::T.let(nil, ::T.untyped) HOMEBREW_PULL_API_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_PULL_OR_COMMIT_URL_REGEX = ::T.let(nil, ::T.untyped) - HOMEBREW_RELEASES_URL_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_REPOSITORY = ::T.let(nil, ::T.untyped) HOMEBREW_REQUIRED_RUBY_VERSION = ::T.let(nil, ::T.untyped) + HOMEBREW_RUBY_EXEC_ARGS = ::T.let(nil, ::T.untyped) HOMEBREW_SHIMS_PATH = ::T.let(nil, ::T.untyped) HOMEBREW_TAP_CASK_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_TAP_DIR_REGEX = ::T.let(nil, ::T.untyped) @@ -12702,7 +12766,6 @@ end module ParallelTests RUBY_BINARY = ::T.let(nil, ::T.untyped) VERSION = ::T.let(nil, ::T.untyped) - Version = ::T.let(nil, ::T.untyped) WINDOWS = ::T.let(nil, ::T.untyped) end @@ -14025,8 +14088,6 @@ class Pry::CLI def self.add_options(&block); end - def self.add_plugin_options(); end - def self.input_args(); end def self.input_args=(input_args); end @@ -15312,10 +15373,6 @@ class Pry::Config def should_load_local_rc=(should_load_local_rc); end - def should_load_plugins(); end - - def should_load_plugins=(should_load_plugins); end - def should_load_rc(); end def should_load_rc=(should_load_rc); end @@ -16445,66 +16502,6 @@ end class Pry::Pager end -class Pry::PluginManager - def load_plugins(); end - - def locate_plugins(); end - - def plugins(); end - PRY_PLUGIN_PREFIX = ::T.let(nil, ::T.untyped) -end - -class Pry::PluginManager::NoPlugin - def initialize(name); end -end - -class Pry::PluginManager::NoPlugin -end - -class Pry::PluginManager::Plugin - def activate!(); end - - def active(); end - - def active=(active); end - - def active?(); end - - def disable!(); end - - def enable!(); end - - def enabled(); end - - def enabled=(enabled); end - - def enabled?(); end - - def gem_name(); end - - def gem_name=(gem_name); end - - def initialize(name, gem_name, spec, enabled); end - - def load_cli_options(); end - - def name(); end - - def name=(name); end - - def spec(); end - - def spec=(spec); end - - def supported?(); end -end - -class Pry::PluginManager::Plugin -end - -class Pry::PluginManager -end - class Pry::Prompt def [](key); end @@ -16743,30 +16740,18 @@ end class Pry::Slop::Option def accepts_optional_argument?(); end - def argument?(); end - def argument_in_value(); end def argument_in_value=(argument_in_value); end - def as?(); end - - def autocreated?(); end - def call(*objects); end - def callback?(); end - def config(); end def count(); end def count=(count); end - def default?(); end - - def delimiter?(); end - def description(); end def expects_argument?(); end @@ -16777,22 +16762,10 @@ class Pry::Slop::Option def key(); end - def limit?(); end - def long(); end - def match?(); end - - def optional?(); end - - def optional_argument?(); end - - def required?(); end - def short(); end - def tail?(); end - def types(); end def value(); end @@ -17040,8 +17013,6 @@ class Pry def self.load_history(); end - def self.load_plugins(*args, &block); end - def self.load_rc_files(); end def self.load_requires(); end @@ -17050,8 +17021,6 @@ class Pry def self.load_win32console(); end - def self.locate_plugins(*args, &block); end - def self.main(); end def self.memory_size(*args, &block); end @@ -17066,8 +17035,6 @@ class Pry def self.pager=(*args, &block); end - def self.plugins(*args, &block); end - def self.print(*args, &block); end def self.print=(*args, &block); end @@ -23420,6 +23387,8 @@ class RSpec::Mocks::Proxy def check_for_unexpected_arguments(expectation); end + def ensure_can_be_proxied!(object); end + def ensure_implemented(*_args); end def has_negative_expectation?(message); end @@ -26864,11 +26833,6 @@ class RuboCop::Cop::FormulaCop def required_dependency_name?(param0, param1); end end -class RuboCop::Cop::Style::UnlessMultipleConditions - extend ::T::Private::Methods::MethodHooks - extend ::T::Private::Methods::SingletonMethodHooks -end - module RuboCop::RSpec::ExpectOffense def expect_correction(correction, loop: T.unsafe(nil), source: T.unsafe(nil)); end @@ -29046,6 +29010,12 @@ class Spoom::Sorbet::Errors::Parser extend ::T::Private::Methods::SingletonMethodHooks end +module Spoom::Sorbet::Errors + extend ::T::Sig + extend ::T::Private::Methods::MethodHooks + extend ::T::Private::Methods::SingletonMethodHooks +end + module Spoom::Sorbet::MetricsParser extend ::T::Sig extend ::T::Private::Methods::MethodHooks @@ -29059,12 +29029,16 @@ module Spoom::Sorbet::Sigils end module Spoom::Sorbet + extend ::T::Private::Methods::SingletonMethodHooks +end + +class Spoom::Timeline extend ::T::Sig extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::SingletonMethodHooks end -class Spoom::Timeline +module Spoom extend ::T::Sig extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::SingletonMethodHooks @@ -29937,8 +29911,27 @@ class WEBrick::HTTPServlet::FileHandler def set_filesystem_encoding(str); end end +module Warning::Processor + def clear(); end + + def dedup(); end + + def freeze(); end + + def ignore(regexp, path=T.unsafe(nil)); end + + def process(path=T.unsafe(nil), actions=T.unsafe(nil), &block); end + + def warn(str); end + IGNORE_MAP = ::T.let(nil, ::T.untyped) +end + +module Warning::Processor +end + module Warning extend ::Warning + extend ::Warning::Processor end class WeakRef diff --git a/Library/Homebrew/sorbet/rbi/todo.rbi b/Library/Homebrew/sorbet/rbi/todo.rbi index 6911cdc379..9257c3b689 100644 --- a/Library/Homebrew/sorbet/rbi/todo.rbi +++ b/Library/Homebrew/sorbet/rbi/todo.rbi @@ -9,5 +9,3 @@ module T::InterfaceWrapper::Helpers; end module T::Private::Abstract::Hooks; end module T::Private::Methods::MethodHooks; end module T::Private::Methods::SingletonMethodHooks; end -module Test::Unit::AssertionFailedError; end -module Test::Unit::Assertions; end diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index 4e3b80942f..7511754fdb 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -72,11 +72,19 @@ module Homebrew end end + RUBOCOP = (HOMEBREW_LIBRARY_PATH/"utils/rubocop.rb").freeze + def run_rubocop(files, output_type, fix: false, except_cops: nil, only_cops: nil, display_cop_names: false, reset_cache: false, debug: false, verbose: false) Homebrew.install_bundler_gems! - require "rubocop" + + require "warnings" + + Warnings.ignore :parser_syntax do + require "rubocop" + end + require "rubocops" args = %w[ @@ -134,11 +142,6 @@ module Homebrew FileUtils.rm_rf cache_env["XDG_CACHE_HOME"] if reset_cache - ruby_args = [ - "-S", - "rubocop", - ].compact.freeze - case output_type when :print args << "--debug" if debug @@ -149,11 +152,11 @@ module Homebrew args << "--color" if Tty.color? - system cache_env, RUBY_PATH, *ruby_args, *args + system cache_env, RUBY_PATH, RUBOCOP, *args $CHILD_STATUS.success? when :json result = system_command RUBY_PATH, - args: [*ruby_args, "--format", "json", *args], + args: [RUBOCOP, "--format", "json", *args], env: cache_env json = json_result!(result) json["files"] diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 7d049c0c62..952564ffb6 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -10,13 +10,15 @@ require "extend/io" require "extend/predicable" require "extend/hash_validator" +require "extend/time" + # Class for running sub-processes and capturing their output and exit status. # # @api private class SystemCommand extend T::Sig - using HashValidator + using TimeRemaining # Helper functions for calling {SystemCommand.run}. module Mixin @@ -78,10 +80,24 @@ class SystemCommand verbose: T.nilable(T::Boolean), secrets: T.any(String, T::Array[String]), chdir: T.any(String, Pathname), + timeout: T.nilable(T.any(Integer, Float)), ).void } - def initialize(executable, args: [], sudo: false, env: {}, input: [], must_succeed: false, - print_stdout: false, print_stderr: true, debug: nil, verbose: nil, secrets: [], chdir: T.unsafe(nil)) + def initialize( + executable, + args: [], + sudo: false, + env: {}, + input: [], + must_succeed: false, + print_stdout: false, + print_stderr: true, + debug: nil, + verbose: false, + secrets: [], + chdir: T.unsafe(nil), + timeout: nil + ) require "extend/ENV" @executable = executable @args = args @@ -100,6 +116,7 @@ class SystemCommand @verbose = verbose @secrets = (Array(secrets) + ENV.sensitive_environment.values).uniq @chdir = chdir + @timeout = timeout end sig { returns(T::Array[String]) } @@ -197,10 +214,14 @@ class SystemCommand sig { params(sources: T::Array[IO], _block: T.proc.params(type: Symbol, line: String).void).void } def each_line_from(sources, &_block) - loop do - readable_sources, = IO.select(sources) + end_time = Time.now + @timeout if @timeout - readable_sources = T.must(readable_sources).reject(&:eof?) + loop do + select_timeout = end_time&.remaining! + readable_sources, = IO.select(sources, [], [], select_timeout) + raise Timeout::Error if readable_sources.nil? + + readable_sources = readable_sources.reject(&:eof?) break if readable_sources.empty? diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 29c1e7d511..3175ad447f 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -29,7 +29,7 @@ class Tab < OpenStruct "tabfile" => formula.prefix/FILENAME, "built_as_bottle" => build.bottle?, "installed_as_dependency" => false, - "installed_on_request" => true, + "installed_on_request" => false, "poured_from_bottle" => false, "time" => Time.now.to_i, "source_modified_time" => formula.source_modified_time.to_i, @@ -184,7 +184,7 @@ class Tab < OpenStruct "unused_options" => [], "built_as_bottle" => false, "installed_as_dependency" => false, - "installed_on_request" => true, + "installed_on_request" => false, "poured_from_bottle" => false, "time" => nil, "source_modified_time" => 0, diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index f6a5a1bf80..ea4b535a03 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -170,13 +170,6 @@ class Tap path.git_head end - # git HEAD in short format for this {Tap}. - def git_short_head - raise TapUnavailableError, name unless installed? - - path.git_short_head(length: 4) - end - # Time since last git commit for this {Tap}. def git_last_commit raise TapUnavailableError, name unless installed? @@ -184,13 +177,6 @@ class Tap path.git_last_commit end - # Last git commit date for this {Tap}. - def git_last_commit_date - raise TapUnavailableError, name unless installed? - - path.git_last_commit_date - end - # The issues URL of this {Tap}. # e.g. `https://github.com/user/homebrew-repo/issues` sig { returns(T.nilable(String)) } @@ -204,16 +190,6 @@ class Tap name end - sig { returns(String) } - def version_string - return "N/A" unless installed? - - pretty_revision = git_short_head - return "(no Git repository)" unless pretty_revision - - "(git revision #{pretty_revision}; last commit #{git_last_commit_date})" - end - # True if this {Tap} is an official Homebrew tap. def official? user == "Homebrew" @@ -692,9 +668,9 @@ class Tap else GitHub.private_repo?(full_name) end - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError true - rescue GitHub::Error + rescue GitHub::API::Error false end end diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index 72f373c8bb..d560da83db 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -3,7 +3,7 @@ old_trap = trap("INT") { exit! 130 } -require "global" +require_relative "global" require "extend/ENV" require "timeout" require "debrew" diff --git a/Library/Homebrew/test/archive_spec.rb b/Library/Homebrew/test/archive_spec.rb new file mode 100644 index 0000000000..877aa7e630 --- /dev/null +++ b/Library/Homebrew/test/archive_spec.rb @@ -0,0 +1,20 @@ +# typed: false +# frozen_string_literal: true + +require "archive" + +describe Archive, :needs_network do + subject(:archive) { described_class.new(item: "homebrew") } + + describe "::remote_checksum" do + it "detects a published file" do + hash = archive.remote_md5(directory: ".", remote_file: "cmake-3.1.2.yosemite.bottle.tar.gz") + expect(hash).to eq("c6e525d472124670b0b635800488f438") + end + + it "fails on a non-existent file" do + hash = archive.remote_md5(directory: "bottles", remote_file: "my-fake-bottle-1.0.snow_hyena.tar.gz") + expect(hash).to be nil + end + end +end diff --git a/Library/Homebrew/test/bash_spec.rb b/Library/Homebrew/test/bash_spec.rb index 178db5777a..07ba4cd7cb 100644 --- a/Library/Homebrew/test/bash_spec.rb +++ b/Library/Homebrew/test/bash_spec.rb @@ -18,13 +18,13 @@ describe "Bash" do end end - context "brew" do + describe "brew" do subject { HOMEBREW_LIBRARY_PATH.parent.parent/"bin/brew" } it { is_expected.to have_valid_bash_syntax } end - context "every `.sh` file" do + describe "every `.sh` file" do it "has valid Bash syntax" do Pathname.glob("#{HOMEBREW_LIBRARY_PATH}/**/*.sh").each do |path| relative_path = path.relative_path_from(HOMEBREW_LIBRARY_PATH) @@ -35,13 +35,13 @@ describe "Bash" do end end - context "Bash completion" do + describe "Bash completion" do subject { HOMEBREW_LIBRARY_PATH.parent.parent/"completions/bash/brew" } it { is_expected.to have_valid_bash_syntax } end - context "every shim script" do + describe "every shim script" do it "has valid Bash syntax" do # These have no file extension, but can be identified by their shebang. (HOMEBREW_LIBRARY_PATH/"shims").find do |path| diff --git a/Library/Homebrew/test/build_environment_spec.rb b/Library/Homebrew/test/build_environment_spec.rb index 0e874c31fb..2b19b5155e 100644 --- a/Library/Homebrew/test/build_environment_spec.rb +++ b/Library/Homebrew/test/build_environment_spec.rb @@ -45,7 +45,7 @@ describe BuildEnvironment do describe BuildEnvironment::DSL do subject(:build_environment_dsl) { double.extend(described_class) } - context "single argument" do + context "with a single argument" do before do build_environment_dsl.instance_eval do env :userpaths @@ -55,7 +55,7 @@ describe BuildEnvironment do its(:env) { is_expected.to use_userpaths } end - context "multiple arguments" do + context "with multiple arguments" do before do build_environment_dsl.instance_eval do env :userpaths, :std diff --git a/Library/Homebrew/test/cache_store_spec.rb b/Library/Homebrew/test/cache_store_spec.rb index 78acf07751..9503d8817a 100644 --- a/Library/Homebrew/test/cache_store_spec.rb +++ b/Library/Homebrew/test/cache_store_spec.rb @@ -32,7 +32,7 @@ describe CacheStoreDatabase do end describe "#get" do - context "database created" do + context "with a database created" do let(:db) { double("db", :[] => "bar") } it "gets value in the `CacheStoreDatabase` corresponding to the key" do @@ -44,7 +44,7 @@ describe CacheStoreDatabase do end end - context "database not created" do + context "without a database created" do let(:db) { double("db", :[] => nil) } before do @@ -64,7 +64,7 @@ describe CacheStoreDatabase do end describe "#delete" do - context "database created" do + context "with a database created" do let(:db) { double("db", :[] => { foo: "bar" }) } before do @@ -78,7 +78,7 @@ describe CacheStoreDatabase do end end - context "database not created" do + context "without a database created" do let(:db) { double("db", delete: nil) } before do @@ -94,13 +94,13 @@ describe CacheStoreDatabase do end describe "#write_if_dirty!" do - context "database open" do + context "with an open database" do it "does not raise an error when `close` is called on the database" do expect { sample_db.write_if_dirty! }.not_to raise_error(NoMethodError) end end - context "database not open" do + context "without an open database" do before do sample_db.instance_variable_set(:@db, nil) end @@ -118,7 +118,7 @@ describe CacheStoreDatabase do allow(sample_db).to receive(:cache_path).and_return(cache_path) end - context "`cache_path.exist?` returns `true`" do + context "when `cache_path.exist?` returns `true`" do before do allow(cache_path).to receive(:exist?).and_return(true) end @@ -128,7 +128,7 @@ describe CacheStoreDatabase do end end - context "`cache_path.exist?` returns `false`" do + context "when `cache_path.exist?` returns `false`" do before do allow(cache_path).to receive(:exist?).and_return(false) end diff --git a/Library/Homebrew/test/cask/artifact/binary_spec.rb b/Library/Homebrew/test/cask/artifact/binary_spec.rb index 149eea835f..ba54834ab8 100644 --- a/Library/Homebrew/test/cask/artifact/binary_spec.rb +++ b/Library/Homebrew/test/cask/artifact/binary_spec.rb @@ -96,7 +96,7 @@ describe Cask::Artifact::Binary, :cask do expect(expected_path.exist?).to be true end - context "binary is inside an app package" do + context "when the binary is inside an app package" do let(:cask) { Cask::CaskLoader.load(cask_path("with-embedded-binary")).tap do |cask| InstallHelper.install_without_artifacts(cask) diff --git a/Library/Homebrew/test/cask/artifact/uninstall_spec.rb b/Library/Homebrew/test/cask/artifact/uninstall_spec.rb index 7ce9297f4c..de09f6f850 100644 --- a/Library/Homebrew/test/cask/artifact/uninstall_spec.rb +++ b/Library/Homebrew/test/cask/artifact/uninstall_spec.rb @@ -11,7 +11,7 @@ describe Cask::Artifact::Uninstall, :cask do describe "#post_uninstall_phase" do subject(:artifact) { cask.artifacts.find { |a| a.is_a?(described_class) } } - context "using :rmdir" do + context "when using :rmdir" do let(:fake_system_command) { NeverSudoSystemCommand } let(:cask) { Cask::CaskLoader.load(cask_path("with-uninstall-rmdir")) } let(:empty_directory) { Pathname.new("#{TEST_TMPDIR}/empty_directory_path") } diff --git a/Library/Homebrew/test/cask/artifact/zap_spec.rb b/Library/Homebrew/test/cask/artifact/zap_spec.rb index 1013d9fd44..2d7387727b 100644 --- a/Library/Homebrew/test/cask/artifact/zap_spec.rb +++ b/Library/Homebrew/test/cask/artifact/zap_spec.rb @@ -7,7 +7,7 @@ describe Cask::Artifact::Zap, :cask do describe "#zap_phase" do include_examples "#uninstall_phase or #zap_phase" - context "using :rmdir" do + context "when using :rmdir" do subject(:artifact) { cask.artifacts.find { |a| a.is_a?(described_class) } } let(:fake_system_command) { NeverSudoSystemCommand } diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index 4896353fea..4e0feb6635 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -315,7 +315,7 @@ describe Cask::Audit, :cask do end end - context "when cask token is in tap_migrations.json" do + context "when cask token is in tap_migrations.json and" do let(:cask_token) { "token-migrated" } let(:tap) { Tap.fetch("homebrew/cask") } @@ -324,7 +324,7 @@ describe Cask::Audit, :cask do allow(cask).to receive(:tap).and_return(tap) end - context "and `new_cask` is true" do + context "when `new_cask` is true" do let(:new_cask) { true } it "fails" do @@ -332,7 +332,7 @@ describe Cask::Audit, :cask do end end - context "and `new_cask` is false" do + context "when `new_cask` is false" do let(:new_cask) { false } it "does not fail" do @@ -688,14 +688,14 @@ describe Cask::Audit, :cask do it { is_expected.to pass } end - context "when the Cask is on the denylist" do - context "and it's in the official Homebrew tap" do + context "when the Cask is on the denylist and" do + context "when it's in the official Homebrew tap" do let(:cask_token) { "adobe-illustrator" } it { is_expected.to fail_with(/#{cask_token} is not allowed: \w+/) } end - context "and it isn't in the official Homebrew tap" do + context "when it isn't in the official Homebrew tap" do let(:cask_token) { "pharo" } it { is_expected.to pass } @@ -786,7 +786,7 @@ describe Cask::Audit, :cask do end describe "url checks" do - context "given a block" do + context "with a block" do let(:cask_token) { "booby-trap" } context "when loading the cask" do @@ -981,5 +981,54 @@ describe Cask::Audit, :cask do it { is_expected.to fail_with(/a homepage stanza is required/) } end + + context "when url is lazy" do + let(:strict) { true } + let(:cask_token) { "with-lazy" } + let(:cask) do + tmp_cask cask_token.to_s, <<~RUBY + cask '#{cask_token}' do + version '1.8.0_72,8.13.0.5' + sha256 '8dd95daa037ac02455435446ec7bc737b34567afe9156af7d20b2a83805c1d8a' + url do + ['https://brew.sh/foo.zip', {referer: 'https://example.com', cookies: {'foo' => 'bar'}}] + end + name 'Audit' + desc 'Audit Description' + homepage 'https://brew.sh' + app 'Audit.app' + end + RUBY + end + + it { is_expected.to pass } + + it "receives a referer" do + expect(audit.cask.url.referer).to eq "https://example.com" + end + + it "receives cookies" do + expect(audit.cask.url.cookies).to eq "foo" => "bar" + end + end + + context "when the version contains a slash" do + let(:cask_token) { "foo" } + let(:cask) do + tmp_cask cask_token.to_s, <<~RUBY + cask '#{cask_token}' do + version '0.1,../../directory/traversal' + sha256 '8dd95daa037ac02455435446ec7bc737b34567afe9156af7d20b2a83805c1d8a' + url 'https://brew.sh/foo.zip' + name 'Audit' + desc 'Audit Description' + homepage 'https://brew.sh' + app 'Audit.app' + end + RUBY + end + + it { is_expected.to fail_with(%r{version should not contain '/'}) } + end end end diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb index 2072dff887..50298bbb28 100644 --- a/Library/Homebrew/test/cask/cask_spec.rb +++ b/Library/Homebrew/test/cask/cask_spec.rb @@ -6,19 +6,19 @@ describe Cask::Cask, :cask do context "when multiple versions are installed" do describe "#versions" do - context "and there are duplicate versions" do + context "when there are duplicate versions" do it "uses the last unique version" do allow(cask).to receive(:timestamped_versions).and_return([ - ["1.2.2", "0999"], - ["1.2.3", "1000"], - ["1.2.2", "1001"], - ]) + ["1.2.2", "0999"], + ["1.2.3", "1000"], + ["1.2.2", "1001"], + ]) expect(cask).to receive(:timestamped_versions) expect(cask.versions).to eq([ - "1.2.3", - "1.2.2", - ]) + "1.2.3", + "1.2.2", + ]) end end end diff --git a/Library/Homebrew/test/cask/cmd/upgrade_spec.rb b/Library/Homebrew/test/cask/cmd/upgrade_spec.rb index 2db6976522..70cdd4c510 100644 --- a/Library/Homebrew/test/cask/cmd/upgrade_spec.rb +++ b/Library/Homebrew/test/cask/cmd/upgrade_spec.rb @@ -12,7 +12,7 @@ describe Cask::Cmd::Upgrade, :cask do let(:local_caffeine_path) { local_caffeine.config.appdir.join("Caffeine.app") } let(:local_caffeine) { Cask::CaskLoader.load("local-caffeine") } - context "successful upgrade" do + context "when the upgrade is successful" do let(:installed) { [ "outdated/local-caffeine", @@ -149,7 +149,7 @@ describe Cask::Cmd::Upgrade, :cask do end end - context "dry run upgrade" do + context "when the upgrade is a dry run" do let(:installed) { [ "outdated/local-caffeine", @@ -294,7 +294,7 @@ describe Cask::Cmd::Upgrade, :cask do end end - context "failed upgrade" do + context "when an upgrade failed" do let(:installed) { [ "outdated/bad-checksum", @@ -349,7 +349,7 @@ describe Cask::Cmd::Upgrade, :cask do end end - context "multiple failures" do + context "when there were multiple failures" do let(:installed) { [ "outdated/bad-checksum", diff --git a/Library/Homebrew/test/cask/depends_on_spec.rb b/Library/Homebrew/test/cask/depends_on_spec.rb index aa1647de6c..191df90dae 100644 --- a/Library/Homebrew/test/cask/depends_on_spec.rb +++ b/Library/Homebrew/test/cask/depends_on_spec.rb @@ -32,7 +32,7 @@ describe "Satisfy Dependencies and Requirements", :cask do end describe "depends_on macos" do - context "given an array" do + context "with an array" do let(:cask) { Cask::CaskLoader.load(cask_path("with-depends-on-macos-array")) } it "does not raise an error" do @@ -40,7 +40,7 @@ describe "Satisfy Dependencies and Requirements", :cask do end end - context "given a comparison" do + context "with a comparison" do let(:cask) { Cask::CaskLoader.load(cask_path("with-depends-on-macos-comparison")) } it "does not raise an error" do @@ -48,7 +48,7 @@ describe "Satisfy Dependencies and Requirements", :cask do end end - context "given a symbol" do + context "with a symbol" do let(:cask) { Cask::CaskLoader.load(cask_path("with-depends-on-macos-symbol")) } it "does not raise an error" do diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index cd713b3282..ad93c252c3 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -5,7 +5,7 @@ describe Cask::DSL, :cask do let(:cask) { Cask::CaskLoader.load(cask_path(token.to_s)) } let(:token) { "basic-cask" } - context "stanzas" do + describe "stanzas" do it "lets you set url, homepage, and version" do expect(cask.url.to_s).to eq("https://brew.sh/TestCask-1.2.3.dmg") expect(cask.homepage).to eq("https://brew.sh/") @@ -80,8 +80,8 @@ describe Cask::DSL, :cask do end expect(cask.name).to eq([ - "Proper Name", - ]) + "Proper Name", + ]) end it "Accepts an array value to the name stanza" do @@ -90,9 +90,9 @@ describe Cask::DSL, :cask do end expect(cask.name).to eq([ - "Proper Name", - "Alternate Name", - ]) + "Proper Name", + "Alternate Name", + ]) end it "Accepts multiple name stanzas" do @@ -102,9 +102,9 @@ describe Cask::DSL, :cask do end expect(cask.name).to eq([ - "Proper Name", - "Alternate Name", - ]) + "Proper Name", + "Alternate Name", + ]) end end @@ -168,37 +168,37 @@ describe Cask::DSL, :cask do cask.config = config end - context "to 'zh'" do + describe "to 'zh'" do let(:languages) { ["zh"] } it { is_expected.to be_the_chinese_version } end - context "to 'zh-XX'" do + describe "to 'zh-XX'" do let(:languages) { ["zh-XX"] } it { is_expected.to be_the_chinese_version } end - context "to 'en'" do + describe "to 'en'" do let(:languages) { ["en"] } it { is_expected.to be_the_english_version } end - context "to 'xx-XX'" do + describe "to 'xx-XX'" do let(:languages) { ["xx-XX"] } it { is_expected.to be_the_english_version } end - context "to 'xx-XX,zh,en'" do + describe "to 'xx-XX,zh,en'" do let(:languages) { ["xx-XX", "zh", "en"] } it { is_expected.to be_the_chinese_version } end - context "to 'xx-XX,en-US,zh'" do + describe "to 'xx-XX,en-US,zh'" do let(:languages) { ["xx-XX", "en-US", "zh"] } it { is_expected.to be_the_english_version } @@ -356,7 +356,7 @@ describe Cask::DSL, :cask do end describe "depends_on cask" do - context "specifying one" do + context "with a single cask" do let(:token) { "with-depends-on-cask" } it "is allowed" do @@ -364,7 +364,7 @@ describe Cask::DSL, :cask do end end - context "specifying multiple" do + context "when specifying multiple" do let(:token) { "with-depends-on-cask-multiple" } it "is allowed" do @@ -374,7 +374,7 @@ describe Cask::DSL, :cask do end describe "depends_on macos" do - context "invalid depends_on macos value" do + context "when the depends_on macos value is invalid" do let(:token) { "invalid/invalid-depends-on-macos-bad-release" } it "refuses to load" do @@ -382,7 +382,7 @@ describe Cask::DSL, :cask do end end - context "conflicting depends_on macos forms" do + context "when there are conflicting depends_on macos forms" do let(:token) { "invalid/invalid-depends-on-macos-conflicting-forms" } it "refuses to load" do @@ -392,7 +392,7 @@ describe Cask::DSL, :cask do end describe "depends_on arch" do - context "valid" do + context "when valid" do let(:token) { "with-depends-on-arch" } it "is allowed to be specified" do @@ -400,7 +400,7 @@ describe Cask::DSL, :cask do end end - context "invalid depends_on arch value" do + context "with invalid depends_on arch value" do let(:token) { "invalid/invalid-depends-on-arch-value" } it "refuses to load" do @@ -410,7 +410,7 @@ describe Cask::DSL, :cask do end describe "depends_on x11" do - context "invalid depends_on x11 value" do + context "with invalid depends_on x11 value" do let(:token) { "invalid/invalid-depends-on-x11-value" } it "refuses to load" do @@ -420,7 +420,7 @@ describe Cask::DSL, :cask do end describe "conflicts_with stanza" do - context "valid" do + context "when valid" do let(:token) { "with-conflicts-with" } it "allows conflicts_with stanza to be specified" do @@ -428,7 +428,7 @@ describe Cask::DSL, :cask do end end - context "invalid conflicts_with key" do + context "with invalid conflicts_with key" do let(:token) { "invalid/invalid-conflicts-with-key" } it "refuses to load invalid conflicts_with key" do @@ -438,7 +438,7 @@ describe Cask::DSL, :cask do end describe "installer stanza" do - context "script" do + context "when script" do let(:token) { "with-installer-script" } it "allows installer script to be specified" do @@ -449,7 +449,7 @@ describe Cask::DSL, :cask do end end - context "manual" do + context "when manual" do let(:token) { "with-installer-manual" } it "allows installer manual to be specified" do @@ -487,7 +487,7 @@ describe Cask::DSL, :cask do end describe "#appdir" do - context "interpolation of the appdir in stanzas" do + context "with interpolation of the appdir in stanzas" do let(:token) { "appdir-interpolation" } it "is allowed" do @@ -497,8 +497,8 @@ describe Cask::DSL, :cask do it "does not include a trailing slash" do config = Cask::Config.new(explicit: { - appdir: "/Applications/", - }) + appdir: "/Applications/", + }) cask = Cask::Cask.new("appdir-trailing-slash", config: config) do binary "#{appdir}/some/path" diff --git a/Library/Homebrew/test/cask/pkg_spec.rb b/Library/Homebrew/test/cask/pkg_spec.rb index cd45d57cf7..5c7b4eecca 100644 --- a/Library/Homebrew/test/cask/pkg_spec.rb +++ b/Library/Homebrew/test/cask/pkg_spec.rb @@ -35,7 +35,7 @@ describe Cask::Pkg, :cask do expect(root_dir).not_to exist end - context "pkgutil" do + describe "pkgutil" do it "forgets the pkg" do allow(fake_system_command).to receive(:run!).with( "/usr/sbin/pkgutil", @@ -93,6 +93,15 @@ describe Cask::Pkg, :cask do allow(pkg).to receive(:root).and_return(fake_root) allow(pkg).to receive(:forget) + # This is expected to fail in tests since we don't use `sudo`. + allow(fake_system_command).to receive(:run!).and_call_original + expect(fake_system_command).to receive(:run!).with( + "/usr/bin/xargs", + args: ["-0", "--", "/bin/bash", "-c", a_string_including("/bin/rmdir"), "--"], + input: [fake_dir].join("\0"), + sudo: true, + ).and_return(instance_double(SystemCommand::Result, stdout: "")) + pkg.uninstall expect(fake_dir).to be_a_directory diff --git a/Library/Homebrew/test/caveats_spec.rb b/Library/Homebrew/test/caveats_spec.rb index c2cbeb5205..15cb29d4f8 100644 --- a/Library/Homebrew/test/caveats_spec.rb +++ b/Library/Homebrew/test/caveats_spec.rb @@ -176,7 +176,7 @@ describe Caveats do end end - context "shell completions" do + describe "shell completions" do let(:f) { formula do url "foo-1.0" diff --git a/Library/Homebrew/test/cleanup_spec.rb b/Library/Homebrew/test/cleanup_spec.rb index 75dbe01560..0f98f539db 100644 --- a/Library/Homebrew/test/cleanup_spec.rb +++ b/Library/Homebrew/test/cleanup_spec.rb @@ -328,7 +328,7 @@ describe Homebrew::Cleanup do expect(foo).to exist end - context "cleans old files in HOMEBREW_CACHE" do + context "when cleaning old files in HOMEBREW_CACHE" do let(:bottle) { (HOMEBREW_CACHE/"testball--0.0.1.tag.bottle.tar.gz") } let(:testball) { (HOMEBREW_CACHE/"testball--0.0.1") } let(:testball_resource) { (HOMEBREW_CACHE/"testball--rsrc--0.0.1.txt") } diff --git a/Library/Homebrew/test/cmd/--caskroom_spec.rb b/Library/Homebrew/test/cmd/--caskroom_spec.rb index 769d95544f..6277d5c855 100644 --- a/Library/Homebrew/test/cmd/--caskroom_spec.rb +++ b/Library/Homebrew/test/cmd/--caskroom_spec.rb @@ -1,23 +1,19 @@ # typed: false # frozen_string_literal: true -describe "brew --caskroom", :integration_test do - let(:local_transmission) { - Cask::CaskLoader.load(cask_path("local-transmission")) - } +require "cmd/shared_examples/args_parse" - let(:local_caffeine) { - Cask::CaskLoader.load(cask_path("local-caffeine")) - } +describe "brew --caskroom" do + it_behaves_like "parseable arguments" - it "outputs Homebrew's caskroom" do - expect { brew "--caskroom" } - .to output("#{HOMEBREW_PREFIX/"Caskroom"}\n").to_stdout + it "prints Homebrew's Caskroom", :integration_test do + expect { brew_sh "--caskroom" } + .to output("#{ENV["HOMEBREW_PREFIX"]}/Caskroom\n").to_stdout .and not_to_output.to_stderr .and be_a_success end - it "outputs the caskroom path of casks" do + it "prints the Caskroom for Casks", :integration_test do expect { brew "--caskroom", cask_path("local-transmission"), cask_path("local-caffeine") } .to output("#{HOMEBREW_PREFIX/"Caskroom"/"local-transmission"}\n" \ "#{HOMEBREW_PREFIX/"Caskroom"/"local-caffeine\n"}").to_stdout diff --git a/Library/Homebrew/test/cmd/--cellar_spec.rb b/Library/Homebrew/test/cmd/--cellar_spec.rb index a91b8ecd3f..22eee9e244 100644 --- a/Library/Homebrew/test/cmd/--cellar_spec.rb +++ b/Library/Homebrew/test/cmd/--cellar_spec.rb @@ -6,7 +6,14 @@ require "cmd/shared_examples/args_parse" describe "brew --cellar" do it_behaves_like "parseable arguments" - it "returns the Cellar subdirectory for a given Formula", :integration_test do + it "prints Homebrew's Cellar", :integration_test do + expect { brew_sh "--cellar" } + .to output("#{ENV["HOMEBREW_CELLAR"]}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints the Cellar for a Formula", :integration_test do expect { brew "--cellar", testball } .to output(%r{#{HOMEBREW_CELLAR}/testball}o).to_stdout .and not_to_output.to_stderr diff --git a/Library/Homebrew/test/cmd/--prefix_spec.rb b/Library/Homebrew/test/cmd/--prefix_spec.rb index 4759af5954..44a4244667 100644 --- a/Library/Homebrew/test/cmd/--prefix_spec.rb +++ b/Library/Homebrew/test/cmd/--prefix_spec.rb @@ -6,15 +6,22 @@ require "cmd/shared_examples/args_parse" describe "brew --prefix" do it_behaves_like "parseable arguments" - it "prints a given Formula's prefix", :integration_test do - expect { brew "--prefix", testball } - .to output(%r{#{HOMEBREW_CELLAR}/testball}o).to_stdout + it "prints Homebrew's prefix", :integration_test do + expect { brew_sh "--prefix" } + .to output("#{ENV["HOMEBREW_PREFIX"]}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints the prefix for a Formula", :integration_test do + expect { brew_sh "--prefix", "wget" } + .to output("#{ENV["HOMEBREW_PREFIX"]}/opt/wget\n").to_stdout .and not_to_output.to_stderr .and be_a_success end it "errors if the given Formula doesn't exist", :integration_test do - expect { brew "--prefix", "--installed", "nonexistent" } + expect { brew "--prefix", "nonexistent" } .to output(/No available formula/).to_stderr .and not_to_output.to_stdout .and be_a_failure diff --git a/Library/Homebrew/test/cmd/--repository_spec.rb b/Library/Homebrew/test/cmd/--repository_spec.rb index d8c63aaaf8..d85df8f3a8 100644 --- a/Library/Homebrew/test/cmd/--repository_spec.rb +++ b/Library/Homebrew/test/cmd/--repository_spec.rb @@ -6,7 +6,14 @@ require "cmd/shared_examples/args_parse" describe "brew --repository" do it_behaves_like "parseable arguments" - it "prints the path of a given Tap", :integration_test do + it "prints Homebrew's repository", :integration_test do + expect { brew_sh "--repository" } + .to output("#{ENV["HOMEBREW_REPOSITORY"]}\n").to_stdout + .and not_to_output.to_stderr + .and be_a_success + end + + it "prints a Tap's repository", :integration_test do expect { brew "--repository", "foo/bar" } .to output("#{HOMEBREW_LIBRARY}/Taps/foo/homebrew-bar\n").to_stdout .and not_to_output.to_stderr diff --git a/Library/Homebrew/test/cmd/--version_spec.rb b/Library/Homebrew/test/cmd/--version_spec.rb index 0717854349..944ff2981f 100644 --- a/Library/Homebrew/test/cmd/--version_spec.rb +++ b/Library/Homebrew/test/cmd/--version_spec.rb @@ -4,10 +4,8 @@ require "cmd/shared_examples/args_parse" describe "brew --version" do - it_behaves_like "parseable arguments" - - it "prints the Homebrew version", :integration_test do - expect { brew "--version" } + it "prints the Homebrew's version", :integration_test do + expect { brew_sh "--version" } .to output(/^Homebrew #{Regexp.escape(HOMEBREW_VERSION)}\n/o).to_stdout .and not_to_output.to_stderr .and be_a_success diff --git a/Library/Homebrew/test/commands_spec.rb b/Library/Homebrew/test/commands_spec.rb index b4a672191f..d817a4c80a 100644 --- a/Library/Homebrew/test/commands_spec.rb +++ b/Library/Homebrew/test/commands_spec.rb @@ -3,7 +3,7 @@ require "commands" -RSpec.shared_context "custom internal commands" do +RSpec.shared_context "custom internal commands" do # rubocop:disable RSpec/ContextWording let(:cmds) do [ # internal commands diff --git a/Library/Homebrew/test/completions_spec.rb b/Library/Homebrew/test/completions_spec.rb index c3b9ad9632..cadc966bb8 100644 --- a/Library/Homebrew/test/completions_spec.rb +++ b/Library/Homebrew/test/completions_spec.rb @@ -321,7 +321,8 @@ describe Homebrew::Completions do '--hide[Act as if none of the specified hidden are installed. hidden should be a comma-separated list of formulae]' \\ '--quiet[Make some output more quiet]' \\ '--verbose[Make some output more verbose]' \\ - '::formula:__brew_formulae' + - formula \\ + '*::formula:__brew_formulae' } COMPLETION end @@ -343,9 +344,12 @@ describe Homebrew::Completions do end it "returns appropriate completion for a command with multiple named arg types" do - completion = described_class.generate_zsh_subcommand_completion("upgrade") + completion = described_class.generate_zsh_subcommand_completion("livecheck") expect(completion).to match( - /'::outdated_formula:__brew_outdated_formulae' \\\n '::outdated_cask:__brew_outdated_casks'\n}$/, + /'*::formula:__brew_formulae'/, + ) + expect(completion).to match( + /'*::cask:__brew_casks'\n}$/, ) end end diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index 2efd90abd6..209dfddaf4 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -817,8 +817,8 @@ module Homebrew end end - context "checksums" do - context "should not change with the same version" do + describe "checksums" do + describe "should not change with the same version" do before do formula_gsub( 'sha256 "31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e"', @@ -829,7 +829,7 @@ module Homebrew it { is_expected.to match("stable sha256 changed without the url/version also changing") } end - context "should not change with the same version when not the first commit" do + describe "should not change with the same version when not the first commit" do before do formula_gsub_origin_commit( 'sha256 "31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e"', @@ -846,7 +846,7 @@ module Homebrew it { is_expected.to match("stable sha256 changed without the url/version also changing") } end - context "can change with the different version" do + describe "can change with the different version" do before do formula_gsub_origin_commit( 'sha256 "31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e"', @@ -862,7 +862,7 @@ module Homebrew it { is_expected.to be_nil } end - context "can be removed when switching schemes" do + describe "can be removed when switching schemes" do before do formula_gsub_origin_commit( 'url "https://brew.sh/foo-1.0.tar.gz"', @@ -876,42 +876,42 @@ module Homebrew end end - context "revisions" do - context "should not be removed when first committed above 0" do + describe "revisions" do + describe "should not be removed when first committed above 0" do it { is_expected.to be_nil } end - context "should not decrease with the same version" do + describe "with the same version, should not decrease" do before { formula_gsub_origin_commit "revision 2", "revision 1" } it { is_expected.to match("revision should not decrease (from 2 to 1)") } end - context "should not be removed with the same version" do + describe "should not be removed with the same version" do before { formula_gsub_origin_commit "revision 2" } it { is_expected.to match("revision should not decrease (from 2 to 0)") } end - context "should not decrease with the same, uncommitted version" do + describe "should not decrease with the same, uncommitted version" do before { formula_gsub "revision 2", "revision 1" } it { is_expected.to match("revision should not decrease (from 2 to 1)") } end - context "should be removed with a newer version" do + describe "should be removed with a newer version" do before { formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" } it { is_expected.to match("'revision 2' should be removed") } end - context "should be removed with a newer local version" do + describe "should be removed with a newer local version" do before { formula_gsub "foo-1.0.tar.gz", "foo-1.1.tar.gz" } it { is_expected.to match("'revision 2' should be removed") } end - context "should not warn on an newer version revision removal" do + describe "should not warn on an newer version revision removal" do before do formula_gsub_origin_commit "revision 2", "" formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" @@ -920,7 +920,7 @@ module Homebrew it { is_expected.to be_nil } end - context "should not warn when revision from previous version matches current revision" do + describe "should not warn when revision from previous version matches current revision" do before do formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" formula_gsub_origin_commit "revision 2", "# no revision" @@ -931,7 +931,7 @@ module Homebrew it { is_expected.to be_nil } end - context "should only increment by 1 with an uncommitted version" do + describe "should only increment by 1 with an uncommitted version" do before do formula_gsub "foo-1.0.tar.gz", "foo-1.1.tar.gz" formula_gsub "revision 2", "revision 4" @@ -940,7 +940,7 @@ module Homebrew it { is_expected.to match("revisions should only increment by 1") } end - context "should not warn on past increment by more than 1" do + describe "should not warn on past increment by more than 1" do before do formula_gsub_origin_commit "revision 2", "# no revision" formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" @@ -951,14 +951,14 @@ module Homebrew end end - context "version_schemes" do - context "should not decrease with the same version" do + describe "version_schemes" do + describe "should not decrease with the same version" do before { formula_gsub_origin_commit "version_scheme 1" } it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } end - context "should not decrease with a new version" do + describe "should not decrease with a new version" do before do formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" formula_gsub_origin_commit "revision 2", "" @@ -968,7 +968,7 @@ module Homebrew it { is_expected.to match("version_scheme should not decrease (from 1 to 0)") } end - context "should only increment by 1" do + describe "should only increment by 1" do before do formula_gsub_origin_commit "version_scheme 1", "# no version_scheme" formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-1.1.tar.gz" @@ -980,14 +980,14 @@ module Homebrew end end - context "versions" do - context "uncommitted should not decrease" do + describe "versions" do + context "when uncommitted should not decrease" do before { formula_gsub "foo-1.0.tar.gz", "foo-0.9.tar.gz" } it { is_expected.to match("stable version should not decrease (from 1.0 to 0.9)") } end - context "committed can decrease" do + context "when committed can decrease" do before do formula_gsub_origin_commit "revision 2" formula_gsub_origin_commit "foo-1.0.tar.gz", "foo-0.9.tar.gz" @@ -996,7 +996,7 @@ module Homebrew it { is_expected.to be_nil } end - context "can decrease with version_scheme increased" do + describe "can decrease with version_scheme increased" do before do formula_gsub "revision 2" formula_gsub "foo-1.0.tar.gz", "foo-0.9.tar.gz" diff --git a/Library/Homebrew/test/dev-cmd/test_spec.rb b/Library/Homebrew/test/dev-cmd/test_spec.rb index bf4ee0660f..4466262501 100644 --- a/Library/Homebrew/test/dev-cmd/test_spec.rb +++ b/Library/Homebrew/test/dev-cmd/test_spec.rb @@ -6,8 +6,7 @@ require "cmd/shared_examples/args_parse" describe "brew test" do it_behaves_like "parseable arguments" - # randomly segfaults on Linux with portable-ruby. - it "tests a given Formula", :integration_test, :needs_macos do + it "tests a given Formula", :integration_test do install_test_formula "testball", <<~'RUBY' test do assert_equal "test", shell_output("#{bin}/test") diff --git a/Library/Homebrew/test/download_strategies/curl_spec.rb b/Library/Homebrew/test/download_strategies/curl_spec.rb index 6ea5e5be0c..09cd6ca07a 100644 --- a/Library/Homebrew/test/download_strategies/curl_spec.rb +++ b/Library/Homebrew/test/download_strategies/curl_spec.rb @@ -15,28 +15,6 @@ describe CurlDownloadStrategy do expect(strategy.send(:_curl_args)).to eq(["--user", "download:123456"]) end - describe "#cached_location" do - subject(:location) { described_class.new(url, name, version, **specs).cached_location } - - context "when URL ends with file" do - it { - expect(location).to eq( - HOMEBREW_CACHE/"downloads/3d1c0ae7da22be9d83fb1eb774df96b7c4da71d3cf07e1cb28555cf9a5e5af70--foo.tar.gz", - ) - } - end - - context "when URL file is in middle" do - let(:url) { "https://example.com/foo.tar.gz/from/this/mirror" } - - it { - expect(location).to eq( - HOMEBREW_CACHE/"downloads/1ab61269ba52c83994510b1e28dd04167a2f2e8393a35a9c50c1f7d33fd8f619--foo.tar.gz", - ) - } - end - end - describe "#fetch" do before do strategy.temporary_path.dirname.mkpath @@ -147,22 +125,48 @@ describe CurlDownloadStrategy do end describe "#cached_location" do + subject(:cached_location) { described_class.new(url, name, version, **specs).cached_location } + + context "when URL ends with file" do + it { + expect(cached_location).to eq( + HOMEBREW_CACHE/"downloads/3d1c0ae7da22be9d83fb1eb774df96b7c4da71d3cf07e1cb28555cf9a5e5af70--foo.tar.gz", + ) + } + end + + context "when URL file is in middle" do + let(:url) { "https://example.com/foo.tar.gz/from/this/mirror" } + + it { + expect(cached_location).to eq( + HOMEBREW_CACHE/"downloads/1ab61269ba52c83994510b1e28dd04167a2f2e8393a35a9c50c1f7d33fd8f619--foo.tar.gz", + ) + } + end + context "with a file name trailing the URL path" do let(:url) { "https://example.com/cask.dmg" } - its("cached_location.extname") { is_expected.to eq(".dmg") } + it { + expect(cached_location.extname).to eq(".dmg") + } end context "with a file name trailing the first query parameter" do let(:url) { "https://example.com/download?file=cask.zip&a=1" } - its("cached_location.extname") { is_expected.to eq(".zip") } + it { + expect(cached_location.extname).to eq(".zip") + } end context "with a file name trailing the second query parameter" do let(:url) { "https://example.com/dl?a=1&file=cask.zip&b=2" } - its("cached_location.extname") { is_expected.to eq(".zip") } + it { + expect(cached_location.extname).to eq(".zip") + } end context "with an unusually long query string" do @@ -184,8 +188,10 @@ describe CurlDownloadStrategy do ].join end - its("cached_location.extname") { is_expected.to eq(".zip") } - its("cached_location.to_path.length") { is_expected.to be_between(0, 255) } + it { + expect(cached_location.extname).to eq(".zip") + expect(cached_location.to_path.length).to be_between(0, 255) + } end end end diff --git a/Library/Homebrew/test/error_during_execution_spec.rb b/Library/Homebrew/test/error_during_execution_spec.rb index a3f6221198..a2fdcc3a9d 100644 --- a/Library/Homebrew/test/error_during_execution_spec.rb +++ b/Library/Homebrew/test/error_during_execution_spec.rb @@ -5,7 +5,7 @@ describe ErrorDuringExecution do subject(:error) { described_class.new(command, status: status, output: output) } let(:command) { ["false"] } - let(:status) { instance_double(Process::Status, exitstatus: exitstatus) } + let(:status) { instance_double(Process::Status, exitstatus: exitstatus, termsig: nil) } let(:exitstatus) { 1 } let(:output) { nil } diff --git a/Library/Homebrew/test/exceptions_spec.rb b/Library/Homebrew/test/exceptions_spec.rb index be1373e0fd..dfa8e9b6bc 100644 --- a/Library/Homebrew/test/exceptions_spec.rb +++ b/Library/Homebrew/test/exceptions_spec.rb @@ -34,6 +34,14 @@ describe "Exception" do } end + describe TapFormulaOrCaskUnavailableError do + subject(:error) { described_class.new(tap, "foo") } + + let(:tap) { double(Tap, user: "u", repo: "r", to_s: "u/r", installed?: false) } + + its(:to_s) { is_expected.to match(%r{Please tap it and then try again: brew tap u/r}) } + end + describe FormulaUnavailableError do subject(:error) { described_class.new("foo") } @@ -87,7 +95,7 @@ describe "Exception" do end end - context "no classes" do + context "when there are no classes" do let(:list) { [] } its(:to_s) { @@ -95,7 +103,7 @@ describe "Exception" do } end - context "class not derived from Formula" do + context "when the class is not derived from Formula" do let(:list) { [mod.const_get(:Bar)] } its(:to_s) { @@ -103,7 +111,7 @@ describe "Exception" do } end - context "class derived from Formula" do + context "when the class is derived from Formula" do let(:list) { [mod.const_get(:Baz)] } its(:to_s) { is_expected.to match(/Expected to find class Foo, but only found: Baz\./) } @@ -170,13 +178,13 @@ describe "Exception" do end describe CurlDownloadStrategyError do - context "file does not exist" do + context "when the file does not exist" do subject { described_class.new("file:///tmp/foo") } its(:to_s) { is_expected.to eq("File does not exist: /tmp/foo") } end - context "download failed" do + context "when the download failed" do subject { described_class.new("https://brew.sh") } its(:to_s) { is_expected.to eq("Download failed: https://brew.sh") } @@ -186,7 +194,7 @@ describe "Exception" do describe ErrorDuringExecution do subject { described_class.new(["badprg", "arg1", "arg2"], status: status) } - let(:status) { instance_double(Process::Status, exitstatus: 17) } + let(:status) { instance_double(Process::Status, exitstatus: 17, termsig: nil) } its(:to_s) { is_expected.to eq("Failure while executing; `badprg arg1 arg2` exited with 17.") } end diff --git a/Library/Homebrew/test/formula_info_spec.rb b/Library/Homebrew/test/formula_info_spec.rb index 0e8bcebb10..c9c1c7a366 100644 --- a/Library/Homebrew/test/formula_info_spec.rb +++ b/Library/Homebrew/test/formula_info_spec.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true require "formula_info" -require "global" describe FormulaInfo, :integration_test do it "tests the FormulaInfo class" do diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index 0e84ed74a5..b4233dfaff 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -96,40 +96,97 @@ describe FormulaInstaller do end end - specify "check installation sanity pinned dependency" do - dep_name = "dependency" - dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb" - dep_path.write <<~RUBY - class #{Formulary.class_s(dep_name)} < Formula - url "foo" - version "0.2" - end - RUBY + describe "#check_install_sanity" do + it "raises on direct cyclic dependency" do + ENV["HOMEBREW_DEVELOPER"] = "1" - Formulary.cache.delete(dep_path) - dependency = Formulary.factory(dep_name) + dep_name = "homebrew-test-cyclic" + dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb" + dep_path.write <<~RUBY + class #{Formulary.class_s(dep_name)} < Formula + url "foo" + version "0.1" + depends_on "#{dep_name}" + end + RUBY + Formulary.cache.delete(dep_path) + f = Formulary.factory(dep_name) - dependent = formula do - url "foo" - version "0.5" - depends_on dependency.name.to_s + fi = described_class.new(f) + + expect { + fi.check_install_sanity + }.to raise_error(CannotInstallFormulaError) end - (dependency.prefix("0.1")/"bin"/"a").mkpath - HOMEBREW_PINNED_KEGS.mkpath - FileUtils.ln_s dependency.prefix("0.1"), HOMEBREW_PINNED_KEGS/dep_name + it "raises on indirect cyclic dependency" do + ENV["HOMEBREW_DEVELOPER"] = "1" - dependency_keg = Keg.new(dependency.prefix("0.1")) - dependency_keg.link + formula1_name = "homebrew-test-formula1" + formula2_name = "homebrew-test-formula2" + formula1_path = CoreTap.new.formula_dir/"#{formula1_name}.rb" + formula1_path.write <<~RUBY + class #{Formulary.class_s(formula1_name)} < Formula + url "foo" + version "0.1" + depends_on "#{formula2_name}" + end + RUBY + Formulary.cache.delete(formula1_path) + formula1 = Formulary.factory(formula1_name) - expect(dependency_keg).to be_linked - expect(dependency).to be_pinned + formula2_path = CoreTap.new.formula_dir/"#{formula2_name}.rb" + formula2_path.write <<~RUBY + class #{Formulary.class_s(formula2_name)} < Formula + url "foo" + version "0.1" + depends_on "#{formula1_name}" + end + RUBY + Formulary.cache.delete(formula2_path) - fi = described_class.new(dependent) + fi = described_class.new(formula1) - expect { - fi.check_install_sanity - }.to raise_error(CannotInstallFormulaError) + expect { + fi.check_install_sanity + }.to raise_error(CannotInstallFormulaError) + end + + it "raises on pinned dependency" do + dep_name = "homebrew-test-dependency" + dep_path = CoreTap.new.formula_dir/"#{dep_name}.rb" + dep_path.write <<~RUBY + class #{Formulary.class_s(dep_name)} < Formula + url "foo" + version "0.2" + end + RUBY + + Formulary.cache.delete(dep_path) + dependency = Formulary.factory(dep_name) + + dependent = formula do + url "foo" + version "0.5" + depends_on dependency.name.to_s + end + + (dependency.prefix("0.1")/"bin"/"a").mkpath + HOMEBREW_PINNED_KEGS.mkpath + FileUtils.ln_s dependency.prefix("0.1"), HOMEBREW_PINNED_KEGS/dep_name + + dependency_keg = Keg.new(dependency.prefix("0.1")) + dependency_keg.link + + expect(dependency_keg).to be_linked + expect(dependency).to be_pinned + + fi = described_class.new(dependent) + + expect { + fi.check_install_sanity + }.to raise_error(CannotInstallFormulaError) + end end specify "install fails with BuildError when a system() call fails" do diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 0148bb4158..1ac97f254d 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -56,7 +56,7 @@ describe Formula do expect { klass.new }.to raise_error(ArgumentError) end - context "in a Tap" do + context "when in a Tap" do let(:tap) { Tap.new("foo", "bar") } let(:path) { (tap.path/"Formula/#{name}.rb") } let(:full_name) { "#{tap.user}/#{tap.repo}/#{name}" } diff --git a/Library/Homebrew/test/hardware/cpu_spec.rb b/Library/Homebrew/test/hardware/cpu_spec.rb index 7c6bf9cde4..5d307c4c43 100644 --- a/Library/Homebrew/test/hardware/cpu_spec.rb +++ b/Library/Homebrew/test/hardware/cpu_spec.rb @@ -22,6 +22,12 @@ describe Hardware::CPU do describe "::family" do let(:cpu_families) { [ + :amd_k7, + :amd_k8, + :amd_k8_k10_hybrid, + :amd_k10, + :amd_k12, + :arm, :arm_firestorm_icestorm, :arm_hurricane_zephyr, :arm_lightning_thunder, @@ -30,22 +36,29 @@ describe Hardware::CPU do :arm_typhoon, :arm_vortex_tempest, :atom, + :bobcat, :broadwell, + :bulldozer, + :cannonlake, :core, :core2, :dothan, :haswell, :icelake, :ivybridge, + :jaguar, :kabylake, :merom, :nehalem, :penryn, + :ppc, :prescott, :presler, :sandybridge, :skylake, :westmere, + :zen, + :zen3, :dunno, ] } diff --git a/Library/Homebrew/test/installed_dependents_spec.rb b/Library/Homebrew/test/installed_dependents_spec.rb new file mode 100644 index 0000000000..824c6f2d94 --- /dev/null +++ b/Library/Homebrew/test/installed_dependents_spec.rb @@ -0,0 +1,179 @@ +# typed: false +# frozen_string_literal: true + +require "installed_dependents" + +describe InstalledDependents do + include FileUtils + + def setup_test_keg(name, version) + path = HOMEBREW_CELLAR/name/version + (path/"bin").mkpath + + %w[hiworld helloworld goodbye_cruel_world].each do |file| + touch path/"bin"/file + end + + Keg.new(path) + end + + let!(:keg) { setup_test_keg("foo", "1.0") } + + describe "::find_some_installed_dependents" do + def stub_formula_name(name) + f = formula(name) { url "foo-1.0" } + stub_formula_loader f + stub_formula_loader f, "homebrew/core/#{f}" + f + end + + def setup_test_keg(name, version) + f = stub_formula_name(name) + keg = super + Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write + keg + end + + before do + keg.link + end + + def alter_tab(keg = dependent) + tab = Tab.for_keg(keg) + yield tab + tab.write + end + + # 1.1.6 is the earliest version of Homebrew that generates correct runtime + # dependency lists in {Tab}s. + def dependencies(deps, homebrew_version: "1.1.6") + alter_tab do |tab| + tab.homebrew_version = homebrew_version + tab.tabfile = dependent/Tab::FILENAME + tab.runtime_dependencies = deps + end + end + + def unreliable_dependencies(deps) + # 1.1.5 is (hopefully!) the last version of Homebrew that generates + # incorrect runtime dependency lists in {Tab}s. + dependencies(deps, homebrew_version: "1.1.5") + end + + let(:dependent) { setup_test_keg("bar", "1.0") } + + specify "a dependency with no Tap in Tab" do + tap_dep = setup_test_keg("baz", "1.0") + + # allow tap_dep to be linked too + FileUtils.rm_r tap_dep/"bin" + tap_dep.link + + alter_tab(keg) { |t| t.source["tap"] = nil } + + dependencies nil + Formula["bar"].class.depends_on "foo" + Formula["bar"].class.depends_on "baz" + + result = described_class.find_some_installed_dependents([keg, tap_dep]) + expect(result).to eq([[keg, tap_dep], ["bar"]]) + end + + specify "no dependencies anywhere" do + dependencies nil + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "missing Formula dependency" do + dependencies nil + Formula["bar"].class.depends_on "foo" + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "uninstalling dependent and dependency" do + dependencies nil + Formula["bar"].class.depends_on "foo" + expect(described_class.find_some_installed_dependents([keg, dependent])).to be nil + end + + specify "renamed dependency" do + dependencies nil + + stub_formula_loader Formula["foo"], "homebrew/core/foo-old" + renamed_path = HOMEBREW_CELLAR/"foo-old" + (HOMEBREW_CELLAR/"foo").rename(renamed_path) + renamed_keg = Keg.new(renamed_path/"1.0") + + Formula["bar"].class.depends_on "foo" + + result = described_class.find_some_installed_dependents([renamed_keg]) + expect(result).to eq([[renamed_keg], ["bar"]]) + end + + specify "empty dependencies in Tab" do + dependencies [] + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "same name but different version in Tab" do + dependencies [{ "full_name" => "foo", "version" => "1.1" }] + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "different name and same version in Tab" do + stub_formula_name("baz") + dependencies [{ "full_name" => "baz", "version" => keg.version.to_s }] + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "same name and version in Tab" do + dependencies [{ "full_name" => "foo", "version" => "1.0" }] + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "fallback for old versions" do + unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }] + Formula["bar"].class.depends_on "foo" + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + specify "non-opt-linked" do + keg.remove_opt_record + dependencies [{ "full_name" => "foo", "version" => "1.0" }] + expect(described_class.find_some_installed_dependents([keg])).to be nil + end + + specify "keg-only" do + keg.unlink + Formula["foo"].class.keg_only "a good reason" + dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version + expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) + end + + def stub_cask_name(name, version, dependency) + c = Cask::CaskLoader.load(+<<-RUBY) + cask "#{name}" do + version "#{version}" + + url "c-1" + depends_on formula: "#{dependency}" + end + RUBY + + stub_cask_loader c + c + end + + def setup_test_cask(name, version, dependency) + c = stub_cask_name(name, version, dependency) + Cask::Caskroom.path.join(name, c.version).mkpath + c + end + + specify "identify dependent casks" do + setup_test_cask("qux", "1.0.0", "foo") + dependents = described_class.find_some_installed_dependents([keg]).last + expect(dependents.include?("qux")).to eq(true) + end + end +end diff --git a/Library/Homebrew/test/keg_spec.rb b/Library/Homebrew/test/keg_spec.rb index c64d825987..1b82ada38b 100644 --- a/Library/Homebrew/test/keg_spec.rb +++ b/Library/Homebrew/test/keg_spec.rb @@ -5,8 +5,6 @@ require "keg" require "stringio" describe Keg do - include FileUtils - def setup_test_keg(name, version) path = HOMEBREW_CELLAR/name/version (path/"bin").mkpath @@ -324,136 +322,4 @@ describe Keg do keg.unlink expect(keg).not_to be_linked end - - describe "::find_some_installed_dependents" do - def stub_formula_name(name) - f = formula(name) { url "foo-1.0" } - stub_formula_loader f - stub_formula_loader f, "homebrew/core/#{f}" - f - end - - def setup_test_keg(name, version) - f = stub_formula_name(name) - keg = super - Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write - keg - end - - before do - keg.link - end - - def alter_tab(keg = dependent) - tab = Tab.for_keg(keg) - yield tab - tab.write - end - - # 1.1.6 is the earliest version of Homebrew that generates correct runtime - # dependency lists in {Tab}s. - def dependencies(deps, homebrew_version: "1.1.6") - alter_tab do |tab| - tab.homebrew_version = homebrew_version - tab.tabfile = dependent/Tab::FILENAME - tab.runtime_dependencies = deps - end - end - - def unreliable_dependencies(deps) - # 1.1.5 is (hopefully!) the last version of Homebrew that generates - # incorrect runtime dependency lists in {Tab}s. - dependencies(deps, homebrew_version: "1.1.5") - end - - let(:dependent) { setup_test_keg("bar", "1.0") } - - specify "a dependency with no Tap in Tab" do - tap_dep = setup_test_keg("baz", "1.0") - - # allow tap_dep to be linked too - FileUtils.rm_r tap_dep/"bin" - tap_dep.link - - alter_tab(keg) { |t| t.source["tap"] = nil } - - dependencies nil - Formula["bar"].class.depends_on "foo" - Formula["bar"].class.depends_on "baz" - - result = described_class.find_some_installed_dependents([keg, tap_dep]) - expect(result).to eq([[keg, tap_dep], ["bar"]]) - end - - specify "no dependencies anywhere" do - dependencies nil - expect(described_class.find_some_installed_dependents([keg])).to be nil - end - - specify "missing Formula dependency" do - dependencies nil - Formula["bar"].class.depends_on "foo" - expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) - end - - specify "uninstalling dependent and dependency" do - dependencies nil - Formula["bar"].class.depends_on "foo" - expect(described_class.find_some_installed_dependents([keg, dependent])).to be nil - end - - specify "renamed dependency" do - dependencies nil - - stub_formula_loader Formula["foo"], "homebrew/core/foo-old" - renamed_path = HOMEBREW_CELLAR/"foo-old" - (HOMEBREW_CELLAR/"foo").rename(renamed_path) - renamed_keg = described_class.new(renamed_path/"1.0") - - Formula["bar"].class.depends_on "foo" - - result = described_class.find_some_installed_dependents([renamed_keg]) - expect(result).to eq([[renamed_keg], ["bar"]]) - end - - specify "empty dependencies in Tab" do - dependencies [] - expect(described_class.find_some_installed_dependents([keg])).to be nil - end - - specify "same name but different version in Tab" do - dependencies [{ "full_name" => "foo", "version" => "1.1" }] - expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) - end - - specify "different name and same version in Tab" do - stub_formula_name("baz") - dependencies [{ "full_name" => "baz", "version" => keg.version.to_s }] - expect(described_class.find_some_installed_dependents([keg])).to be nil - end - - specify "same name and version in Tab" do - dependencies [{ "full_name" => "foo", "version" => "1.0" }] - expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) - end - - specify "fallback for old versions" do - unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }] - Formula["bar"].class.depends_on "foo" - expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) - end - - specify "non-opt-linked" do - keg.remove_opt_record - dependencies [{ "full_name" => "foo", "version" => "1.0" }] - expect(described_class.find_some_installed_dependents([keg])).to be nil - end - - specify "keg-only" do - keg.unlink - Formula["foo"].class.keg_only "a good reason" - dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version - expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]]) - end - end end diff --git a/Library/Homebrew/test/language/node_spec.rb b/Library/Homebrew/test/language/node_spec.rb index 5202296e40..5aaac0f581 100644 --- a/Library/Homebrew/test/language/node_spec.rb +++ b/Library/Homebrew/test/language/node_spec.rb @@ -4,7 +4,7 @@ require "language/node" describe Language::Node do - let(:npm_pack_cmd) { "npm pack --ignore-scripts" } + let(:npm_pack_cmd) { ["npm", "pack", "--ignore-scripts"] } describe "#setup_npm_environment" do it "calls prepend_path when node formula exists only during the first call" do @@ -31,7 +31,7 @@ describe Language::Node do mktmpdir.cd do path = Pathname("package.json") path.atomic_write("{\"scripts\":{\"prepare\": \"ls\", \"prepack\": \"ls\", \"test\": \"ls\"}}") - allow(Utils).to receive(:popen_read).with(npm_pack_cmd).and_return(`echo pack.tgz`) + allow(Utils).to receive(:popen_read).with(*npm_pack_cmd).and_return(`echo pack.tgz`) described_class.pack_for_installation expect(path.read).not_to include("prepare") expect(path.read).not_to include("prepack") @@ -44,19 +44,19 @@ describe Language::Node do npm_install_arg = Pathname("libexec") it "raises error with non zero exitstatus" do - allow(Utils).to receive(:popen_read).with(npm_pack_cmd).and_return(`false`) + allow(Utils).to receive(:popen_read).with(*npm_pack_cmd).and_return(`false`) expect { described_class.std_npm_install_args(npm_install_arg) }.to \ raise_error("npm failed to pack #{Dir.pwd}") end it "raises error with empty npm pack output" do - allow(Utils).to receive(:popen_read).with(npm_pack_cmd).and_return(`true`) + allow(Utils).to receive(:popen_read).with(*npm_pack_cmd).and_return(`true`) expect { described_class.std_npm_install_args(npm_install_arg) }.to \ raise_error("npm failed to pack #{Dir.pwd}") end it "does not raise error with a zero exitstatus" do - allow(Utils).to receive(:popen_read).with(npm_pack_cmd).and_return(`echo pack.tgz`) + allow(Utils).to receive(:popen_read).with(*npm_pack_cmd).and_return(`echo pack.tgz`) resp = described_class.std_npm_install_args(npm_install_arg) expect(resp).to include("--prefix=#{npm_install_arg}", "#{Dir.pwd}/pack.tgz") end diff --git a/Library/Homebrew/test/language/python/virtualenv_spec.rb b/Library/Homebrew/test/language/python/virtualenv_spec.rb index 948363dda3..07ab7bcf35 100644 --- a/Library/Homebrew/test/language/python/virtualenv_spec.rb +++ b/Library/Homebrew/test/language/python/virtualenv_spec.rb @@ -24,7 +24,7 @@ describe Language::Python::Virtualenv::Virtualenv, :needs_python do it "accepts a string" do expect(formula).to receive(:system) .with(dir/"bin/pip", "install", "-v", "--no-deps", - "--no-binary", ":all:", "--no-user", "--ignore-installed", "foo") + "--no-binary", ":all:", "--ignore-installed", "foo") .and_return(true) virtualenv.pip_install "foo" end @@ -32,7 +32,7 @@ describe Language::Python::Virtualenv::Virtualenv, :needs_python do it "accepts a multi-line strings" do expect(formula).to receive(:system) .with(dir/"bin/pip", "install", "-v", "--no-deps", - "--no-binary", ":all:", "--no-user", "--ignore-installed", "foo", "bar") + "--no-binary", ":all:", "--ignore-installed", "foo", "bar") .and_return(true) virtualenv.pip_install <<~EOS @@ -44,12 +44,12 @@ describe Language::Python::Virtualenv::Virtualenv, :needs_python do it "accepts an array" do expect(formula).to receive(:system) .with(dir/"bin/pip", "install", "-v", "--no-deps", - "--no-binary", ":all:", "--no-user", "--ignore-installed", "foo") + "--no-binary", ":all:", "--ignore-installed", "foo") .and_return(true) expect(formula).to receive(:system) .with(dir/"bin/pip", "install", "-v", "--no-deps", - "--no-binary", ":all:", "--no-user", "--ignore-installed", "bar") + "--no-binary", ":all:", "--ignore-installed", "bar") .and_return(true) virtualenv.pip_install ["foo", "bar"] @@ -61,7 +61,7 @@ describe Language::Python::Virtualenv::Virtualenv, :needs_python do expect(res).to receive(:stage).and_yield expect(formula).to receive(:system) .with(dir/"bin/pip", "install", "-v", "--no-deps", - "--no-binary", ":all:", "--no-user", "--ignore-installed", Pathname.pwd) + "--no-binary", ":all:", "--ignore-installed", Pathname.pwd) .and_return(true) virtualenv.pip_install res diff --git a/Library/Homebrew/test/linkage_cache_store_spec.rb b/Library/Homebrew/test/linkage_cache_store_spec.rb index 2d821ce953..f03bf3f1bb 100644 --- a/Library/Homebrew/test/linkage_cache_store_spec.rb +++ b/Library/Homebrew/test/linkage_cache_store_spec.rb @@ -10,14 +10,14 @@ describe LinkageCacheStore do let(:database) { double("database") } describe "#keg_exists?" do - context "`keg_name` exists in cache" do + context "when `keg_name` exists in cache" do it "returns `true`" do expect(database).to receive(:get).with(keg_name).and_return("") expect(linkage_cache.keg_exists?).to be(true) end end - context "`keg_name` does not exist in cache" do + context "when `keg_name` does not exist in cache" do it "returns `false`" do expect(database).to receive(:get).with(keg_name).and_return(nil) expect(linkage_cache.keg_exists?).to be(false) @@ -26,14 +26,14 @@ describe LinkageCacheStore do end describe "#update!" do - context "a `value` is a `Hash`" do + context "when a `value` is a `Hash`" do it "sets the cache for the `keg_name`" do expect(database).to receive(:set).with(keg_name, anything) linkage_cache.update!(keg_files_dylibs: { key: ["value"] }) end end - context "a `value` is not a `Hash`" do + context "when a `value` is not a `Hash`" do it "raises a `TypeError` if a `value` is not a `Hash`" do expect { linkage_cache.update!(a_value: ["value"]) }.to raise_error(TypeError) end @@ -48,14 +48,14 @@ describe LinkageCacheStore do end describe "#fetch" do - context "`HASH_LINKAGE_TYPES.include?(type)`" do + context "when `HASH_LINKAGE_TYPES.include?(type)`" do it "returns a `Hash` of values" do expect(database).to receive(:get).with(keg_name).and_return(nil) expect(linkage_cache.fetch(:keg_files_dylibs)).to be_an_instance_of(Hash) end end - context "`type` not in `HASH_LINKAGE_TYPES`" do + context "when `type` is not in `HASH_LINKAGE_TYPES`" do it "raises a `TypeError` if the `type` is not supported" do expect { linkage_cache.fetch(:bad_type) }.to raise_error(TypeError) end diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 3b5df88553..5bdbfd9aba 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -68,13 +68,13 @@ describe Homebrew::Livecheck do it "returns a hash containing the livecheck status" do expect(livecheck.status_hash(f, "error", ["Unable to get versions"])) .to eq({ - formula: "test", - status: "error", - messages: ["Unable to get versions"], - meta: { - livecheckable: true, - }, - }) + formula: "test", + status: "error", + messages: ["Unable to get versions"], + meta: { + livecheckable: true, + }, + }) end end diff --git a/Library/Homebrew/test/livecheck/skip_conditions_spec.rb b/Library/Homebrew/test/livecheck/skip_conditions_spec.rb index 1a60197a57..988e4a01ea 100644 --- a/Library/Homebrew/test/livecheck/skip_conditions_spec.rb +++ b/Library/Homebrew/test/livecheck/skip_conditions_spec.rb @@ -265,56 +265,56 @@ describe Homebrew::Livecheck::SkipConditions do end describe "::skip_conditions" do - context "a deprecated formula without a livecheckable" do + context "when a formula without a livecheckable is deprecated" do it "skips" do expect(skip_conditions.skip_information(formulae[:deprecated])) .to eq(status_hashes[:formula][:deprecated]) end end - context "a disabled formula without a livecheckable" do + context "when a formula without a livecheckable is disabled" do it "skips" do expect(skip_conditions.skip_information(formulae[:disabled])) .to eq(status_hashes[:formula][:disabled]) end end - context "a versioned formula without a livecheckable" do + context "when a formula without a livecheckable is versioned" do it "skips" do expect(skip_conditions.skip_information(formulae[:versioned])) .to eq(status_hashes[:formula][:versioned]) end end - context "a HEAD-only formula that is not installed" do + context "when a formula is HEAD-only and not installed" do it "skips " do expect(skip_conditions.skip_information(formulae[:head_only])) .to eq(status_hashes[:formula][:head_only]) end end - context "a formula with a GitHub Gist stable URL" do + context "when a formula has a GitHub Gist stable URL" do it "skips" do expect(skip_conditions.skip_information(formulae[:gist])) .to eq(status_hashes[:formula][:gist]) end end - context "a formula with a Google Code Archive stable URL" do + context "when a formula has a Google Code Archive stable URL" do it "skips" do expect(skip_conditions.skip_information(formulae[:google_code_archive])) .to eq(status_hashes[:formula][:google_code_archive]) end end - context "a formula with an Internet Archive stable URL" do + context "when a formula has an Internet Archive stable URL" do it "skips" do expect(skip_conditions.skip_information(formulae[:internet_archive])) .to eq(status_hashes[:formula][:internet_archive]) end end - context "a formula with a `livecheck` block containing `skip`" do + context "when a formula has a `livecheck` block containing `skip`" do it "skips" do expect(skip_conditions.skip_information(formulae[:skip])) .to eq(status_hashes[:formula][:skip]) @@ -324,28 +324,28 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a discontinued cask without a livecheckable" do + context "when a cask without a livecheckable is discontinued" do it "skips" do expect(skip_conditions.skip_information(casks[:discontinued])) .to eq(status_hashes[:cask][:discontinued]) end end - context "a cask containing `version :latest` without a livecheckable" do + context "when a cask without a livecheckable has `version :latest`" do it "skips" do expect(skip_conditions.skip_information(casks[:latest])) .to eq(status_hashes[:cask][:latest]) end end - context "a cask containing an unversioned URL without a livecheckable" do + context "when a cask without a livecheckable has an unversioned URL" do it "skips" do expect(skip_conditions.skip_information(casks[:unversioned])) .to eq(status_hashes[:cask][:unversioned]) end end - context "a cask with a `livecheck` block containing `skip`" do + context "when a cask has a `livecheck` block containing `skip`" do it "skips" do expect(skip_conditions.skip_information(casks[:skip])) .to eq(status_hashes[:cask][:skip]) @@ -365,7 +365,7 @@ describe Homebrew::Livecheck::SkipConditions do end describe "::print_skip_information" do - context "a deprecated formula without a livecheckable" do + context "when a formula without a livecheckable is deprecated" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:deprecated]) } .to output("test_deprecated : deprecated\n").to_stdout @@ -373,7 +373,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a disabled formula without a livecheckable" do + context "when a formula without a livecheckable is disabled" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:disabled]) } .to output("test_disabled : disabled\n").to_stdout @@ -381,7 +381,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a versioned formula without a livecheckable" do + context "when a formula without a livecheckable is versioned" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:versioned]) } .to output("test@0.0.1 : versioned\n").to_stdout @@ -389,7 +389,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a HEAD-only formula that is not installed" do + context "when a formula is HEAD-only and not installed" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:head_only]) } .to output("test_head_only : HEAD only formula must be installed to be livecheckable\n").to_stdout @@ -397,7 +397,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a formula with a GitHub Gist stable URL" do + context "when a formula has a GitHub Gist stable URL" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:gist]) } .to output("test_gist : skipped - Stable URL is a GitHub Gist\n").to_stdout @@ -405,7 +405,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a formula with a Google Code Archive stable URL" do + context "when a formula has a Google Code Archive stable URL" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:google_code_archive]) } .to output("test_google_code_archive : skipped - Stable URL is from Google Code Archive\n").to_stdout @@ -413,7 +413,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a formula with an Internet Archive stable URL" do + context "when a formula has an Internet Archive stable URL" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:internet_archive]) } .to output("test_internet_archive : skipped - Stable URL is from Internet Archive\n").to_stdout @@ -421,7 +421,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a formula with a `livecheck` block containing `skip`" do + context "when a formula has a `livecheck` block containing `skip`" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:formula][:skip]) } .to output("test_skip : skipped\n").to_stdout @@ -433,7 +433,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a discontinued cask without a livecheckable" do + context "when the cask is discontinued without a livecheckable" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:cask][:discontinued]) } .to output("test_discontinued : discontinued\n").to_stdout @@ -441,7 +441,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a cask containing `version :latest` without a livecheckable" do + context "when the cask has `version :latest` without a livecheckable" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:cask][:latest]) } .to output("test_latest : latest\n").to_stdout @@ -449,7 +449,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a cask containing an unversioned URL without a livecheckable" do + context "when the cask has an unversioned URL without a livecheckable" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:cask][:unversioned]) } .to output("test_unversioned : unversioned\n").to_stdout @@ -457,7 +457,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a cask with a `livecheck` block containing `skip`" do + context "when the cask has a `livecheck` block containing `skip`" do it "prints skip information" do expect { skip_conditions.print_skip_information(status_hashes[:cask][:skip]) } .to output("test_skip : skipped\n").to_stdout @@ -469,7 +469,7 @@ describe Homebrew::Livecheck::SkipConditions do end end - context "a blank parameter" do + context "with a blank parameter" do it "prints nothing" do expect { skip_conditions.print_skip_information({}) } .to not_to_output.to_stdout diff --git a/Library/Homebrew/test/locale_spec.rb b/Library/Homebrew/test/locale_spec.rb index f36b9a1ba7..e704fe87b0 100644 --- a/Library/Homebrew/test/locale_spec.rb +++ b/Library/Homebrew/test/locale_spec.rb @@ -16,7 +16,7 @@ describe Locale do expect(described_class.parse("es-419")).to eql(described_class.new("es", "419", nil)) end - context "raises a ParserError when given" do + describe "raises a ParserError when given" do it "an empty string" do expect { described_class.parse("") }.to raise_error(Locale::ParserError) end @@ -60,12 +60,12 @@ describe Locale do describe "#eql?" do subject(:locale) { described_class.new("zh", "CN", "Hans") } - context "all parts match" do + context "when all parts match" do it { is_expected.to eql("zh-CN-Hans") } it { is_expected.to eql(locale) } end - context "only some parts match" do + context "when only some parts match" do it { is_expected.not_to eql("zh") } it { is_expected.not_to eql("zh-CN") } it { is_expected.not_to eql("CN") } diff --git a/Library/Homebrew/test/missing_formula_spec.rb b/Library/Homebrew/test/missing_formula_spec.rb index e6b2dd644a..6c0530e031 100644 --- a/Library/Homebrew/test/missing_formula_spec.rb +++ b/Library/Homebrew/test/missing_formula_spec.rb @@ -118,7 +118,7 @@ describe Homebrew::MissingFormula do describe "::suggest_command", :cask do subject { described_class.suggest_command(name, command) } - context "brew install" do + context "when installing" do let(:name) { "local-caffeine" } let(:command) { "install" } @@ -126,7 +126,7 @@ describe Homebrew::MissingFormula do it { is_expected.to match(/Try\n brew install --cask local-caffeine/) } end - context "brew uninstall" do + context "when uninstalling" do let(:name) { "local-caffeine" } let(:command) { "uninstall" } @@ -142,7 +142,7 @@ describe Homebrew::MissingFormula do end end - context "brew info" do + context "when getting info" do let(:name) { "local-caffeine" } let(:command) { "info" } diff --git a/Library/Homebrew/test/os/linux/formula_spec.rb b/Library/Homebrew/test/os/linux/formula_spec.rb index 6a38602109..412284a9a5 100644 --- a/Library/Homebrew/test/os/linux/formula_spec.rb +++ b/Library/Homebrew/test/os/linux/formula_spec.rb @@ -56,9 +56,7 @@ describe Formula do expect(f.class.stable.deps[1].name).to eq("hello_linux") expect(f.class.stable.deps[2]).to eq(nil) end - end - describe "#on_linux" do it "adds a patch on Linux only" do f = formula do homepage "https://brew.sh" @@ -81,9 +79,7 @@ describe Formula do expect(f.patchlist.first.strip).to eq(:p1) expect(f.patchlist.first.url).to eq("patch_linux") end - end - describe "#on_linux" do it "uses on_linux within a resource block" do f = formula do homepage "https://brew.sh" diff --git a/Library/Homebrew/test/os/mac/diagnostic_spec.rb b/Library/Homebrew/test/os/mac/diagnostic_spec.rb index f58aef8cff..e81993cd8f 100644 --- a/Library/Homebrew/test/os/mac/diagnostic_spec.rb +++ b/Library/Homebrew/test/os/mac/diagnostic_spec.rb @@ -39,4 +39,76 @@ describe Homebrew::Diagnostic::Checks do expect(checks.check_ruby_version) .to match "Ruby version 1.8.6 is unsupported on 10.12" end + + describe "#check_if_supported_sdk_available" do + let(:macos_version) { OS::Mac::Version.new("11") } + + before do + allow(DevelopmentTools).to receive(:installed?).and_return(true) + allow(OS::Mac).to receive(:version).and_return(macos_version) + end + + it "doesn't trigger when SDK root is not needed" do + allow(OS::Mac).to receive(:sdk_root_needed?).and_return(false) + allow(OS::Mac).to receive(:sdk).and_return(nil) + + expect(checks.check_if_supported_sdk_available).to be_nil + end + + it "doesn't trigger when a valid SDK is present" do + allow(OS::Mac).to receive(:sdk_root_needed?).and_return(true) + allow(OS::Mac).to receive(:sdk).and_return(OS::Mac::SDK.new(macos_version, "/some/path/MacOSX.sdk", :clt)) + + expect(checks.check_if_supported_sdk_available).to be_nil + end + + it "triggers when a valid SDK is not present on CLT systems" do + allow(OS::Mac).to receive(:sdk_root_needed?).and_return(true) + allow(OS::Mac).to receive(:sdk).and_return(nil) + allow(OS::Mac).to receive(:sdk_locator).and_return(OS::Mac::CLT.sdk_locator) + + expect(checks.check_if_supported_sdk_available) + .to include("Your Command Line Tools (CLT) does not support macOS #{macos_version}") + end + + it "triggers when a valid SDK is not present on Xcode systems" do + allow(OS::Mac).to receive(:sdk_root_needed?).and_return(true) + allow(OS::Mac).to receive(:sdk).and_return(nil) + allow(OS::Mac).to receive(:sdk_locator).and_return(OS::Mac::Xcode.sdk_locator) + + expect(checks.check_if_supported_sdk_available) + .to include("Your Xcode does not support macOS #{macos_version}") + end + end + + describe "#check_broken_sdks" do + it "doesn't trigger when SDK versions are as expected" do + allow(OS::Mac).to receive(:sdk_locator).and_return(OS::Mac::CLT.sdk_locator) + allow_any_instance_of(OS::Mac::CLTSDKLocator).to receive(:all_sdks).and_return([ + OS::Mac::SDK.new(OS::Mac::Version.new("11"), "/some/path/MacOSX.sdk", :clt), + OS::Mac::SDK.new(OS::Mac::Version.new("10.15"), "/some/path/MacOSX10.15.sdk", :clt), + ]) + + expect(checks.check_broken_sdks).to be_nil + end + + it "triggers when the CLT SDK version doesn't match the folder name" do + allow_any_instance_of(OS::Mac::CLTSDKLocator).to receive(:all_sdks).and_return([ + OS::Mac::SDK.new(OS::Mac::Version.new("10.14"), "/some/path/MacOSX10.15.sdk", :clt), + ]) + + expect(checks.check_broken_sdks) + .to include("SDKs in your Command Line Tools (CLT) installation do not match the SDK folder names") + end + + it "triggers when the Xcode SDK version doesn't match the folder name" do + allow(OS::Mac).to receive(:sdk_locator).and_return(OS::Mac::Xcode.sdk_locator) + allow_any_instance_of(OS::Mac::XcodeSDKLocator).to receive(:all_sdks).and_return([ + OS::Mac::SDK.new(OS::Mac::Version.new("10.14"), "/some/path/MacOSX10.15.sdk", :xcode), + ]) + + expect(checks.check_broken_sdks) + .to include("The contents of the SDKs in your Xcode installation do not match the SDK folder names") + end + end end diff --git a/Library/Homebrew/test/os/mac/formula_spec.rb b/Library/Homebrew/test/os/mac/formula_spec.rb index f41812a072..762d5b02af 100644 --- a/Library/Homebrew/test/os/mac/formula_spec.rb +++ b/Library/Homebrew/test/os/mac/formula_spec.rb @@ -61,9 +61,7 @@ describe Formula do expect(f.class.stable.deps[1].name).to eq("hello_macos") expect(f.class.stable.deps[2]).to eq(nil) end - end - describe "#on_macos" do it "adds a patch on Mac only" do f = formula do homepage "https://brew.sh" @@ -86,9 +84,7 @@ describe Formula do expect(f.patchlist.first.strip).to eq(:p1) expect(f.patchlist.first.url).to eq("patch_macos") end - end - describe "#on_macos" do it "uses on_macos within a resource block" do f = formula do homepage "https://brew.sh" diff --git a/Library/Homebrew/test/os/mac/sdk_spec.rb b/Library/Homebrew/test/os/mac/sdk_spec.rb new file mode 100644 index 0000000000..55c18aa221 --- /dev/null +++ b/Library/Homebrew/test/os/mac/sdk_spec.rb @@ -0,0 +1,97 @@ +# typed: false +# frozen_string_literal: true + +describe OS::Mac::CLTSDKLocator do + subject(:locator) { described_class.new } + + let(:big_sur_sdk) { OS::Mac::SDK.new(OS::Mac::Version.new("11"), "/some/path/MacOSX.sdk", :clt) } + let(:catalina_sdk) { OS::Mac::SDK.new(OS::Mac::Version.new("10.15"), "/some/path/MacOSX10.15.sdk", :clt) } + + specify "#sdk_for" do + allow(locator).to receive(:all_sdks).and_return([big_sur_sdk, catalina_sdk]) + + expect(locator.sdk_for(OS::Mac::Version.new("11"))).to eq(big_sur_sdk) + expect(locator.sdk_for(OS::Mac::Version.new("10.15"))).to eq(catalina_sdk) + expect { locator.sdk_for(OS::Mac::Version.new("10.14")) }.to raise_error(described_class::NoSDKError) + end + + describe "#sdk_if_applicable" do + before do + allow(locator).to receive(:all_sdks).and_return([big_sur_sdk, catalina_sdk]) + end + + it "returns the requested SDK" do + expect(locator.sdk_if_applicable(OS::Mac::Version.new("11"))).to eq(big_sur_sdk) + expect(locator.sdk_if_applicable(OS::Mac::Version.new("10.15"))).to eq(catalina_sdk) + end + + it "returns the latest SDK if the requested version is not found" do + expect(locator.sdk_if_applicable(OS::Mac::Version.new("10.14"))).to eq(big_sur_sdk) + expect(locator.sdk_if_applicable(OS::Mac::Version.new("12"))).to eq(big_sur_sdk) + end + + it "returns the SDK matching the OS version if no version is specified" do + allow(OS::Mac).to receive(:version).and_return(OS::Mac::Version.new("10.15")) + expect(locator.sdk_if_applicable).to eq(catalina_sdk) + end + + it "returns the latest SDK on older OS versions when there's no matching SDK" do + allow(OS::Mac).to receive(:version).and_return(OS::Mac::Version.new("10.14")) + expect(locator.sdk_if_applicable).to eq(big_sur_sdk) + end + + it "returns nil if the OS is newer than all SDKs" do + allow(OS::Mac).to receive(:version).and_return(OS::Mac::Version.new("12")) + expect(locator.sdk_if_applicable).to be_nil + end + end + + describe "#all_sdks" do + let(:big_sur_sdk_prefix) { TEST_FIXTURE_DIR/"sdks/big_sur" } + let(:mojave_broken_sdk_prefix) { TEST_FIXTURE_DIR/"sdks/mojave_broken" } + let(:high_sierra_sdk_prefix) { TEST_FIXTURE_DIR/"sdks/high_sierra" } + let(:malformed_sdk_prefix) { TEST_FIXTURE_DIR/"sdks/malformed" } + + it "reads the SDKSettings.json version of unversioned SDKs folders" do + allow(locator).to receive(:sdk_prefix).and_return(big_sur_sdk_prefix.to_s) + + sdks = locator.all_sdks + expect(sdks.count).to eq(1) + + sdk = sdks.first + expect(sdk.path).to eq(big_sur_sdk_prefix/"MacOSX.sdk") + expect(sdk.version).to eq(OS::Mac::Version.new("11")) + expect(sdk.source).to eq(:clt) + end + + it "reads the SDKSettings.json version of versioned SDKs folders" do + allow(locator).to receive(:sdk_prefix).and_return(mojave_broken_sdk_prefix.to_s) + + sdks = locator.all_sdks + expect(sdks.count).to eq(1) + + sdk = sdks.first + expect(sdk.path).to eq(mojave_broken_sdk_prefix/"MacOSX10.14.sdk") + expect(sdk.version).to eq(OS::Mac::Version.new("10.15")) + expect(sdk.source).to eq(:clt) + end + + it "reads the SDKSettings.plist version" do + allow(locator).to receive(:sdk_prefix).and_return(high_sierra_sdk_prefix.to_s) + + sdks = locator.all_sdks + expect(sdks.count).to eq(1) + + sdk = sdks.first + expect(sdk.path).to eq(high_sierra_sdk_prefix/"MacOSX10.13.sdk") + expect(sdk.version).to eq(OS::Mac::Version.new("10.13")) + expect(sdk.source).to eq(:clt) + end + + it "rejects malformed sdks" do + allow(locator).to receive(:sdk_prefix).and_return(malformed_sdk_prefix.to_s) + + expect(locator.all_sdks).to be_empty + end + end +end diff --git a/Library/Homebrew/test/os/mac/version_spec.rb b/Library/Homebrew/test/os/mac/version_spec.rb index 7c835fbdf5..c69e0239bc 100644 --- a/Library/Homebrew/test/os/mac/version_spec.rb +++ b/Library/Homebrew/test/os/mac/version_spec.rb @@ -40,7 +40,7 @@ describe OS::Mac::Version do expect(version).to be < Version.create("10.15") end - context "after Big Sur" do + describe "after Big Sur" do specify "comparison with :big_sur" do expect(big_sur_major).to eq :big_sur expect(big_sur_major).to be <= :big_sur diff --git a/Library/Homebrew/test/patch_spec.rb b/Library/Homebrew/test/patch_spec.rb index 2c4dbd2952..f39f22553a 100644 --- a/Library/Homebrew/test/patch_spec.rb +++ b/Library/Homebrew/test/patch_spec.rb @@ -5,7 +5,7 @@ require "patch" describe Patch do describe "#create" do - context "simple patch" do + context "with a simple patch" do subject { described_class.create(:p2, nil) } it { is_expected.to be_kind_of ExternalPatch } @@ -13,28 +13,28 @@ describe Patch do its(:strip) { is_expected.to eq(:p2) } end - context "string patch" do + context "with a string patch" do subject { described_class.create(:p0, "foo") } it { is_expected.to be_kind_of StringPatch } its(:strip) { is_expected.to eq(:p0) } end - context "string patch without strip" do + context "with a string patch without strip" do subject { described_class.create("foo", nil) } it { is_expected.to be_kind_of StringPatch } its(:strip) { is_expected.to eq(:p1) } end - context "data patch" do + context "with a data patch" do subject { described_class.create(:p0, :DATA) } it { is_expected.to be_kind_of DATAPatch } its(:strip) { is_expected.to eq(:p0) } end - context "data patch without strip" do + context "with a data patch without strip" do subject { described_class.create(:DATA, nil) } it { is_expected.to be_kind_of DATAPatch } @@ -55,7 +55,7 @@ describe Patch do describe "#patch_files" do subject(:patch) { described_class.create(:p2, nil) } - context "empty patch" do + context "when the patch is empty" do its(:resource) { is_expected.to be_kind_of Resource::PatchResource } its(:patch_files) { is_expected.to eq(patch.resource.patch_files) } its(:patch_files) { is_expected.to eq([]) } diff --git a/Library/Homebrew/test/requirement_spec.rb b/Library/Homebrew/test/requirement_spec.rb index 7e082d2b0f..4fe5cad5a1 100644 --- a/Library/Homebrew/test/requirement_spec.rb +++ b/Library/Homebrew/test/requirement_spec.rb @@ -14,25 +14,25 @@ describe Requirement do describe "#tags" do subject { described_class.new(tags) } - context "single tag" do + context "with a single tag" do let(:tags) { ["bar"] } its(:tags) { are_expected.to eq(tags) } end - context "multiple tags" do + context "with multiple tags" do let(:tags) { ["bar", "baz"] } its(:tags) { are_expected.to eq(tags) } end - context "symbol tags" do + context "with symbol tags" do let(:tags) { [:build] } its(:tags) { are_expected.to eq(tags) } end - context "symbol and string tags" do + context "with symbol and string tags" do let(:tags) { [:build, "bar"] } its(:tags) { are_expected.to eq(tags) } @@ -148,7 +148,7 @@ describe Requirement do end describe "#build?" do - context ":build tag is specified" do + context "when the :build tag is specified" do subject { described_class.new([:build]) } it { is_expected.to be_a_build_requirement } diff --git a/Library/Homebrew/test/rubocops/bottle/bottle_format_spec.rb b/Library/Homebrew/test/rubocops/bottle/bottle_format_spec.rb index 2a080b0ab3..408d08747d 100644 --- a/Library/Homebrew/test/rubocops/bottle/bottle_format_spec.rb +++ b/Library/Homebrew/test/rubocops/bottle/bottle_format_spec.rb @@ -65,7 +65,7 @@ describe RuboCop::Cop::FormulaAudit::BottleFormat do RUBY end - it "reports and corrects old `sha256` syntax in `bottle` block without cellars" do + it "reports and corrects old `sha256` syntax in `bottle` block with cellars" do expect_offense(<<~RUBY) class Foo < Formula url "https://brew.sh/foo-1.0.tgz" diff --git a/Library/Homebrew/test/rubocops/components_order_spec.rb b/Library/Homebrew/test/rubocops/components_order_spec.rb index c050472781..42ce5b9759 100644 --- a/Library/Homebrew/test/rubocops/components_order_spec.rb +++ b/Library/Homebrew/test/rubocops/components_order_spec.rb @@ -491,7 +491,7 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do RUBY end - context "in a resource block" do + context "when in a resource block" do it "reports no offenses for a valid `on_macos` and `on_linux` block" do expect_no_offenses(<<~RUBY) class Foo < Formula diff --git a/Library/Homebrew/test/rubocops/formula_desc_spec.rb b/Library/Homebrew/test/rubocops/formula_desc_spec.rb index f0b4f1a140..bef0ca1a18 100644 --- a/Library/Homebrew/test/rubocops/formula_desc_spec.rb +++ b/Library/Homebrew/test/rubocops/formula_desc_spec.rb @@ -6,7 +6,7 @@ require "rubocops/formula_desc" describe RuboCop::Cop::FormulaAudit::Desc do subject(:cop) { described_class.new } - context "When auditing formula `desc` methods" do + context "when auditing formula `desc` methods" do it "reports an offense when there is no `desc`" do expect_offense(<<~RUBY) class Foo < Formula @@ -48,7 +48,7 @@ describe RuboCop::Cop::FormulaAudit::Desc do end end - context "When auditing formula description texts" do + context "when auditing formula description texts" do it "reports an offense when the description starts with a leading space" do expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb") class Foo < Formula diff --git a/Library/Homebrew/test/rubocops/homepage_spec.rb b/Library/Homebrew/test/rubocops/homepage_spec.rb index 023ac46318..99df59c53e 100644 --- a/Library/Homebrew/test/rubocops/homepage_spec.rb +++ b/Library/Homebrew/test/rubocops/homepage_spec.rb @@ -80,7 +80,7 @@ describe RuboCop::Cop::FormulaAudit::Homepage do RUBY end - context "for Sourceforge" do + describe "for Sourceforge" do correct_formula = <<~RUBY class Foo < Formula homepage "https://foo.sourceforge.io/" diff --git a/Library/Homebrew/test/rubocops/patches_spec.rb b/Library/Homebrew/test/rubocops/patches_spec.rb index 1e903ca805..6a7db5908f 100644 --- a/Library/Homebrew/test/rubocops/patches_spec.rb +++ b/Library/Homebrew/test/rubocops/patches_spec.rb @@ -54,23 +54,19 @@ describe RuboCop::Cop::FormulaAudit::Patches do expected_offense = if patch_url.include?("/raw.github.com/") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source - GitHub/Gist patches should specify a revision: - #{patch_url} + GitHub/Gist patches should specify a revision: #{patch_url} EOS elsif patch_url.include?("macports/trunk") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source - MacPorts patches should specify a revision instead of trunk: - #{patch_url} + MacPorts patches should specify a revision instead of trunk: #{patch_url} EOS elsif patch_url.start_with?("http://trac.macports.org") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source - Patches from MacPorts Trac should be https://, not http: - #{patch_url} + Patches from MacPorts Trac should be https://, not http: #{patch_url} EOS elsif patch_url.start_with?("http://bugs.debian.org") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source - Patches from Debian should be https://, not http: - #{patch_url} + Patches from Debian should be https://, not http: #{patch_url} EOS # rubocop:disable Layout/LineLength elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}) @@ -78,9 +74,8 @@ describe RuboCop::Cop::FormulaAudit::Patches do expect_offense_hash message: "Use a commit hash URL rather than patch-diff: #{patch_url}", severity: :convention, line: 5, column: 4, source: source elsif patch_url.match?(%r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)}) - expect_offense_hash message: <<~EOS, severity: :convention, line: 5, column: 4, source: source - GitHub patches should use the full_index parameter: - #{patch_url}?full_index=1 + expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + GitHub patches should use the full_index parameter: #{patch_url}?full_index=1 EOS end expected_offense.zip([inspect_source(source).last]).each do |expected, actual| @@ -112,11 +107,8 @@ describe RuboCop::Cop::FormulaAudit::Patches do line: 4, column: 2, source: source }, - { message: - <<~EOS.chomp, - Patches from MacPorts Trac should be https://, not http: - http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/ - EOS + { message: "Patches from MacPorts Trac should be https://, not http: " \ + "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/", severity: :convention, line: 8, column: 25, @@ -205,23 +197,19 @@ describe RuboCop::Cop::FormulaAudit::Patches do expected_offense = if patch_url.include?("/raw.github.com/") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - GitHub/Gist patches should specify a revision: - #{patch_url} + GitHub/Gist patches should specify a revision: #{patch_url} EOS elsif patch_url.include?("macports/trunk") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - MacPorts patches should specify a revision instead of trunk: - #{patch_url} + MacPorts patches should specify a revision instead of trunk: #{patch_url} EOS elsif patch_url.start_with?("http://trac.macports.org") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - Patches from MacPorts Trac should be https://, not http: - #{patch_url} + Patches from MacPorts Trac should be https://, not http: #{patch_url} EOS elsif patch_url.start_with?("http://bugs.debian.org") expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - Patches from Debian should be https://, not http: - #{patch_url} + Patches from Debian should be https://, not http: #{patch_url} EOS elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/pull}) expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source @@ -233,13 +221,11 @@ describe RuboCop::Cop::FormulaAudit::Patches do EOS elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/commit/}) expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - GitHub patches should end with .patch, not .diff: - #{patch_url} + GitHub patches should end with .patch, not .diff: #{patch_url} EOS elsif patch_url.match?(%r{.*gitlab.*/commit/}) expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source - GitLab patches should end with .patch, not .diff: - #{patch_url} + GitLab patches should end with .patch, not .diff: #{patch_url} EOS # rubocop:disable Layout/LineLength elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}) diff --git a/Library/Homebrew/test/rubocops/text/shell_commands_spec.rb b/Library/Homebrew/test/rubocops/shell_commands_spec.rb similarity index 98% rename from Library/Homebrew/test/rubocops/text/shell_commands_spec.rb rename to Library/Homebrew/test/rubocops/shell_commands_spec.rb index 9699092063..60ee8aac3a 100644 --- a/Library/Homebrew/test/rubocops/text/shell_commands_spec.rb +++ b/Library/Homebrew/test/rubocops/shell_commands_spec.rb @@ -1,9 +1,9 @@ # typed: false # frozen_string_literal: true -require "rubocops/lines" +require "rubocops/shell_commands" -describe RuboCop::Cop::FormulaAuditStrict::ShellCommands do +describe RuboCop::Cop::Style::ShellCommands do subject(:cop) { described_class.new } context "when auditing shell commands" do diff --git a/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb b/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb index 2371c0bd6b..818c894e3c 100644 --- a/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb +++ b/Library/Homebrew/test/rubocops/text/option_declarations_spec.rb @@ -42,7 +42,7 @@ describe RuboCop::Cop::FormulaAudit::OptionDeclarations do RUBY end - it "reports an offense when `build.without?` is used for a conditional dependency" do + it "reports an offense when `build.with?` is used for a conditional dependency" do expect_offense(<<~RUBY) class Foo < Formula depends_on "bar" if build.with?("baz") diff --git a/Library/Homebrew/test/rubocops/unless_multiple_conditions_spec.rb b/Library/Homebrew/test/rubocops/unless_multiple_conditions_spec.rb deleted file mode 100644 index 186c419044..0000000000 --- a/Library/Homebrew/test/rubocops/unless_multiple_conditions_spec.rb +++ /dev/null @@ -1,128 +0,0 @@ -# typed: false -# frozen_string_literal: true - -require "rubocops/unless_multiple_conditions" - -describe RuboCop::Cop::Style::UnlessMultipleConditions do - subject(:cop) { described_class.new } - - it "reports an offense when using `unless` with multiple `and` conditions" do - expect_offense <<~RUBY - unless foo && bar - ^^^^^^^^^^^^^^^^^ Avoid using `unless` with multiple conditions. - something - end - RUBY - - expect_offense <<~RUBY - something unless foo && bar - ^^^^^^^^^^^^^^^^^ Avoid using `unless` with multiple conditions. - RUBY - end - - it "reports an offense when using `unless` with multiple `or` conditions" do - expect_offense <<~RUBY - unless foo || bar - ^^^^^^^^^^^^^^^^^ Avoid using `unless` with multiple conditions. - something - end - RUBY - - expect_offense <<~RUBY - something unless foo || bar - ^^^^^^^^^^^^^^^^^ Avoid using `unless` with multiple conditions. - RUBY - end - - it "reports no offenses when using `if` with multiple `and` conditions" do - expect_no_offenses <<~RUBY - if !foo && !bar - something - end - RUBY - - expect_no_offenses <<~RUBY - something if !foo && !bar - RUBY - end - - it "reports no offenses when using `if` with multiple `or` conditions" do - expect_no_offenses <<~RUBY - if !foo || !bar - something - end - RUBY - - expect_no_offenses <<~RUBY - something if !foo || !bar - RUBY - end - - it "reports no offenses when using `unless` with single condition" do - expect_no_offenses <<~RUBY - unless foo - something - end - RUBY - - expect_no_offenses <<~RUBY - something unless foo - RUBY - end - - it "auto-corrects `unless` with multiple `and` conditions" do - source = <<~RUBY - unless foo && (bar || baz) - something - end - RUBY - - corrected_source = <<~RUBY - if !(foo) || !(bar || baz) - something - end - RUBY - - new_source = autocorrect_source(source) - expect(new_source).to eq(corrected_source) - - source = <<~RUBY - something unless foo && bar - RUBY - - corrected_source = <<~RUBY - something if !(foo) || !(bar) - RUBY - - new_source = autocorrect_source(source) - expect(new_source).to eq(corrected_source) - end - - it "auto-corrects `unless` with multiple `or` conditions" do - source = <<~RUBY - unless foo || (bar && baz) - something - end - RUBY - - corrected_source = <<~RUBY - if !(foo) && !(bar && baz) - something - end - RUBY - - new_source = autocorrect_source(source) - expect(new_source).to eq(corrected_source) - - source = <<~RUBY - something unless foo || bar - RUBY - - corrected_source = <<~RUBY - something if !(foo) && !(bar) - RUBY - - new_source = autocorrect_source(source) - expect(new_source).to eq(corrected_source) - end -end diff --git a/Library/Homebrew/test/search_spec.rb b/Library/Homebrew/test/search_spec.rb index 84377c4757..56949f2340 100644 --- a/Library/Homebrew/test/search_spec.rb +++ b/Library/Homebrew/test/search_spec.rb @@ -21,7 +21,7 @@ describe Homebrew::Search do end it "does not raise if the network fails" do - allow(GitHub).to receive(:open_api).and_raise(GitHub::Error) + allow(GitHub::API).to receive(:open_rest).and_raise(GitHub::API::Error) expect(mod.search_taps("some-formula")) .to match(formulae: [], casks: []) @@ -45,7 +45,7 @@ describe Homebrew::Search do ], } - allow(GitHub).to receive(:open_api).and_yield(json_response) + allow(GitHub::API).to receive(:open_rest).and_yield(json_response) expect(mod.search_taps("some-formula")) .to match(formulae: ["homebrew/foo/some-formula"], casks: ["homebrew/bar/some-cask"]) diff --git a/Library/Homebrew/test/searchable_spec.rb b/Library/Homebrew/test/searchable_spec.rb index 7a1f9cacbb..eee316379f 100644 --- a/Library/Homebrew/test/searchable_spec.rb +++ b/Library/Homebrew/test/searchable_spec.rb @@ -37,7 +37,7 @@ describe Searchable do expect(searchable_collection.search("foo")).to eq "foo" => "bar" end - context "containing nil" do + context "with a nil value" do let(:collection) { { "foo" => nil } } it "does not raise an error" do diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index ea57b47c22..bc9653df54 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -16,12 +16,17 @@ if ENV["HOMEBREW_TESTS_COVERAGE"] end end +require_relative "../warnings" + +Warnings.ignore :parser_syntax do + require "rubocop" +end + require "rspec/its" require "rspec/github" require "rspec/wait" require "rspec/retry" require "rspec/sorbet" -require "rubocop" require "rubocop/rspec/support" require "find" require "byebug" diff --git a/Library/Homebrew/test/support/fixtures/sdks/big_sur/MacOSX.sdk/SDKSettings.json b/Library/Homebrew/test/support/fixtures/sdks/big_sur/MacOSX.sdk/SDKSettings.json new file mode 100644 index 0000000000..3e9fb27234 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/sdks/big_sur/MacOSX.sdk/SDKSettings.json @@ -0,0 +1 @@ +{"Version":"11.1"} diff --git a/Library/Homebrew/test/support/fixtures/sdks/high_sierra/MacOSX10.13.sdk/SDKSettings.plist b/Library/Homebrew/test/support/fixtures/sdks/high_sierra/MacOSX10.13.sdk/SDKSettings.plist new file mode 100644 index 0000000000..7e57e7b081 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/sdks/high_sierra/MacOSX10.13.sdk/SDKSettings.plist @@ -0,0 +1,8 @@ + + + + + Version + 10.13 + + diff --git a/Library/Homebrew/test/support/fixtures/sdks/malformed/MacOSX10.15.sdk/SDKSettings.json b/Library/Homebrew/test/support/fixtures/sdks/malformed/MacOSX10.15.sdk/SDKSettings.json new file mode 100644 index 0000000000..8613898c19 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/sdks/malformed/MacOSX10.15.sdk/SDKSettings.json @@ -0,0 +1 @@ +{"Version":"broken"} diff --git a/Library/Homebrew/test/support/fixtures/sdks/mojave_broken/MacOSX10.14.sdk/SDKSettings.json b/Library/Homebrew/test/support/fixtures/sdks/mojave_broken/MacOSX10.14.sdk/SDKSettings.json new file mode 100644 index 0000000000..62938d457a --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/sdks/mojave_broken/MacOSX10.14.sdk/SDKSettings.json @@ -0,0 +1 @@ +{"Version":"10.15.6"} diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb index 1682091b97..4058dd0ac2 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb @@ -31,7 +31,7 @@ module Cask end end -RSpec.shared_context "Homebrew Cask", :needs_macos do +RSpec.shared_context "Homebrew Cask", :needs_macos do # rubocop:disable RSpec/ContextWording around do |example| third_party_tap = Tap.fetch("third-party", "tap") diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index 21ea723f60..88ea92b7f3 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -7,7 +7,7 @@ require "formula_installer" RSpec::Matchers.define_negated_matcher :be_a_failure, :be_a_success -RSpec.shared_context "integration test" do +RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWording extend RSpec::Matchers::DSL matcher :be_a_success do @@ -87,17 +87,18 @@ RSpec.shared_context "integration test" do ) @ruby_args ||= begin - ruby_args = [ - ENV["HOMEBREW_RUBY_WARNINGS"], - "-I", $LOAD_PATH.join(File::PATH_SEPARATOR) - ] + ruby_args = HOMEBREW_RUBY_EXEC_ARGS.dup if ENV["HOMEBREW_TESTS_COVERAGE"] simplecov_spec = Gem.loaded_specs["simplecov"] - specs = [simplecov_spec] - simplecov_spec.runtime_dependencies.each do |dep| - specs += dep.to_specs - rescue Gem::LoadError => e - onoe e + parallel_tests_spec = Gem.loaded_specs["parallel_tests"] + specs = [] + [simplecov_spec, parallel_tests_spec].each do |spec| + specs << spec + spec.runtime_dependencies.each do |dep| + specs += dep.to_specs + rescue Gem::LoadError => e + onoe e + end end libs = specs.flat_map do |spec| full_gem_path = spec.full_gem_path @@ -111,12 +112,21 @@ RSpec.shared_context "integration test" do libs.each { |lib| ruby_args << "-I" << lib } ruby_args << "-rsimplecov" end - ruby_args << "-rtest/support/helper/integration_mocks" + ruby_args << "-r#{HOMEBREW_LIBRARY_PATH}/test/support/helper/integration_mocks" ruby_args << (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path.to_s end Bundler.with_clean_env do - stdout, stderr, status = Open3.capture3(env, RUBY_PATH, *@ruby_args, *args) + stdout, stderr, status = Open3.capture3(env, *@ruby_args, *args) + $stdout.print stdout + $stderr.print stderr + status + end + end + + def brew_sh(*args) + Bundler.with_clean_env do + stdout, stderr, status = Open3.capture3("#{ENV["HOMEBREW_PREFIX"]}/bin/brew", *args) $stdout.print stdout $stderr.print stderr status diff --git a/Library/Homebrew/test/support/lib/config.rb b/Library/Homebrew/test/support/lib/config.rb index 1dede23e84..9e11210c39 100644 --- a/Library/Homebrew/test/support/lib/config.rb +++ b/Library/Homebrew/test/support/lib/config.rb @@ -37,6 +37,11 @@ HOMEBREW_LOCKS = (HOMEBREW_PREFIX.parent/"locks").freeze HOMEBREW_CELLAR = (HOMEBREW_PREFIX.parent/"cellar").freeze HOMEBREW_LOGS = (HOMEBREW_PREFIX.parent/"logs").freeze HOMEBREW_TEMP = (HOMEBREW_PREFIX.parent/"temp").freeze +HOMEBREW_RUBY_EXEC_ARGS = [ + RUBY_PATH, + ENV["HOMEBREW_RUBY_WARNINGS"], + "-I", HOMEBREW_LIBRARY_PATH/"test/support/lib" +].freeze TEST_FIXTURE_DIR = (HOMEBREW_LIBRARY_PATH/"test/support/fixtures").freeze diff --git a/Library/Homebrew/test/system_command_result_spec.rb b/Library/Homebrew/test/system_command_result_spec.rb index 5ce216387d..a4995c8b13 100644 --- a/Library/Homebrew/test/system_command_result_spec.rb +++ b/Library/Homebrew/test/system_command_result_spec.rb @@ -155,7 +155,7 @@ describe SystemCommand::Result do end end - context "given a hdiutil stdout" do + context "when there's a hdiutil stdout" do let(:stdout) { plist } it "successfully parses it" do diff --git a/Library/Homebrew/test/system_command_spec.rb b/Library/Homebrew/test/system_command_spec.rb index b1da8157f0..a73cd7acfc 100644 --- a/Library/Homebrew/test/system_command_spec.rb +++ b/Library/Homebrew/test/system_command_spec.rb @@ -79,7 +79,7 @@ describe SystemCommand do context "when the exit code is 1" do let(:command) { "false" } - context "and the command must succeed" do + context "with a command that must succeed" do it "throws an error" do expect { described_class.run!(command) @@ -87,7 +87,7 @@ describe SystemCommand do end end - context "and the command does not have to succeed" do + context "with a command that does not have to succeed" do describe "its result" do subject { described_class.run(command) } diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb index 03bf027c9f..c762680710 100644 --- a/Library/Homebrew/test/tap_spec.rb +++ b/Library/Homebrew/test/tap_spec.rb @@ -210,13 +210,11 @@ describe Tap do setup_git_repo expect(homebrew_foo_tap.git_head).to eq("0453e16c8e3fac73104da50927a86221ca0740c2") - expect(homebrew_foo_tap.git_short_head).to eq("0453") expect(homebrew_foo_tap.git_last_commit).to match(/\A\d+ .+ ago\Z/) - expect(homebrew_foo_tap.git_last_commit_date).to eq("2017-01-22") end specify "#private?" do - skip "HOMEBREW_GITHUB_API_TOKEN is required" unless GitHub.api_credentials + skip "HOMEBREW_GITHUB_API_TOKEN is required" unless GitHub::API.credentials expect(homebrew_foo_tap).to be_private end diff --git a/Library/Homebrew/test/uninstall_spec.rb b/Library/Homebrew/test/uninstall_spec.rb index d5f54077f2..a7c3288d50 100644 --- a/Library/Homebrew/test/uninstall_spec.rb +++ b/Library/Homebrew/test/uninstall_spec.rb @@ -5,31 +5,46 @@ require "uninstall" describe Homebrew::Uninstall do let(:dependency) { formula("dependency") { url "f-1" } } - let(:dependent) do - formula("dependent") do + + let(:dependent_formula) do + formula("dependent_formula") do url "f-1" depends_on "dependency" end end + let(:dependent_cask) do + Cask::CaskLoader.load(+<<-RUBY) + cask "dependent_cask" do + version "1.0.0" + + url "c-1" + depends_on formula: "dependency" + end + RUBY + end + let(:kegs_by_rack) { { dependency.rack => [Keg.new(dependency.latest_installed_prefix)] } } before do - [dependency, dependent].each do |f| + [dependency, dependent_formula].each do |f| f.latest_installed_prefix.mkpath Keg.new(f.latest_installed_prefix).optlink end tab = Tab.empty tab.homebrew_version = "1.1.6" - tab.tabfile = dependent.latest_installed_prefix/Tab::FILENAME + tab.tabfile = dependent_formula.latest_installed_prefix/Tab::FILENAME tab.runtime_dependencies = [ { "full_name" => "dependency", "version" => "1" }, ] tab.write + Cask::Caskroom.path.join("dependent_cask", dependent_cask.version).mkpath + stub_formula_loader dependency - stub_formula_loader dependent + stub_formula_loader dependent_formula + stub_cask_loader dependent_cask end describe "::handle_unsatisfied_dependents" do diff --git a/Library/Homebrew/test/utils/git_spec.rb b/Library/Homebrew/test/utils/git_spec.rb index 5bc2585a31..6f2ede3227 100644 --- a/Library/Homebrew/test/utils/git_spec.rb +++ b/Library/Homebrew/test/utils/git_spec.rb @@ -58,6 +58,7 @@ describe Utils::Git do end it "aborts when cherry picking an existing hash" do + ENV["GIT_MERGE_VERBOSITY"] = "5" # Consistent output across git versions expect { described_class.cherry_pick!(HOMEBREW_CACHE, file_hash1) }.to raise_error(ErrorDuringExecution, /Merge conflict in README.md/) diff --git a/Library/Homebrew/test/utils/github_spec.rb b/Library/Homebrew/test/utils/github_spec.rb index 10067e9359..c33bb0d28b 100644 --- a/Library/Homebrew/test/utils/github_spec.rb +++ b/Library/Homebrew/test/utils/github_spec.rb @@ -7,7 +7,7 @@ describe GitHub do describe "::search_code", :needs_network do it "queries GitHub code with the passed parameters" do results = described_class.search_code(repo: "Homebrew/brew", path: "/", - filename: "readme", language: "markdown") + filename: "readme", extension: "md") expect(results.count).to eq(1) expect(results.first["name"]).to eq("README.md") diff --git a/Library/Homebrew/test/utils/repology_spec.rb b/Library/Homebrew/test/utils/repology_spec.rb index 87fd550eef..c72096eedf 100644 --- a/Library/Homebrew/test/utils/repology_spec.rb +++ b/Library/Homebrew/test/utils/repology_spec.rb @@ -6,13 +6,13 @@ require "utils/repology" describe Repology do describe "single_package_query", :needs_network do it "returns nil for non-existent package" do - response = described_class.single_package_query("invalidName") + response = described_class.single_package_query("invalidName", repository: "homebrew") expect(response).to be_nil end it "returns a hash for existing package" do - response = described_class.single_package_query("openclonk") + response = described_class.single_package_query("openclonk", repository: "homebrew") expect(response).not_to be_nil expect(response).to be_a(Hash) @@ -22,7 +22,7 @@ describe Repology do describe "parse_api_response", :needs_network do it "returns a hash of data" do limit = 1 - response = described_class.parse_api_response(limit) + response = described_class.parse_api_response(limit, repository: "homebrew") expect(response).not_to be_nil expect(response).to be_a(Hash) diff --git a/Library/Homebrew/test/utils/spdx_spec.rb b/Library/Homebrew/test/utils/spdx_spec.rb index 40045647f9..c4852de199 100644 --- a/Library/Homebrew/test/utils/spdx_spec.rb +++ b/Library/Homebrew/test/utils/spdx_spec.rb @@ -132,10 +132,18 @@ describe SPDX do expect(described_class.deprecated_license?("GPL-1.0")).to eq true end + it "returns true for deprecated license identifier with plus" do + expect(described_class.deprecated_license?("GPL-1.0+")).to eq true + end + it "returns false for non-deprecated license identifier" do expect(described_class.deprecated_license?("MIT")).to eq false end + it "returns false for non-deprecated license identifier with plus" do + expect(described_class.deprecated_license?("EPL-1.0+")).to eq false + end + it "returns false for invalid license identifier" do expect(described_class.deprecated_license?("foo")).to eq false end diff --git a/Library/Homebrew/test/utils/string_inreplace_extension_spec.rb b/Library/Homebrew/test/utils/string_inreplace_extension_spec.rb index a072aafb5e..999e55c67d 100644 --- a/Library/Homebrew/test/utils/string_inreplace_extension_spec.rb +++ b/Library/Homebrew/test/utils/string_inreplace_extension_spec.rb @@ -7,7 +7,7 @@ describe StringInreplaceExtension do subject(:string_extension) { described_class.new(string.dup) } describe "#change_make_var!" do - context "flag" do + context "with a flag" do context "with spaces" do let(:string) do <<~EOS @@ -72,7 +72,7 @@ describe StringInreplaceExtension do end end - context "empty flag between other flags" do + context "with an empty flag between other flags" do let(:string) do <<~EOS OTHER=def @@ -91,7 +91,7 @@ describe StringInreplaceExtension do end end - context "empty flag" do + context "with an empty flag" do let(:string) do <<~EOS FLAG = @@ -108,7 +108,7 @@ describe StringInreplaceExtension do end end - context "shell-style variable" do + context "with shell-style variable" do let(:string) do <<~EOS OTHER=def @@ -129,7 +129,7 @@ describe StringInreplaceExtension do end describe "#remove_make_var!" do - context "flag" do + context "with a flag" do context "with spaces" do let(:string) do <<~EOS @@ -182,7 +182,7 @@ describe StringInreplaceExtension do end end - context "multiple flags" do + context "with multiple flags" do let(:string) do <<~EOS OTHER=def diff --git a/Library/Homebrew/uninstall.rb b/Library/Homebrew/uninstall.rb index cabb18f627..0e835b2013 100644 --- a/Library/Homebrew/uninstall.rb +++ b/Library/Homebrew/uninstall.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -require "keg" +require "installed_dependents" module Homebrew # Helper module for uninstalling kegs. @@ -10,8 +10,9 @@ module Homebrew module Uninstall module_function - def uninstall_kegs(kegs_by_rack, force: false, ignore_dependencies: false, named_args: []) + def uninstall_kegs(kegs_by_rack, casks: [], force: false, ignore_dependencies: false, named_args: []) handle_unsatisfied_dependents(kegs_by_rack, + casks: casks, ignore_dependencies: ignore_dependencies, named_args: named_args) return if Homebrew.failed? @@ -96,18 +97,18 @@ module Homebrew end end - def handle_unsatisfied_dependents(kegs_by_rack, ignore_dependencies: false, named_args: []) + def handle_unsatisfied_dependents(kegs_by_rack, casks: [], ignore_dependencies: false, named_args: []) return if ignore_dependencies all_kegs = kegs_by_rack.values.flatten(1) - check_for_dependents(all_kegs, named_args: named_args) + check_for_dependents(all_kegs, casks: casks, named_args: named_args) rescue MethodDeprecatedError # Silently ignore deprecations when uninstalling. nil end - def check_for_dependents(kegs, named_args: []) - return false unless result = Keg.find_some_installed_dependents(kegs) + def check_for_dependents(kegs, casks: [], named_args: []) + return false unless (result = InstalledDependents.find_some_installed_dependents(kegs, casks: casks)) if Homebrew::EnvConfig.developer? DeveloperDependentsMessage.new(*result, named_args: named_args).output diff --git a/Library/Homebrew/unpack_strategy/dmg.rb b/Library/Homebrew/unpack_strategy/dmg.rb index 2b04e12d44..5f2fea6825 100644 --- a/Library/Homebrew/unpack_strategy/dmg.rb +++ b/Library/Homebrew/unpack_strategy/dmg.rb @@ -13,18 +13,18 @@ module UnpackStrategy # Helper module for listing the contents of a volume mounted from a disk image. module Bom DMG_METADATA = Set.new(%w[ - .background - .com.apple.timemachine.donotpresent - .com.apple.timemachine.supported - .DocumentRevisions-V100 - .DS_Store - .fseventsd - .MobileBackups - .Spotlight-V100 - .TemporaryItems - .Trashes - .VolumeIcon.icns - ]).freeze + .background + .com.apple.timemachine.donotpresent + .com.apple.timemachine.supported + .DocumentRevisions-V100 + .DS_Store + .fseventsd + .MobileBackups + .Spotlight-V100 + .TemporaryItems + .Trashes + .VolumeIcon.icns + ]).freeze private_constant :DMG_METADATA refine Pathname do diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 5d54123121..01fee6c88a 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -121,6 +121,7 @@ module Kernel end def puts_stdout_or_stderr(*message) + message = "\n" if message.empty? if $stdout.tty? puts(message) else @@ -222,7 +223,7 @@ module Kernel tap_message = T.let(nil, T.nilable(String)) backtrace.each do |line| - next unless match = line.match(HOMEBREW_TAP_PATH_REGEX) + next unless (match = line.match(HOMEBREW_TAP_PATH_REGEX)) tap = Tap.fetch(match[:user], match[:repo]) tap_message = +"\nPlease report this issue to the #{tap} tap (not Homebrew/brew or Homebrew/core)" diff --git a/Library/Homebrew/utils/bottles.rb b/Library/Homebrew/utils/bottles.rb index 1898f68517..897d8c4af4 100644 --- a/Library/Homebrew/utils/bottles.rb +++ b/Library/Homebrew/utils/bottles.rb @@ -107,15 +107,15 @@ module Utils @checksums = {} end - sig { params(tag: Symbol).returns(T.nilable([Checksum, Symbol, T.any(Symbol, String)])) } - def fetch_checksum_for(tag) - tag = find_matching_tag(tag) + sig { params(tag: Symbol, exact: T::Boolean).returns(T.nilable([Checksum, Symbol, T.any(Symbol, String)])) } + def fetch_checksum_for(tag, exact: false) + tag = find_matching_tag(tag, exact: exact) return self[tag][:checksum], tag, self[tag][:cellar] if tag end private - def find_matching_tag(tag) + def find_matching_tag(tag, exact: false) tag if key?(tag) end end diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index 8e2a798ed3..f6d7cbea75 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -3,11 +3,15 @@ require "open3" +require "extend/time" + module Utils # Helper function for interacting with `curl`. # # @api private module Curl + using TimeRemaining + module_function def curl_executable @@ -49,14 +53,20 @@ module Utils args << "--silent" unless $stdout.tty? end + args << "--connect-timeout" << connect_timeout.round(3) if options[:connect_timeout] + args << "--max-time" << max_time.round(3) if options[:max_time] args << "--retry" << Homebrew::EnvConfig.curl_retries unless options[:retry] == false + args << "--retry-max-time" << retry_max_time.round if options[:retry_max_time] args + extra_args end def curl_with_workarounds( - *args, secrets: nil, print_stdout: nil, print_stderr: nil, debug: nil, verbose: nil, env: {}, **options + *args, + secrets: nil, print_stdout: nil, print_stderr: nil, debug: nil, verbose: nil, env: {}, timeout: nil, **options ) + end_time = Time.now + timeout if timeout + command_options = { secrets: secrets, print_stdout: print_stdout, @@ -68,14 +78,22 @@ module Utils # SSL_CERT_FILE can be incorrectly set by users or portable-ruby and screw # with SSL downloads so unset it here. result = system_command curl_executable, - args: curl_args(*args, **options), - env: { "SSL_CERT_FILE" => nil }.merge(env), + args: curl_args(*args, **options), + env: { "SSL_CERT_FILE" => nil }.merge(env), + timeout: end_time&.remaining, **command_options return result if result.success? || !args.exclude?("--http1.1") + raise Timeout::Error, result.stderr.chomp if result.status.exitstatus == 28 + # Error in the HTTP2 framing layer - return curl_with_workarounds(*args, "--http1.1", **command_options, **options) if result.status.exitstatus == 16 + if result.status.exitstatus == 16 + return curl_with_workarounds( + *args, "--http1.1", + timeout: end_time&.remaining, **command_options, **options + ) + end # This is a workaround for https://github.com/curl/curl/issues/1618. if result.status.exitstatus == 56 # Unexpected EOF diff --git a/Library/Homebrew/utils/fork.rb b/Library/Homebrew/utils/fork.rb index 7094e7d8f4..ac1ff1182a 100644 --- a/Library/Homebrew/utils/fork.rb +++ b/Library/Homebrew/utils/fork.rb @@ -51,7 +51,14 @@ module Utils # to rescue them further down. if e.is_a?(ErrorDuringExecution) error_hash["cmd"] = e.cmd - error_hash["status"] = e.status.exitstatus + error_hash["status"] = if e.status.is_a?(Process::Status) + { + exitstatus: e.status.exitstatus, + termsig: e.status.termsig, + } + else + e.status + end error_hash["output"] = e.output end diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index a75f0b8561..e607da5422 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -22,7 +22,6 @@ module Homebrew end def gem_user_bindir - require "rubygems" "#{gem_user_dir}/bin" end @@ -34,6 +33,14 @@ module Homebrew end end + def opoo_if_defined(message) + if defined?(opoo) + $stderr.opoo message + else + $stderr.puts "Warning: #{message}" + end + end + def odie_if_defined(message) if defined?(odie) odie message @@ -43,21 +50,19 @@ module Homebrew end end - def setup_gem_environment!(gem_home: nil, gem_bindir: nil) - require "rubygems" - + def setup_gem_environment!(gem_home: nil, gem_bindir: nil, setup_path: true) # Match where our bundler gems are. gem_home ||= "#{ENV["HOMEBREW_LIBRARY"]}/Homebrew/vendor/bundle/ruby/#{RbConfig::CONFIG["ruby_version"]}" - ENV["GEM_HOME"] = gem_home - ENV["GEM_PATH"] = "#{ENV["GEM_HOME"]}:#{Gem.default_dir}" + Gem.paths = { + "GEM_HOME" => gem_home, + "GEM_PATH" => gem_home, + } # Set TMPDIR so Xcode's `make` doesn't fall back to `/var/tmp/`, # which may be not user-writable. ENV["TMPDIR"] = ENV["HOMEBREW_TEMP"] - # Make RubyGems notice environment changes. - Gem.clear_paths - Gem::Specification.reset + return unless setup_path # Add necessary Ruby and Gem binary directories to `PATH`. gem_bindir ||= Gem.bindir @@ -65,15 +70,31 @@ module Homebrew paths.unshift(gem_bindir) unless paths.include?(gem_bindir) paths.unshift(ruby_bindir) unless paths.include?(ruby_bindir) ENV["PATH"] = paths.compact.join(":") + + # Set envs so the above binaries can be invoked. + # We don't do this unless requested as some formulae may invoke system Ruby instead of ours. + ENV["GEM_HOME"] = gem_home + ENV["GEM_PATH"] = gem_home end def install_gem!(name, version: nil, setup_gem_environment: true) setup_gem_environment! if setup_gem_environment - return unless Gem::Specification.find_all_by_name(name, version).empty? - ohai_if_defined "Installing '#{name}' gem" - # document: [] , is equivalent to --no-document - Gem.install name, version, document: [] + specs = Gem::Specification.find_all_by_name(name, version) + + if specs.empty? + ohai_if_defined "Installing '#{name}' gem" + # document: [] , is equivalent to --no-document + specs = Gem.install name, version, document: [] + end + + # Add the new specs to the $LOAD_PATH. + specs.each do |spec| + spec.require_paths.each do |path| + full_path = File.join(spec.full_gem_path, path) + $LOAD_PATH.unshift full_path unless $LOAD_PATH.include?(full_path) + end + end rescue Gem::UnsatisfiableDependencyError odie_if_defined "failed to install the '#{name}' gem." end @@ -95,7 +116,6 @@ module Homebrew end def install_bundler! - require "rubygems" setup_gem_environment!(gem_home: gem_user_dir, gem_bindir: gem_user_bindir) install_gem_setup_path!( "bundler", @@ -105,7 +125,11 @@ module Homebrew ) end - def install_bundler_gems! + def install_bundler_gems!(only_warn_on_failure: false, setup_path: true) + old_path = ENV["PATH"] + old_gem_path = ENV["GEM_PATH"] + old_gem_home = ENV["GEM_HOME"] + install_bundler! ENV["BUNDLE_GEMFILE"] = File.join(ENV.fetch("HOMEBREW_LIBRARY"), "Homebrew", "Gemfile") @@ -117,9 +141,14 @@ module Homebrew # for some reason sometimes the exit code lies so check the output too. if bundle_check_failed || bundle_check_output.include?("Install missing gems") unless system bundle, "install" - odie_if_defined <<~EOS + message = <<~EOS failed to run `#{bundle} install`! EOS + if only_warn_on_failure + opoo_if_defined message + else + odie_if_defined message + end end else true @@ -127,5 +156,12 @@ module Homebrew end setup_gem_environment! + ensure + unless setup_path + # Reset the paths. We need to have at least temporarily changed them while invoking `bundle`. + ENV["PATH"] = old_path + ENV["GEM_PATH"] = old_gem_path + ENV["GEM_HOME"] = old_gem_home + end end end diff --git a/Library/Homebrew/utils/gems.rbi b/Library/Homebrew/utils/gems.rbi index 47c3ced643..55bdcc1114 100644 --- a/Library/Homebrew/utils/gems.rbi +++ b/Library/Homebrew/utils/gems.rbi @@ -22,6 +22,6 @@ module Homebrew sig { void } def install_bundler!; end - sig { void } - def install_bundler_gems!; end + sig { params(only_warn_on_failure: T::Boolean, setup_path: T::Boolean).void } + def install_bundler_gems!(only_warn_on_failure: false, setup_path: false); end end diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb index a18b146200..acef79b932 100644 --- a/Library/Homebrew/utils/github.rb +++ b/Library/Homebrew/utils/github.rb @@ -1,12 +1,11 @@ # typed: false # frozen_string_literal: true -require "tempfile" require "uri" require "utils/github/actions" -require "utils/shell" +require "utils/github/api" -# Helper functions for interacting with the GitHub API. +# Wrapper functions for the GitHub API. # # @api private module GitHub @@ -14,288 +13,10 @@ module GitHub module_function - API_URL = "https://api.github.com" - API_MAX_PAGES = 50 - API_MAX_ITEMS = 5000 - - CREATE_GIST_SCOPES = ["gist"].freeze - CREATE_ISSUE_FORK_OR_PR_SCOPES = ["public_repo"].freeze - CREATE_WORKFLOW_SCOPES = ["workflow"].freeze - ALL_SCOPES = (CREATE_GIST_SCOPES + CREATE_ISSUE_FORK_OR_PR_SCOPES + CREATE_WORKFLOW_SCOPES).freeze - ALL_SCOPES_URL = Formatter.url( - "https://github.com/settings/tokens/new?scopes=#{ALL_SCOPES.join(",")}&description=Homebrew", - ).freeze - CREATE_GITHUB_PAT_MESSAGE = <<~EOS - Create a GitHub personal access token: - #{ALL_SCOPES_URL} - #{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")} - EOS - - # Generic API error. - class Error < RuntimeError - attr_reader :github_message - end - - # Error when the requested URL is not found. - class HTTPNotFoundError < Error - def initialize(github_message) - @github_message = github_message - super - end - end - - # Error when the API rate limit is exceeded. - class RateLimitExceededError < Error - def initialize(reset, github_message) - @github_message = github_message - super <<~EOS - GitHub API Error: #{github_message} - Try again in #{pretty_ratelimit_reset(reset)}, or: - #{CREATE_GITHUB_PAT_MESSAGE} - EOS - end - - def pretty_ratelimit_reset(reset) - pretty_duration(Time.at(reset) - Time.now) - end - end - - # Error when authentication fails. - class AuthenticationFailedError < Error - def initialize(github_message) - @github_message = github_message - message = +"GitHub #{github_message}:" - message << if Homebrew::EnvConfig.github_api_token - <<~EOS - HOMEBREW_GITHUB_API_TOKEN may be invalid or expired; check: - #{Formatter.url("https://github.com/settings/tokens")} - EOS - else - <<~EOS - The GitHub credentials in the macOS keychain may be invalid. - Clear them with: - printf "protocol=https\\nhost=github.com\\n" | git credential-osxkeychain erase - #{CREATE_GITHUB_PAT_MESSAGE} - EOS - end - super message.freeze - end - end - - # Error when the user has no GitHub API credentials set at all (macOS keychain or envvar). - class MissingAuthenticationError < Error - def initialize - message = +"No GitHub credentials found in macOS Keychain or environment.\n" - message << CREATE_GITHUB_PAT_MESSAGE - super message - end - end - - # Error when the API returns a validation error. - class ValidationFailedError < Error - def initialize(github_message, errors) - @github_message = if errors.empty? - github_message - else - "#{github_message}: #{errors}" - end - - super(@github_message) - end - end - - API_ERRORS = [ - AuthenticationFailedError, - HTTPNotFoundError, - RateLimitExceededError, - Error, - JSON::ParserError, - ].freeze - - # Gets the password field from `git-credential-osxkeychain` for github.com, - # but only if that password looks like a GitHub Personal Access Token. - sig { returns(T.nilable(String)) } - def keychain_username_password - github_credentials = Utils.popen(["git", "credential-osxkeychain", "get"], "w+") do |pipe| - pipe.write "protocol=https\nhost=github.com\n" - pipe.close_write - pipe.read - end - github_username = github_credentials[/username=(.+)/, 1] - github_password = github_credentials[/password=(.+)/, 1] - return unless github_username - - # Don't use passwords from the keychain unless they look like - # GitHub Personal Access Tokens: - # https://github.com/Homebrew/brew/issues/6862#issuecomment-572610344 - return unless /^[a-f0-9]{40}$/i.match?(github_password) - - github_password - rescue Errno::EPIPE - # The above invocation via `Utils.popen` can fail, causing the pipe to be - # prematurely closed (before we can write to it) and thus resulting in a - # broken pipe error. The root cause is usually a missing or malfunctioning - # `git-credential-osxkeychain` helper. - nil - end - - def api_credentials - @api_credentials ||= begin - Homebrew::EnvConfig.github_api_token || keychain_username_password - end - end - - sig { returns(Symbol) } - def api_credentials_type - if Homebrew::EnvConfig.github_api_token - :env_token - elsif keychain_username_password - :keychain_username_password - else - :none - end - end - - # Given an API response from GitHub, warn the user if their credentials - # have insufficient permissions. - def api_credentials_error_message(response_headers, needed_scopes) - return if response_headers.empty? - - scopes = response_headers["x-accepted-oauth-scopes"].to_s.split(", ") - needed_scopes = Set.new(scopes || needed_scopes) - credentials_scopes = response_headers["x-oauth-scopes"] - return if needed_scopes.subset?(Set.new(credentials_scopes.to_s.split(", "))) - - needed_scopes = needed_scopes.to_a.join(", ").presence || "none" - credentials_scopes = "none" if credentials_scopes.blank? - - what = case api_credentials_type - when :keychain_username_password - "macOS keychain GitHub" - when :env_token - "HOMEBREW_GITHUB_API_TOKEN" - end - - @api_credentials_error_message ||= onoe <<~EOS - Your #{what} credentials do not have sufficient scope! - Scopes required: #{needed_scopes} - Scopes present: #{credentials_scopes} - #{CREATE_GITHUB_PAT_MESSAGE} - EOS - end - def open_api(url, data: nil, data_binary_path: nil, request_method: nil, scopes: [].freeze, parse_json: true) - # This is a no-op if the user is opting out of using the GitHub API. - return block_given? ? yield({}) : {} if Homebrew::EnvConfig.no_github_api? - - args = ["--header", "Accept: application/vnd.github.v3+json", "--write-out", "\n%\{http_code}"] - args += ["--header", "Accept: application/vnd.github.antiope-preview+json"] - - token = api_credentials - args += ["--header", "Authorization: token #{token}"] unless api_credentials_type == :none - - data_tmpfile = nil - if data - begin - data = JSON.generate data - data_tmpfile = Tempfile.new("github_api_post", HOMEBREW_TEMP) - rescue JSON::ParserError => e - raise Error, "Failed to parse JSON request:\n#{e.message}\n#{data}", e.backtrace - end - end - - if data_binary_path.present? - args += ["--data-binary", "@#{data_binary_path}"] - args += ["--header", "Content-Type: application/gzip"] - end - - headers_tmpfile = Tempfile.new("github_api_headers", HOMEBREW_TEMP) - begin - if data - data_tmpfile.write data - data_tmpfile.close - args += ["--data", "@#{data_tmpfile.path}"] - - args += ["--request", request_method.to_s] if request_method - end - - args += ["--dump-header", headers_tmpfile.path] - - output, errors, status = curl_output("--location", url.to_s, *args, secrets: [token]) - output, _, http_code = output.rpartition("\n") - output, _, http_code = output.rpartition("\n") if http_code == "000" - headers = headers_tmpfile.read - ensure - if data_tmpfile - data_tmpfile.close - data_tmpfile.unlink - end - headers_tmpfile.close - headers_tmpfile.unlink - end - - begin - raise_api_error(output, errors, http_code, headers, scopes) if !http_code.start_with?("2") || !status.success? - - return if http_code == "204" # No Content - - output = JSON.parse output if parse_json - if block_given? - yield output - else - output - end - rescue JSON::ParserError => e - raise Error, "Failed to parse JSON response\n#{e.message}", e.backtrace - end - end - - def open_graphql(query, scopes: [].freeze) - data = { query: query } - result = open_api("https://api.github.com/graphql", scopes: scopes, data: data, request_method: "POST") - - raise Error, result["errors"].map { |e| "#{e["type"]}: #{e["message"]}" }.join("\n") if result["errors"].present? - - result["data"] - end - - def raise_api_error(output, errors, http_code, headers, scopes) - json = begin - JSON.parse(output) - rescue - nil - end - message = json&.[]("message") || "curl failed! #{errors}" - - meta = {} - headers.lines.each do |l| - key, _, value = l.delete(":").partition(" ") - key = key.downcase.strip - next if key.empty? - - meta[key] = value.strip - end - - if meta.fetch("x-ratelimit-remaining", 1).to_i <= 0 - reset = meta.fetch("x-ratelimit-reset").to_i - raise RateLimitExceededError.new(reset, message) - end - - api_credentials_error_message(meta, scopes) - - case http_code - when "401", "403" - raise AuthenticationFailedError, message - when "404" - raise MissingAuthenticationError if api_credentials_type == :none && scopes.present? - - raise HTTPNotFoundError, message - when "422" - errors = json&.[]("errors") || [] - raise ValidationFailedError.new(message, errors) - else - raise Error, message - end + odeprecated "GitHub.open_api", "GitHub::API.open_rest" + API.open_rest(url, data: data, data_binary_path: data_binary_path, request_method: request_method, + scopes: scopes, parse_json: parse_json) end def check_runs(repo: nil, commit: nil, pr: nil) @@ -304,23 +25,35 @@ module GitHub commit = pr.fetch("head").fetch("sha") end - open_api(url_to("repos", repo, "commits", commit, "check-runs")) + API.open_rest(url_to("repos", repo, "commits", commit, "check-runs")) end def create_check_run(repo:, data:) - open_api(url_to("repos", repo, "check-runs"), data: data) + API.open_rest(url_to("repos", repo, "check-runs"), data: data) end def search_issues(query, **qualifiers) search("issues", query, **qualifiers) end - def repository(user, repo) - open_api(url_to("repos", user, repo)) + def create_gist(files, description, private:) + url = "https://api.github.com/gists" + data = { "public" => !private, "files" => files, "description" => description } + API.open_rest(url, data: data, scopes: CREATE_GIST_SCOPES)["html_url"] end - def search_code(**qualifiers) - matches = search("code", **qualifiers) + def create_issue(repo, title, body) + url = "https://api.github.com/repos/#{repo}/issues" + data = { "title" => title, "body" => body } + API.open_rest(url, data: data, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)["html_url"] + end + + def repository(user, repo) + API.open_rest(url_to("repos", user, repo)) + end + + def search_code(repo: nil, user: "Homebrew", path: ["Formula", "Casks", "."], filename: nil, extension: "rb") + matches = search("code", user: user, path: path, filename: filename, extension: extension, repo: repo) return matches if matches.blank? matches.map do |match| @@ -335,11 +68,11 @@ module GitHub end def user - @user ||= open_api("#{API_URL}/user") + @user ||= API.open_rest("#{API_URL}/user") end def permission(repo, user) - open_api("#{API_URL}/repos/#{repo}/collaborators/#{user}/permission") + API.open_rest("#{API_URL}/repos/#{repo}/collaborators/#{user}/permission") end def write_access?(repo, user = nil) @@ -349,14 +82,14 @@ module GitHub def pull_requests(repo, **options) url = "#{API_URL}/repos/#{repo}/pulls?#{URI.encode_www_form(options)}" - open_api(url) + API.open_rest(url) end def merge_pull_request(repo, number:, sha:, merge_method:, commit_message: nil) url = "#{API_URL}/repos/#{repo}/pulls/#{number}/merge" data = { sha: sha, merge_method: merge_method } data[:commit_message] = commit_message if commit_message - open_api(url, data: data, request_method: :PUT, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) + API.open_rest(url, data: data, request_method: :PUT, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) end def print_pull_requests_matching(query, only = nil) @@ -386,14 +119,14 @@ module GitHub url = "#{API_URL}/repos/#{repo}/forks" data = {} scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES - open_api(url, data: data, scopes: scopes) + API.open_rest(url, data: data, scopes: scopes) end def check_fork_exists(repo) _, reponame = repo.split("/") - username = open_api(url_to("user")) { |json| json["login"] } - json = open_api(url_to("repos", username, reponame)) + username = API.open_rest(url_to("user")) { |json| json["login"] } + json = API.open_rest(url_to("repos", username, reponame)) return false if json["message"] == "Not Found" @@ -404,12 +137,12 @@ module GitHub url = "#{API_URL}/repos/#{repo}/pulls" data = { title: title, head: head, base: base, body: body } scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES - open_api(url, data: data, scopes: scopes) + API.open_rest(url, data: data, scopes: scopes) end def private_repo?(full_name) uri = url_to "repos", full_name - open_api(uri) { |json| json["private"] } + API.open_rest(uri) { |json| json["private"] } end def query_string(*main_params, **qualifiers) @@ -429,7 +162,7 @@ module GitHub def search(entity, *queries, **qualifiers) uri = url_to "search", entity uri.query = query_string(*queries, **qualifiers) - open_api(uri) { |json| json.fetch("items", []) } + API.open_rest(uri) { |json| json.fetch("items", []) } end def approved_reviews(user, repo, pr, commit: nil) @@ -451,7 +184,7 @@ module GitHub } EOS - result = open_graphql(query, scopes: ["user:email"]) + result = API.open_graphql(query, scopes: ["user:email"]) reviews = result["repository"]["pullRequest"]["reviews"]["nodes"] valid_associations = %w[MEMBER OWNER] @@ -475,26 +208,26 @@ module GitHub def dispatch_event(user, repo, event, **payload) url = "#{API_URL}/repos/#{user}/#{repo}/dispatches" - open_api(url, data: { event_type: event, client_payload: payload }, - request_method: :POST, - scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) + API.open_rest(url, data: { event_type: event, client_payload: payload }, + request_method: :POST, + scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) end def workflow_dispatch_event(user, repo, workflow, ref, **inputs) url = "#{API_URL}/repos/#{user}/#{repo}/actions/workflows/#{workflow}/dispatches" - open_api(url, data: { ref: ref, inputs: inputs }, - request_method: :POST, - scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) + API.open_rest(url, data: { ref: ref, inputs: inputs }, + request_method: :POST, + scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) end def get_release(user, repo, tag) url = "#{API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}" - open_api(url, request_method: :GET) + API.open_rest(url, request_method: :GET) end def get_latest_release(user, repo) url = "#{API_URL}/repos/#{user}/#{repo}/releases/latest" - open_api(url, request_method: :GET) + API.open_rest(url, request_method: :GET) end def create_or_update_release(user, repo, tag, id: nil, name: nil, body: nil, draft: false) @@ -511,24 +244,24 @@ module GitHub draft: draft, } data[:body] = body if body.present? - open_api(url, data: data, request_method: method, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) + API.open_rest(url, data: data, request_method: method, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) end def upload_release_asset(user, repo, id, local_file: nil, remote_file: nil) url = "https://uploads.github.com/repos/#{user}/#{repo}/releases/#{id}/assets" url += "?name=#{remote_file}" if remote_file - open_api(url, data_binary_path: local_file, request_method: :POST, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) + API.open_rest(url, data_binary_path: local_file, request_method: :POST, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES) end def get_workflow_run(user, repo, pr, workflow_id: "tests.yml", artifact_name: "bottles") scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES base_url = "#{API_URL}/repos/#{user}/#{repo}" - pr_payload = open_api("#{base_url}/pulls/#{pr}", scopes: scopes) + pr_payload = API.open_rest("#{base_url}/pulls/#{pr}", scopes: scopes) pr_sha = pr_payload["head"]["sha"] pr_branch = URI.encode_www_form_component(pr_payload["head"]["ref"]) parameters = "event=pull_request&branch=#{pr_branch}" - workflow = open_api("#{base_url}/actions/workflows/#{workflow_id}/runs?#{parameters}", scopes: scopes) + workflow = API.open_rest("#{base_url}/actions/workflows/#{workflow_id}/runs?#{parameters}", scopes: scopes) workflow_run = workflow["workflow_runs"].select do |run| run["head_sha"] == pr_sha end @@ -539,7 +272,7 @@ module GitHub def get_artifact_url(workflow_array) workflow_run, pr_sha, pr_branch, pr, workflow_id, scopes, artifact_name = *workflow_array if workflow_run.empty? - raise Error, <<~EOS + raise API::Error, <<~EOS No matching workflow run found for these criteria! Commit SHA: #{pr_sha} Branch ref: #{pr_branch} @@ -550,20 +283,20 @@ module GitHub status = workflow_run.first["status"].sub("_", " ") if status != "completed" - raise Error, <<~EOS + raise API::Error, <<~EOS The newest workflow run for ##{pr} is still #{status}! #{Formatter.url workflow_run.first["html_url"]} EOS end - artifacts = open_api(workflow_run.first["artifacts_url"], scopes: scopes) + artifacts = API.open_rest(workflow_run.first["artifacts_url"], scopes: scopes) artifact = artifacts["artifacts"].select do |art| art["name"] == artifact_name end if artifact.empty? - raise Error, <<~EOS + raise API::Error, <<~EOS No artifact with the name `#{artifact_name}` was found! #{Formatter.url workflow_run.first["html_url"]} EOS @@ -573,11 +306,11 @@ module GitHub end def public_member_usernames(org, per_page: 100) - url = "#{API_URL}/orgs/#{org}/public_members?per_page=#{per_page}" + url = "#{API_URL}/orgs/#{org}/public_members" members = [] - (1..API_MAX_PAGES).each do |page| - result = open_api("#{url}&page=#{page}").map { |member| member["login"] } + API.paginate_rest(url, per_page: per_page) do |result| + result = result.map { |member| member["login"] } members.concat(result) return members if result.length < per_page @@ -602,13 +335,13 @@ module GitHub } } EOS - result = open_graphql(query, scopes: ["read:org", "user"]) + result = API.open_graphql(query, scopes: ["read:org", "user"]) if result["organization"]["teams"]["nodes"].blank? - raise Error, + raise API::Error, "Your token needs the 'read:org' scope to access this API" end - raise Error, "The team #{org}/#{team} does not exist" if result["organization"]["team"].blank? + raise API::Error, "The team #{org}/#{team} does not exist" if result["organization"]["team"].blank? result["organization"]["team"]["members"]["nodes"].map { |member| [member["login"], member["name"]] }.to_h end @@ -639,13 +372,13 @@ module GitHub } } EOS - result = open_graphql(query, scopes: ["admin:org", "user"]) + result = API.open_graphql(query, scopes: ["admin:org", "user"]) tiers = result["organization"]["sponsorsListing"]["tiers"]["nodes"] tiers.map do |t| tier = t["monthlyPriceInDollars"] - raise Error, "Your token needs the 'admin:org' scope to access this API" if t["adminInfo"].nil? + raise API::Error, "Your token needs the 'admin:org' scope to access this API" if t["adminInfo"].nil? sponsorships = t["adminInfo"]["sponsorships"] count = sponsorships["totalCount"] @@ -669,11 +402,11 @@ module GitHub end def get_repo_license(user, repo) - response = open_api("#{API_URL}/repos/#{user}/#{repo}/license") + response = API.open_rest("#{API_URL}/repos/#{user}/#{repo}/license") return unless response.key?("license") response["license"]["spdx_id"] - rescue HTTPNotFoundError + rescue API::HTTPNotFoundError nil end @@ -688,14 +421,14 @@ module GitHub issues_for_formula(query, tap_full_name: tap_full_name, state: state).select do |pr| pr["html_url"].include?("/pull/") && regex.match?(pr["title"]) end - rescue RateLimitExceededError => e + rescue API::RateLimitExceededError => e opoo e.message [] end def check_for_duplicate_pull_requests(name, tap_full_name, state:, file:, args:, version: nil) pull_requests = fetch_pull_requests(name, tap_full_name, state: state, version: version).select do |pr| - pr_files = open_api(url_to("repos", tap_full_name, "pulls", pr["number"], "files")) + pr_files = API.open_rest(url_to("repos", tap_full_name, "pulls", pr["number"], "files")) pr_files.any? { |f| f["filename"] == file } end return if pull_requests.blank? @@ -748,7 +481,7 @@ module GitHub pr_message = info[:pr_message] sourcefile_path.parent.cd do - git_dir = Utils.popen_read("git rev-parse --git-dir").chomp + git_dir = Utils.popen_read("git", "rev-parse", "--git-dir").chomp shallow = !git_dir.empty? && File.exist?("#{git_dir}/shallow") changed_files = [sourcefile_path] changed_files += additional_files if additional_files.present? @@ -767,12 +500,12 @@ module GitHub unless args.commit? if args.no_fork? - remote_url = Utils.popen_read("git remote get-url --push origin").chomp + remote_url = Utils.popen_read("git", "remote", "get-url", "--push", "origin").chomp username = tap.user else begin remote_url, username = forked_repo_info!(tap_full_name) - rescue *API_ERRORS => e + rescue *API::ERRORS => e sourcefile_path.atomic_write(old_contents) odie "Unable to fork: #{e.message}!" end @@ -812,7 +545,7 @@ module GitHub else exec_browser url end - rescue *API_ERRORS => e + rescue *API::ERRORS => e odie "Unable to open pull request: #{e.message}!" end end @@ -820,29 +553,28 @@ module GitHub end def pull_request_commits(user, repo, pr, per_page: 100) - pr_data = open_api(url_to("repos", user, repo, "pulls", pr)) + pr_data = API.open_rest(url_to("repos", user, repo, "pulls", pr)) commits_api = pr_data["commits_url"] commit_count = pr_data["commits"] commits = [] if commit_count > API_MAX_ITEMS - raise Error, "Getting #{commit_count} commits would exceed limit of #{API_MAX_ITEMS} API items!" + raise API::Error, "Getting #{commit_count} commits would exceed limit of #{API_MAX_ITEMS} API items!" end - (1..API_MAX_PAGES).each do |page| - result = open_api(commits_api + "?per_page=#{per_page}&page=#{page}") + API.paginate_rest(commits_api, per_page: per_page) do |result, page| commits.concat(result.map { |c| c["sha"] }) return commits if commits.length == commit_count if result.empty? || page * per_page >= commit_count - raise Error, "Expected #{commit_count} commits but actually got #{commits.length}!" + raise API::Error, "Expected #{commit_count} commits but actually got #{commits.length}!" end end end def pull_request_labels(user, repo, pr) - pr_data = open_api(url_to("repos", user, repo, "pulls", pr)) + pr_data = API.open_rest(url_to("repos", user, repo, "pulls", pr)) pr_data["labels"].map { |label| label["name"] } end end diff --git a/Library/Homebrew/utils/github/api.rb b/Library/Homebrew/utils/github/api.rb new file mode 100644 index 0000000000..6653c51376 --- /dev/null +++ b/Library/Homebrew/utils/github/api.rb @@ -0,0 +1,311 @@ +# typed: false +# frozen_string_literal: true + +require "tempfile" +require "utils/shell" + +module GitHub + API_URL = "https://api.github.com" + API_MAX_PAGES = 50 + API_MAX_ITEMS = 5000 + + CREATE_GIST_SCOPES = ["gist"].freeze + CREATE_ISSUE_FORK_OR_PR_SCOPES = ["public_repo"].freeze + CREATE_WORKFLOW_SCOPES = ["workflow"].freeze + ALL_SCOPES = (CREATE_GIST_SCOPES + CREATE_ISSUE_FORK_OR_PR_SCOPES + CREATE_WORKFLOW_SCOPES).freeze + ALL_SCOPES_URL = Formatter.url( + "https://github.com/settings/tokens/new?scopes=#{ALL_SCOPES.join(",")}&description=Homebrew", + ).freeze + CREATE_GITHUB_PAT_MESSAGE = <<~EOS + Create a GitHub personal access token: + #{ALL_SCOPES_URL} + #{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")} + EOS + + # Helper functions to access the GitHub API. + # + # @api private + module API + extend T::Sig + + module_function + + # Generic API error. + class Error < RuntimeError + attr_reader :github_message + end + + # Error when the requested URL is not found. + class HTTPNotFoundError < Error + def initialize(github_message) + @github_message = github_message + super + end + end + + # Error when the API rate limit is exceeded. + class RateLimitExceededError < Error + def initialize(reset, github_message) + @github_message = github_message + super <<~EOS + GitHub API Error: #{github_message} + Try again in #{pretty_ratelimit_reset(reset)}, or: + #{CREATE_GITHUB_PAT_MESSAGE} + EOS + end + + def pretty_ratelimit_reset(reset) + pretty_duration(Time.at(reset) - Time.now) + end + end + + # Error when authentication fails. + class AuthenticationFailedError < Error + def initialize(github_message) + @github_message = github_message + message = +"GitHub #{github_message}:" + message << if Homebrew::EnvConfig.github_api_token + <<~EOS + HOMEBREW_GITHUB_API_TOKEN may be invalid or expired; check: + #{Formatter.url("https://github.com/settings/tokens")} + EOS + else + <<~EOS + The GitHub credentials in the macOS keychain may be invalid. + Clear them with: + printf "protocol=https\\nhost=github.com\\n" | git credential-osxkeychain erase + #{CREATE_GITHUB_PAT_MESSAGE} + EOS + end + super message.freeze + end + end + + # Error when the user has no GitHub API credentials set at all (macOS keychain or envvar). + class MissingAuthenticationError < Error + def initialize + message = +"No GitHub credentials found in macOS Keychain or environment.\n" + message << CREATE_GITHUB_PAT_MESSAGE + super message + end + end + + # Error when the API returns a validation error. + class ValidationFailedError < Error + def initialize(github_message, errors) + @github_message = if errors.empty? + github_message + else + "#{github_message}: #{errors}" + end + + super(@github_message) + end + end + + ERRORS = [ + AuthenticationFailedError, + HTTPNotFoundError, + RateLimitExceededError, + Error, + JSON::ParserError, + ].freeze + + # Gets the password field from `git-credential-osxkeychain` for github.com, + # but only if that password looks like a GitHub Personal Access Token. + sig { returns(T.nilable(String)) } + def keychain_username_password + github_credentials = Utils.popen(["git", "credential-osxkeychain", "get"], "w+") do |pipe| + pipe.write "protocol=https\nhost=github.com\n" + pipe.close_write + pipe.read + end + github_username = github_credentials[/username=(.+)/, 1] + github_password = github_credentials[/password=(.+)/, 1] + return unless github_username + + # Don't use passwords from the keychain unless they look like + # GitHub Personal Access Tokens: + # https://github.com/Homebrew/brew/issues/6862#issuecomment-572610344 + return unless /^[a-f0-9]{40}$/i.match?(github_password) + + github_password + rescue Errno::EPIPE + # The above invocation via `Utils.popen` can fail, causing the pipe to be + # prematurely closed (before we can write to it) and thus resulting in a + # broken pipe error. The root cause is usually a missing or malfunctioning + # `git-credential-osxkeychain` helper. + nil + end + + def credentials + @credentials ||= begin + Homebrew::EnvConfig.github_api_token || keychain_username_password + end + end + + sig { returns(Symbol) } + def credentials_type + if Homebrew::EnvConfig.github_api_token + :env_token + elsif keychain_username_password + :keychain_username_password + else + :none + end + end + + # Given an API response from GitHub, warn the user if their credentials + # have insufficient permissions. + def credentials_error_message(response_headers, needed_scopes) + return if response_headers.empty? + + scopes = response_headers["x-accepted-oauth-scopes"].to_s.split(", ") + needed_scopes = Set.new(scopes || needed_scopes) + credentials_scopes = response_headers["x-oauth-scopes"] + return if needed_scopes.subset?(Set.new(credentials_scopes.to_s.split(", "))) + + needed_scopes = needed_scopes.to_a.join(", ").presence || "none" + credentials_scopes = "none" if credentials_scopes.blank? + + what = case credentials_type + when :keychain_username_password + "macOS keychain GitHub" + when :env_token + "HOMEBREW_GITHUB_API_TOKEN" + end + + @credentials_error_message ||= onoe <<~EOS + Your #{what} credentials do not have sufficient scope! + Scopes required: #{needed_scopes} + Scopes present: #{credentials_scopes} + #{CREATE_GITHUB_PAT_MESSAGE} + EOS + end + + def open_rest(url, data: nil, data_binary_path: nil, request_method: nil, scopes: [].freeze, parse_json: true) + # This is a no-op if the user is opting out of using the GitHub API. + return block_given? ? yield({}) : {} if Homebrew::EnvConfig.no_github_api? + + args = ["--header", "Accept: application/vnd.github.v3+json", "--write-out", "\n%\{http_code}"] + args += ["--header", "Accept: application/vnd.github.antiope-preview+json"] + + token = credentials + args += ["--header", "Authorization: token #{token}"] unless credentials_type == :none + + data_tmpfile = nil + if data + begin + data = JSON.generate data + data_tmpfile = Tempfile.new("github_api_post", HOMEBREW_TEMP) + rescue JSON::ParserError => e + raise Error, "Failed to parse JSON request:\n#{e.message}\n#{data}", e.backtrace + end + end + + if data_binary_path.present? + args += ["--data-binary", "@#{data_binary_path}"] + args += ["--header", "Content-Type: application/gzip"] + end + + headers_tmpfile = Tempfile.new("github_api_headers", HOMEBREW_TEMP) + begin + if data + data_tmpfile.write data + data_tmpfile.close + args += ["--data", "@#{data_tmpfile.path}"] + + args += ["--request", request_method.to_s] if request_method + end + + args += ["--dump-header", headers_tmpfile.path] + + output, errors, status = curl_output("--location", url.to_s, *args, secrets: [token]) + output, _, http_code = output.rpartition("\n") + output, _, http_code = output.rpartition("\n") if http_code == "000" + headers = headers_tmpfile.read + ensure + if data_tmpfile + data_tmpfile.close + data_tmpfile.unlink + end + headers_tmpfile.close + headers_tmpfile.unlink + end + + begin + raise_error(output, errors, http_code, headers, scopes) if !http_code.start_with?("2") || !status.success? + + return if http_code == "204" # No Content + + output = JSON.parse output if parse_json + if block_given? + yield output + else + output + end + rescue JSON::ParserError => e + raise Error, "Failed to parse JSON response\n#{e.message}", e.backtrace + end + end + + def paginate_rest(url, per_page: 100) + (1..API_MAX_PAGES).each do |page| + result = API.open_rest("#{url}?per_page=#{per_page}&page=#{page}") + yield(result, page) + end + end + + def open_graphql(query, scopes: [].freeze) + data = { query: query } + result = open_rest("https://api.github.com/graphql", scopes: scopes, data: data, request_method: "POST") + + if result["errors"].present? + raise Error, result["errors"].map { |e| + "#{e["type"]}: #{e["message"]}" + }.join("\n") + end + + result["data"] + end + + def raise_error(output, errors, http_code, headers, scopes) + json = begin + JSON.parse(output) + rescue + nil + end + message = json&.[]("message") || "curl failed! #{errors}" + + meta = {} + headers.lines.each do |l| + key, _, value = l.delete(":").partition(" ") + key = key.downcase.strip + next if key.empty? + + meta[key] = value.strip + end + + if meta.fetch("x-ratelimit-remaining", 1).to_i <= 0 + reset = meta.fetch("x-ratelimit-reset").to_i + raise RateLimitExceededError.new(reset, message) + end + + credentials_error_message(meta, scopes) + + case http_code + when "401", "403" + raise AuthenticationFailedError, message + when "404" + raise MissingAuthenticationError if credentials_type == :none && scopes.present? + + raise HTTPNotFoundError, message + when "422" + errors = json&.[]("errors") || [] + raise ValidationFailedError.new(message, errors) + else + raise Error, message + end + end + end +end diff --git a/Library/Homebrew/utils/popen.rb b/Library/Homebrew/utils/popen.rb index c5546c6d93..36966a5252 100644 --- a/Library/Homebrew/utils/popen.rb +++ b/Library/Homebrew/utils/popen.rb @@ -50,7 +50,7 @@ module Utils yield pipe else - options[:err] ||= :close unless ENV["HOMEBREW_STDERR"] + options[:err] ||= "/dev/null" unless ENV["HOMEBREW_STDERR"] begin exec(*args, options) rescue Errno::ENOENT diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index 7408ac9988..3beff05829 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -42,7 +42,7 @@ module PyPI @name = package_string @name, @version = @name.split("==") if @name.include? "==" - return unless match = @name.match(/^(.*?)\[(.+)\]$/) + return unless (match = @name.match(/^(.*?)\[(.+)\]$/)) @name = match[1] @extras = match[2].split "," @@ -182,7 +182,7 @@ module PyPI extra_packages = (extra_packages || []).map { |p| Package.new p } exclude_packages = (exclude_packages || []).map { |p| Package.new p } - exclude_packages += %W[#{main_package.name} argparse pip setuptools wheel wsgiref].map { |p| Package.new p } + exclude_packages += %W[#{main_package.name} argparse pip setuptools wsgiref].map { |p| Package.new p } # remove packages from the exclude list if we've explicitly requested them as an extra package exclude_packages.delete_if { |package| extra_packages.include?(package) } diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb index 9e80e455cc..e4517c2cff 100644 --- a/Library/Homebrew/utils/repology.rb +++ b/Library/Homebrew/utils/repology.rb @@ -7,21 +7,24 @@ require "utils/curl" # # @api private module Repology + HOMEBREW_CORE = "homebrew" + HOMEBREW_CASK = "homebrew_casks" + module_function MAX_PAGINATION = 15 private_constant :MAX_PAGINATION - def query_api(last_package_in_response = "") + def query_api(last_package_in_response = "", repository:) last_package_in_response += "/" if last_package_in_response.present? - url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=homebrew&outdated=1" + url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=#{repository}&outdated=1" output, _errors, _status = curl_output(url.to_s) JSON.parse(output) end - def single_package_query(name) - url = "https://repology.org/tools/project-by?repo=homebrew&" \ + def single_package_query(name, repository:) + url = "https://repology.org/tools/project-by?repo=#{repository}&" \ "name_type=srcname&target_page=api_v1_project&name=#{name}" output, _errors, _status = curl_output("--location", url.to_s) @@ -34,26 +37,34 @@ module Repology end end - def parse_api_response(limit = nil) - ohai "Querying outdated packages from Repology" + def parse_api_response(limit = nil, repository:) + package_term = case repository + when HOMEBREW_CORE + "formula" + when HOMEBREW_CASK + "cask" + else + "package" + end + + ohai "Querying outdated #{package_term.pluralize} from Repology" page_no = 1 outdated_packages = {} - last_package_index = "" + last_package = "" while page_no <= MAX_PAGINATION odebug "Paginating Repology API page: #{page_no}" - response = query_api(last_package_index.to_s) - response_size = response.size + response = query_api(last_package, repository: repository) outdated_packages.merge!(response) - last_package_index = outdated_packages.size - 1 + last_package = response.keys.last page_no += 1 - break if limit && outdated_packages.size >= limit || response_size <= 1 + break if limit && outdated_packages.size >= limit || response.size <= 1 end - puts "#{outdated_packages.size} outdated #{"package".pluralize(outdated_packages.size)} found" + puts "#{outdated_packages.size} outdated #{package_term.pluralize(outdated_packages.size)} found" puts outdated_packages diff --git a/Library/Homebrew/utils/rubocop.rb b/Library/Homebrew/utils/rubocop.rb new file mode 100755 index 0000000000..ae6050ddd0 --- /dev/null +++ b/Library/Homebrew/utils/rubocop.rb @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby +# typed: false +# frozen_string_literal: true + +require_relative "gems" +Homebrew.setup_gem_environment! + +require_relative "../warnings" + +Warnings.ignore :parser_syntax do + require "rubocop" +end + +exit RuboCop::CLI.new.run diff --git a/Library/Homebrew/utils/shared_audits.rb b/Library/Homebrew/utils/shared_audits.rb index 310b497521..ff17b0b8a8 100644 --- a/Library/Homebrew/utils/shared_audits.rb +++ b/Library/Homebrew/utils/shared_audits.rb @@ -17,17 +17,18 @@ module SharedAudits @github_repo_data["#{user}/#{repo}"] ||= GitHub.repository(user, repo) @github_repo_data["#{user}/#{repo}"] - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError nil end def github_release_data(user, repo, tag) id = "#{user}/#{repo}/#{tag}" + url = "#{GitHub::API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}" @github_release_data ||= {} - @github_release_data[id] ||= GitHub.open_api("#{GitHub::API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}") + @github_release_data[id] ||= GitHub::API.open_rest(url) @github_release_data[id] - rescue GitHub::HTTPNotFoundError + rescue GitHub::API::HTTPNotFoundError nil end diff --git a/Library/Homebrew/utils/sorbet.rb b/Library/Homebrew/utils/sorbet.rb index 2f91f50bb8..aaf7f223fd 100644 --- a/Library/Homebrew/utils/sorbet.rb +++ b/Library/Homebrew/utils/sorbet.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true if ENV["HOMEBREW_SORBET_RUNTIME"] - require "utils/gems" Homebrew.install_bundler_gems! require "sorbet-runtime" else diff --git a/Library/Homebrew/utils/spdx.rb b/Library/Homebrew/utils/spdx.rb index 1fe89ae6fa..43e19401f7 100644 --- a/Library/Homebrew/utils/spdx.rb +++ b/Library/Homebrew/utils/spdx.rb @@ -29,7 +29,7 @@ module SPDX end def latest_tag - @latest_tag ||= GitHub.open_api(API_URL)["tag_name"] + @latest_tag ||= GitHub::API.open_rest(API_URL)["tag_name"] end def download_latest_license_data!(to: DATA_PATH) @@ -78,6 +78,7 @@ module SPDX return false if ALLOWED_LICENSE_SYMBOLS.include? license return false unless valid_license?(license) + license = license.delete_suffix "+" license_data["licenses"].none? do |spdx_license| spdx_license["licenseId"] == license && !spdx_license["isDeprecatedLicenseId"] end @@ -110,7 +111,7 @@ module SPDX else bracket = false license_expression.each do |expression| - expressions.push license_expression_to_string(Hash[*expression], bracket: true) + expressions.push license_expression_to_string([expression].to_h, bracket: true) end end diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index 74f833e8d2..e43d4e752f 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -4,11 +4,11 @@ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby' ruby_version = RbConfig::CONFIG["ruby_version"] path = File.expand_path('..', __FILE__) $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.8.8/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.14.3/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.8.9/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.14.4/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-2.0.4/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.4.2/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.1.2/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.1.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.8/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/msgpack-1.4.2" @@ -36,14 +36,14 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/elftools-1.1.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/hpricot-0.8.6" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/hpricot-0.8.6/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/http-cookie-1.0.3/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-data-3.2020.1104/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-data-3.2021.0212/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-3.3.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/net-http-digest_auth-1.4.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/net-http-persistent-4.0.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mini_portile2-2.5.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/racc-1.5.2" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/racc-1.5.2/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/nokogiri-1.11.1-x86_64-darwin/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/nokogiri-1.11.2-x86_64-darwin/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ntlm-http-0.1.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrick-1.7.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrobots-0.1.2/lib" @@ -51,24 +51,24 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mechanize-2.7.7/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/method_source-1.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mustache-1.1.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.20.1/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.4.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.5.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-3.0.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.6267/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-5.0.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.6274/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-6.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.3.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.6.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/pry-0.13.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/pry-0.14.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rack-2.2.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/rdiscount-2.2.0.2" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rdiscount-2.2.0.2/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/regexp_parser-2.0.3/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/regexp_parser-2.1.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rexml-3.2.4/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ronn-0.7.3/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.10.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-core-3.10.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-expectations-3.10.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-mocks-3.10.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.10.2/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-core-3.10.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-expectations-3.10.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-mocks-3.10.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.10.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-github-2.3.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib" @@ -80,13 +80,14 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-1.4.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.11.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.0.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.9.1/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.9.2/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.11.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.10.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rails-2.9.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.2.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.5.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.6.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.5.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-stub-0.2.0/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.0.1/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.0.7/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.4.13/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.1.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.0.9/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.4.17/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/warning-1.2.0/lib" diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/actionable_error.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/actionable_error.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/actionable_error.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/actionable_error.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/array_inquirer.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/array_inquirer.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/array_inquirer.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/array_inquirer.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/backtrace_cleaner.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/backtrace_cleaner.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/backtrace_cleaner.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/backtrace_cleaner.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/benchmarkable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/benchmarkable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/benchmarkable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/benchmarkable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/builder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/builder.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/builder.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/builder.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/callbacks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/callbacks.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/callbacks.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/callbacks.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/concern.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/concern.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/concern.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/concern.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/configurable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/configurable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/configurable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/configurable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/configuration_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/configuration_file.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/configuration_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/configuration_file.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/access.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/access.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/access.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/access.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/extract.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/extract.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/extract.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/extract.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/extract_options.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/extract_options.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/extract_options.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/extract_options.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/grouping.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/grouping.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/grouping.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/grouping.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/inquiry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/inquiry.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/inquiry.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/inquiry.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/wrap.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/wrap.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/array/wrap.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/array/wrap.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/benchmark.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/benchmark.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/benchmark.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/benchmark.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/big_decimal.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/big_decimal.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/big_decimal.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/big_decimal.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/big_decimal/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/big_decimal/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/big_decimal/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/big_decimal/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/attribute.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/attribute.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/attribute.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/attribute.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/attribute_accessors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/attribute_accessors.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/attribute_accessors.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/attribute_accessors.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/subclasses.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/subclasses.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/class/subclasses.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/class/subclasses.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/acts_like.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/acts_like.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/acts_like.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/acts_like.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/blank.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/blank.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/blank.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/blank.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/calculations.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/calculations.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/calculations.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/calculations.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/zones.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/zones.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date/zones.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date/zones.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/calculations.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/calculations.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/calculations.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/calculations.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/compatibility.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/compatibility.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/compatibility.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/compatibility.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/zones.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/zones.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_and_time/zones.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_and_time/zones.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/acts_like.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/acts_like.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/acts_like.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/acts_like.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/blank.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/blank.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/blank.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/blank.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/calculations.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/calculations.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/calculations.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/calculations.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/compatibility.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/compatibility.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/compatibility.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/compatibility.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/date_time/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/date_time/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/digest.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/digest.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/digest.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/digest.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/digest/uuid.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/digest/uuid.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/digest/uuid.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/digest/uuid.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/enumerable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/enumerable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/enumerable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/file.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/file.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/file/atomic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/file/atomic.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/file/atomic.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/file/atomic.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/deep_merge.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/deep_merge.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/deep_merge.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/deep_merge.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/deep_transform_values.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/deep_transform_values.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/deep_transform_values.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/deep_transform_values.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/except.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/except.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/except.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/except.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/indifferent_access.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/indifferent_access.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/indifferent_access.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/indifferent_access.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/keys.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/keys.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/keys.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/keys.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/reverse_merge.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/reverse_merge.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/reverse_merge.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/reverse_merge.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/slice.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/slice.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/hash/slice.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/hash/slice.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/inflections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/inflections.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/inflections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/inflections.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/multiple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/multiple.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/multiple.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/multiple.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/time.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/time.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/integer/time.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/integer/time.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/concern.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/concern.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/concern.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/concern.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/reporting.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/reporting.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/reporting.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/reporting.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/singleton_class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/singleton_class.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/kernel/singleton_class.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/kernel/singleton_class.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/load_error.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/load_error.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/load_error.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/load_error.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/marshal.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/marshal.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/marshal.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/marshal.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/aliasing.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/aliasing.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/aliasing.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/aliasing.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/anonymous.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/anonymous.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/anonymous.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/anonymous.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attr_internal.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attr_internal.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attr_internal.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attr_internal.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attribute_accessors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attribute_accessors.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attribute_accessors.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attribute_accessors.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/concerning.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/concerning.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/concerning.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/concerning.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/delegation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/delegation.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/delegation.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/delegation.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/deprecation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/deprecation.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/deprecation.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/deprecation.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/introspection.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/introspection.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/introspection.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/introspection.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/redefine_method.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/redefine_method.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/redefine_method.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/redefine_method.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/remove_method.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/remove_method.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/module/remove_method.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/module/remove_method.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/name_error.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/name_error.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/name_error.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/name_error.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/bytes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/bytes.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/bytes.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/bytes.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/time.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/time.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/numeric/time.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/numeric/time.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/acts_like.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/acts_like.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/acts_like.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/acts_like.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/blank.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/blank.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/blank.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/blank.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/deep_dup.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/deep_dup.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/deep_dup.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/deep_dup.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/duplicable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/duplicable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/duplicable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/duplicable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/inclusion.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/inclusion.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/inclusion.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/inclusion.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/instance_variables.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/instance_variables.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/instance_variables.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/instance_variables.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/json.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/json.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/json.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/json.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/to_param.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/to_param.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/to_param.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/to_param.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/to_query.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/to_query.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/to_query.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/to_query.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/try.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/try.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/try.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/try.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/with_options.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/with_options.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/object/with_options.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/object/with_options.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/compare_range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/compare_range.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/compare_range.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/compare_range.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/each.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/each.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/each.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/each.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/include_time_with_zone.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/include_time_with_zone.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/include_time_with_zone.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/include_time_with_zone.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/overlaps.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/overlaps.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/range/overlaps.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/range/overlaps.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/regexp.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/regexp.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/regexp.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/regexp.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/securerandom.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/securerandom.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/securerandom.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/securerandom.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/access.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/access.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/access.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/access.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/behavior.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/behavior.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/behavior.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/behavior.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/exclude.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/exclude.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/exclude.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/exclude.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/filters.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/filters.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/filters.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/filters.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/indent.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/indent.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/indent.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/indent.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/inflections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/inflections.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/inflections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/inflections.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/inquiry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/inquiry.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/inquiry.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/inquiry.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/multibyte.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/multibyte.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/multibyte.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/multibyte.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/output_safety.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/output_safety.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/output_safety.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/output_safety.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/starts_ends_with.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/starts_ends_with.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/starts_ends_with.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/starts_ends_with.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/strip.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/strip.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/strip.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/strip.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/zones.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/zones.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/string/zones.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/string/zones.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/symbol.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/symbol.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/symbol.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/symbol.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/symbol/starts_ends_with.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/symbol/starts_ends_with.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/symbol/starts_ends_with.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/symbol/starts_ends_with.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/acts_like.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/acts_like.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/acts_like.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/acts_like.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/calculations.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/calculations.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/calculations.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/calculations.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/compatibility.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/compatibility.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/compatibility.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/compatibility.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/conversions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/conversions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/conversions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/conversions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/zones.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/zones.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/time/zones.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/time/zones.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/uri.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/uri.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/core_ext/uri.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/core_ext/uri.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/current_attributes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/current_attributes.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/current_attributes.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/current_attributes.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/current_attributes/test_helper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/current_attributes/test_helper.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/current_attributes/test_helper.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/current_attributes/test_helper.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/behaviors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/behaviors.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/behaviors.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/behaviors.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/constant_accessor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/constant_accessor.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/constant_accessor.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/constant_accessor.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/disallowed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/disallowed.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/disallowed.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/disallowed.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/instance_delegator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/instance_delegator.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/instance_delegator.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/instance_delegator.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/method_wrappers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/method_wrappers.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/method_wrappers.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/method_wrappers.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/proxy_wrappers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/proxy_wrappers.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/proxy_wrappers.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/proxy_wrappers.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/reporting.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/reporting.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/deprecation/reporting.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/deprecation/reporting.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/descendants_tracker.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/descendants_tracker.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/descendants_tracker.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/descendants_tracker.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/digest.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/digest.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/digest.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/digest.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/duration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/duration.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/duration.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/duration.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/encrypted_configuration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/encrypted_configuration.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/encrypted_configuration.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/encrypted_configuration.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/encrypted_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/encrypted_file.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/encrypted_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/encrypted_file.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/environment_inquirer.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/environment_inquirer.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/environment_inquirer.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/environment_inquirer.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/evented_file_update_checker.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/evented_file_update_checker.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/evented_file_update_checker.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/evented_file_update_checker.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/execution_wrapper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/execution_wrapper.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/execution_wrapper.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/execution_wrapper.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/executor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/executor.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/executor.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/executor.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/file_update_checker.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/file_update_checker.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/file_update_checker.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/file_update_checker.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/fork_tracker.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/fork_tracker.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/fork_tracker.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/fork_tracker.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/gem_version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/gem_version.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/gem_version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/gem_version.rb index 47a1a4219f..545641c8ae 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/gem_version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/gem_version.rb @@ -9,7 +9,7 @@ module ActiveSupport module VERSION MAJOR = 6 MINOR = 1 - TINY = 2 + TINY = 3 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/gzip.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/gzip.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/gzip.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/gzip.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/hash_with_indifferent_access.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/hash_with_indifferent_access.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/hash_with_indifferent_access.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/hash_with_indifferent_access.rb index 26a9db0654..71198ef10f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/hash_with_indifferent_access.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/hash_with_indifferent_access.rb @@ -113,7 +113,7 @@ module ActiveSupport # ActiveSupport::HashWithIndifferentAccess or a regular +Hash+. # In either case the merge respects the semantics of indifferent access. # - # If the argument is a regular hash with keys +:key+ and +"key"+ only one + # If the argument is a regular hash with keys +:key+ and "key" only one # of the values end up in the receiver, but which one is unspecified. # # When given a block, the value for duplicated keys will be determined diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/i18n.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/i18n.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/i18n.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/i18n.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/i18n_railtie.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/i18n_railtie.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/i18n_railtie.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/i18n_railtie.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflections.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflections.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/inflections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/inflections.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/inflections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/inflections.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/methods.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/methods.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/methods.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/transliterate.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/transliterate.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/inflector/transliterate.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/inflector/transliterate.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/key_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/key_generator.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/key_generator.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/key_generator.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/lazy_load_hooks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/lazy_load_hooks.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/locale/en.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/locale/en.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/locale/en.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/locale/en.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/locale/en.yml b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/locale/en.yml similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/locale/en.yml rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/locale/en.yml diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger_silence.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger_silence.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger_silence.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger_silence.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger_thread_safe_level.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger_thread_safe_level.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/logger_thread_safe_level.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/logger_thread_safe_level.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/message_encryptor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/message_encryptor.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/message_encryptor.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/message_encryptor.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/message_verifier.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/message_verifier.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/message_verifier.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/message_verifier.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/multibyte.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/multibyte.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/multibyte.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/multibyte.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications.rb index a7a6112b0f..d1227c2473 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications.rb @@ -178,7 +178,7 @@ module ActiveSupport # # Subscribers using a regexp or other pattern-matching object will remain subscribed # to all events that match their original pattern, unless those events match a string - # passed to `unsubscribe`: + # passed to +unsubscribe+: # # subscriber = ActiveSupport::Notifications.subscribe(/render/) { } # ActiveSupport::Notifications.unsubscribe('render_template.action_view') diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications/fanout.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications/fanout.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications/fanout.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications/fanout.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications/instrumenter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications/instrumenter.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/notifications/instrumenter.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/notifications/instrumenter.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/option_merger.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/option_merger.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/option_merger.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/option_merger.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/ordered_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/ordered_hash.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/ordered_hash.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/ordered_hash.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/ordered_options.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/ordered_options.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/ordered_options.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/ordered_options.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/parameter_filter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/parameter_filter.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/parameter_filter.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/parameter_filter.rb index 6f9289cab9..134778251f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/parameter_filter.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/parameter_filter.rb @@ -33,7 +33,7 @@ module ActiveSupport # # ==== Options # - # * :mask - A replaced object when filtered. Defaults to +"[FILTERED]"+ + # * :mask - A replaced object when filtered. Defaults to "[FILTERED]". def initialize(filters = [], mask: FILTERED) @filters = filters @mask = mask diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/per_thread_registry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/per_thread_registry.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/per_thread_registry.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/per_thread_registry.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/proxy_object.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/proxy_object.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/proxy_object.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/proxy_object.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/rails.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/rails.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/rails.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/rails.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/railtie.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/railtie.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/railtie.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/railtie.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/reloader.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/reloader.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/reloader.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/reloader.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/rescuable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/rescuable.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/rescuable.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/rescuable.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/secure_compare_rotator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/secure_compare_rotator.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/secure_compare_rotator.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/secure_compare_rotator.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/security_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/security_utils.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/security_utils.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/security_utils.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/string_inquirer.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/string_inquirer.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/string_inquirer.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/string_inquirer.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/subscriber.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/subscriber.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/subscriber.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/subscriber.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/tagged_logging.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/tagged_logging.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/tagged_logging.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/tagged_logging.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/test_case.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/test_case.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/test_case.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/test_case.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/time.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/time.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/time.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/time.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/time_with_zone.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/time_with_zone.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/time_with_zone.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/time_with_zone.rb index e01457b56a..03d49d597f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/time_with_zone.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/time_with_zone.rb @@ -301,7 +301,7 @@ module ActiveSupport alias_method :in, :+ # Subtracts an interval of time and returns a new TimeWithZone object unless - # the other value `acts_like?` time. Then it will return a Float of the difference + # the other value +acts_like?+ time. Then it will return a Float of the difference # between the two times that represents the difference between the current # object's time and the +other+ time. # diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/values/time_zone.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/values/time_zone.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/values/time_zone.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/values/time_zone.rb index 2e5d9d3e9d..4c289a5836 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/values/time_zone.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/values/time_zone.rb @@ -508,7 +508,7 @@ module ActiveSupport # Time#in_time_zone() instead. # # As of tzinfo 2, utc_to_local returns a Time with a non-zero utc_offset. - # See the `utc_to_local_returns_utc_offset_times` config for more info. + # See the +utc_to_local_returns_utc_offset_times+ config for more info. def utc_to_local(time) tzinfo.utc_to_local(time).yield_self do |t| ActiveSupport.utc_to_local_returns_utc_offset_times ? diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/version.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/version.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/jdom.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/jdom.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/jdom.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/jdom.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/libxml.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/libxml.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/libxml.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/libxml.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/libxmlsax.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/libxmlsax.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/libxmlsax.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/libxmlsax.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/nokogiri.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/nokogiri.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/nokogiri.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/nokogiri.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/nokogirisax.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/nokogirisax.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/nokogirisax.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/nokogirisax.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/rexml.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/rexml.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.2/lib/active_support/xml_mini/rexml.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.3/lib/active_support/xml_mini/rexml.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/base.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/base.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/base.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/base.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cache.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cache.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cache.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cache.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cache_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cache_file.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cache_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cache_file.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cascade.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cascade.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/cascade.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/cascade.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/chain.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/chain.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/chain.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/chain.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/fallbacks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/fallbacks.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/fallbacks.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/fallbacks.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/flatten.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/flatten.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/flatten.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/flatten.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/gettext.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/gettext.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/gettext.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/gettext.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/interpolation_compiler.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/interpolation_compiler.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/interpolation_compiler.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/interpolation_compiler.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/key_value.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/key_value.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/key_value.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/key_value.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/memoize.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/memoize.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/memoize.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/memoize.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/metadata.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/metadata.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/metadata.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/metadata.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/pluralization.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/pluralization.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/pluralization.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/pluralization.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/simple.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/simple.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/simple.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/transliterator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/transliterator.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/backend/transliterator.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/backend/transliterator.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/config.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/config.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/config.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/config.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/core_ext/hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/core_ext/hash.rb similarity index 97% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/core_ext/hash.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/core_ext/hash.rb index 775d490d34..e022e84234 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/core_ext/hash.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/core_ext/hash.rb @@ -4,7 +4,7 @@ module I18n using I18n::HashRefinements def except(*keys) dup.except!(*keys) - end + end unless method_defined?(:except) def except!(*keys) keys.each { |key| delete(key) } diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/exceptions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/exceptions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/exceptions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/exceptions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext/helpers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext/helpers.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext/helpers.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext/helpers.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext/po_parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext/po_parser.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/gettext/po_parser.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/gettext/po_parser.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/interpolate/ruby.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/interpolate/ruby.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/interpolate/ruby.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/interpolate/ruby.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/fallbacks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/fallbacks.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/fallbacks.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/fallbacks.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/parents.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/parents.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/parents.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/parents.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/rfc4646.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/rfc4646.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/rfc4646.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/rfc4646.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/simple.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/locale/tag/simple.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/locale/tag/simple.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/middleware.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/middleware.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/middleware.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/middleware.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/version.rb similarity index 70% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/version.rb index 0f0cebd5cf..77c13e585f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.8/lib/i18n/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/i18n-1.8.9/lib/i18n/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module I18n - VERSION = "1.8.8" + VERSION = "1.8.9" end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/config/default.yml b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/config/default.yml similarity index 93% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/config/default.yml rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/config/default.yml index dfb20d66d7..17f3e7c249 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/config/default.yml +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/config/default.yml @@ -10,7 +10,7 @@ Performance/AncestorsInclude: Performance/ArraySemiInfiniteRangeSlice: Description: 'Identifies places where slicing arrays with semi-infinite ranges can be replaced by `Array#take` and `Array#drop`.' # This cop was created due to a mistake in microbenchmark. - # Refer https://github.com/rubocop-hq/rubocop-performance/pull/175#issuecomment-731892717 + # Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717 Enabled: false # Unsafe for string slices because strings do not have `#take` and `#drop` methods. Safe: false @@ -80,6 +80,7 @@ Performance/ConstantRegexp: Description: 'Finds regular expressions with dynamic components that are all constants.' Enabled: pending VersionAdded: '1.9' + VersionChanged: '1.10' Performance/Count: Description: >- @@ -136,11 +137,10 @@ Performance/EndWith: # object. Switching these methods has to be done with knowledge of the types # of the variables which rubocop doesn't have. SafeAutoCorrect: false - AutoCorrect: false Enabled: true SafeMultiline: true VersionAdded: '0.36' - VersionChanged: '1.6' + VersionChanged: '1.10' Performance/FixedSize: Description: 'Do not compute the size of statically sized objects except in constants.' @@ -200,6 +200,15 @@ Performance/RedundantBlockCall: Enabled: true VersionAdded: '0.36' +Performance/RedundantEqualityComparisonBlock: + Description: >- + Checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`, + or `Enumerable#none?` are compared with `===` or similar methods in block. + Reference: 'https://github.com/rails/rails/pull/41363' + Enabled: pending + Safe: false + VersionAdded: '1.10' + Performance/RedundantMatch: Description: >- Use `=~` instead of `String#match` or `Regexp#match` in a context where the @@ -220,6 +229,11 @@ Performance/RedundantSortBlock: Enabled: 'pending' VersionAdded: '1.7' +Performance/RedundantSplitRegexpArgument: + Description: 'This cop identifies places where `split` argument can be replaced from a deterministic regexp to a string.' + Enabled: pending + VersionAdded: '1.10' + Performance/RedundantStringChars: Description: 'Checks for redundant `String#chars`.' Enabled: 'pending' @@ -270,11 +284,10 @@ Performance/StartWith: # object. Switching these methods has to be done with knowledge of the types # of the variables which rubocop doesn't have. SafeAutoCorrect: false - AutoCorrect: false Enabled: true SafeMultiline: true VersionAdded: '0.36' - VersionChanged: '1.6' + VersionChanged: '1.10' Performance/StringInclude: Description: 'Use `String#include?` instead of a regex match with literal-only pattern.' @@ -304,7 +317,7 @@ Performance/TimesMap: Enabled: true VersionAdded: '0.36' VersionChanged: '0.50' - SafeAutoCorrect: false # see https://github.com/rubocop-hq/rubocop/issues/4658 + SafeAutoCorrect: false # see https://github.com/rubocop/rubocop/issues/4658 Performance/UnfreezeString: Description: 'Use unary plus to get an unfrozen string literal.' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop-performance.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop-performance.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop-performance.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop-performance.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/mixin/regexp_metacharacter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/mixin/regexp_metacharacter.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/mixin/regexp_metacharacter.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/mixin/regexp_metacharacter.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/mixin/sort_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/mixin/sort_block.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/mixin/sort_block.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/mixin/sort_block.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/ancestors_include.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/ancestors_include.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/ancestors_include.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/ancestors_include.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb index 61250a3596..bb0b39ee91 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb @@ -6,7 +6,7 @@ module RuboCop # This cop identifies places where slicing arrays with semi-infinite ranges # can be replaced by `Array#take` and `Array#drop`. # This cop was created due to a mistake in microbenchmark and hence is disabled by default. - # Refer https://github.com/rubocop-hq/rubocop-performance/pull/175#issuecomment-731892717 + # Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717 # This cop is also unsafe for string slices because strings do not have `#take` and `#drop` methods. # # @example diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/bind_call.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/bind_call.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/bind_call.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/bind_call.rb index 001209171f..0e97597ba2 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/bind_call.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/bind_call.rb @@ -33,7 +33,7 @@ module RuboCop def_node_matcher :bind_with_call_method?, <<~PATTERN (send $(send - (send nil? _) :bind + _ :bind $(...)) :call $...) PATTERN @@ -64,7 +64,7 @@ module RuboCop def correction_range(receiver, node) location_of_bind = receiver.loc.selector.begin_pos - location_of_call = node.loc.end.end_pos + location_of_call = node.source_range.end.end_pos range_between(location_of_bind, location_of_call) end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/block_given_with_explicit_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/block_given_with_explicit_block.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/block_given_with_explicit_block.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/block_given_with_explicit_block.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/caller.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/caller.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/caller.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/caller.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/case_when_splat.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/case_when_splat.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/case_when_splat.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/case_when_splat.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/casecmp.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/casecmp.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/casecmp.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/casecmp.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/chain_array_allocation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/chain_array_allocation.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/chain_array_allocation.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/chain_array_allocation.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/collection_literal_in_loop.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/collection_literal_in_loop.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/collection_literal_in_loop.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/collection_literal_in_loop.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/compare_with_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/compare_with_block.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/compare_with_block.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/compare_with_block.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/constant_regexp.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/constant_regexp.rb similarity index 76% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/constant_regexp.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/constant_regexp.rb index 09e5c0d81f..dcb55dd0fd 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/constant_regexp.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/constant_regexp.rb @@ -6,9 +6,9 @@ module RuboCop # This cop finds regular expressions with dynamic components that are all constants. # # Ruby allocates a new Regexp object every time it executes a code containing such - # a regular expression. It is more efficient to extract it into a constant - # or add an `/o` option to perform `#{}` interpolation only once and reuse that - # Regexp object. + # a regular expression. It is more efficient to extract it into a constant, + # memoize it, or add an `/o` option to perform `#{}` interpolation only once and + # reuse that Regexp object. # # @example # @@ -28,13 +28,18 @@ module RuboCop # pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/o) } # end # + # # good + # def separators + # @separators ||= /\A#{SEPARATORS}\Z/ + # end + # class ConstantRegexp < Base extend AutoCorrector - MSG = 'Extract this regexp into a constant or append an `/o` option to its options.' + MSG = 'Extract this regexp into a constant, memoize it, or append an `/o` option to its options.' def on_regexp(node) - return if within_const_assignment?(node) || + return if within_allowed_assignment?(node) || !include_interpolated_const?(node) || node.single_interpolation? @@ -45,8 +50,8 @@ module RuboCop private - def within_const_assignment?(node) - node.each_ancestor(:casgn).any? + def within_allowed_assignment?(node) + node.each_ancestor(:casgn, :or_asgn).any? end def_node_matcher :regexp_escape?, <<~PATTERN diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/count.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/count.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/count.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/count.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/delete_prefix.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/delete_prefix.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/delete_prefix.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/delete_prefix.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/delete_suffix.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/delete_suffix.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/delete_suffix.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/delete_suffix.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/detect.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/detect.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/detect.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/detect.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/double_start_end_with.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/double_start_end_with.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/double_start_end_with.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/double_start_end_with.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/end_with.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/end_with.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/end_with.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/end_with.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/fixed_size.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/fixed_size.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/fixed_size.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/fixed_size.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/flat_map.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/flat_map.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/flat_map.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/flat_map.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/inefficient_hash_search.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/inefficient_hash_search.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/inefficient_hash_search.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/inefficient_hash_search.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/io_readlines.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/io_readlines.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/io_readlines.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/io_readlines.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/method_object_as_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/method_object_as_block.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/method_object_as_block.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/method_object_as_block.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/open_struct.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/open_struct.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/open_struct.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/open_struct.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/range_include.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/range_include.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/range_include.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/range_include.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_block_call.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_block_call.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_block_call.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_block_call.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb new file mode 100644 index 0000000000..0e91f808f5 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Performance + # This cop checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`, + # and `Enumerable#none?` are compared with `===` or similar methods in block. + # + # By default, `Object#===` behaves the same as `Object#==`, but this + # behavior is appropriately overridden in subclass. For example, + # `Range#===` returns `true` when argument is within the range. + # Therefore, It is marked as unsafe by default because `===` and `==` + # do not always behave the same. + # + # @example + # # bad + # items.all? { |item| pattern === item } + # items.all? { |item| item == other } + # items.all? { |item| item.is_a?(Klass) } + # items.all? { |item| item.kind_of?(Klass) } + # + # # good + # items.all?(pattern) + # + class RedundantEqualityComparisonBlock < Base + extend AutoCorrector + extend TargetRubyVersion + + minimum_target_ruby_version 2.5 + + MSG = 'Use `%s` instead of block.' + + TARGET_METHODS = %i[all? any? one? none?].freeze + COMPARISON_METHODS = %i[== === is_a? kind_of?].freeze + IS_A_METHODS = %i[is_a? kind_of?].freeze + + def on_block(node) + return unless TARGET_METHODS.include?(node.method_name) && node.arguments.one? + + block_argument = node.arguments.first + block_body = node.body + return unless use_equality_comparison_block?(block_body) + return if same_block_argument_and_is_a_argument?(block_body, block_argument) + return unless (new_argument = new_argument(block_argument, block_body)) + + range = offense_range(node) + prefer = "#{node.method_name}(#{new_argument})" + + add_offense(range, message: format(MSG, prefer: prefer)) do |corrector| + corrector.replace(range, prefer) + end + end + + private + + def use_equality_comparison_block?(block_body) + block_body.send_type? && COMPARISON_METHODS.include?(block_body.method_name) + end + + def same_block_argument_and_is_a_argument?(block_body, block_argument) + return false unless IS_A_METHODS.include?(block_body.method_name) + + block_argument.source == block_body.first_argument.source + end + + def new_argument(block_argument, block_body) + if block_argument.source == block_body.receiver.source + block_body.first_argument.source + elsif block_argument.source == block_body.first_argument.source + block_body.receiver.source + end + end + + def offense_range(node) + node.send_node.loc.selector.join(node.source_range.end) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_match.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_match.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_match.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_match.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_merge.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_merge.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_merge.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_merge.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_sort_block.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_sort_block.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_sort_block.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_sort_block.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb new file mode 100644 index 0000000000..6113c1e4cb --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Performance + # This cop identifies places where `split` argument can be replaced from + # a deterministic regexp to a string. + # + # @example + # # bad + # 'a,b,c'.split(/,/) + # + # # good + # 'a,b,c'.split(',') + class RedundantSplitRegexpArgument < Base + extend AutoCorrector + + MSG = 'Use string as argument instead of regexp.' + RESTRICT_ON_SEND = %i[split].freeze + DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze + STR_SPECIAL_CHARS = %w[\n \" \' \\\\ \t \b \f \r].freeze + + def_node_matcher :split_call_with_regexp?, <<~PATTERN + {(send !nil? :split $regexp)} + PATTERN + + def on_send(node) + return unless (regexp_node = split_call_with_regexp?(node)) + return if regexp_node.ignore_case? + return unless determinist_regexp?(regexp_node) + + add_offense(regexp_node) do |corrector| + new_argument = replacement(regexp_node) + + corrector.replace(regexp_node, "\"#{new_argument}\"") + end + end + + private + + def determinist_regexp?(regexp_node) + DETERMINISTIC_REGEX.match?(regexp_node.source) + end + + def replacement(regexp_node) + regexp_content = regexp_node.content + stack = [] + chars = regexp_content.chars.each_with_object([]) do |char, strings| + if stack.empty? && char == '\\' + stack.push(char) + else + strings << "#{stack.pop}#{char}" + end + end + chars.map do |char| + char = char.dup + char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char) + char + end.join + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_string_chars.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_string_chars.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/redundant_string_chars.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/redundant_string_chars.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/regexp_match.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/regexp_match.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/regexp_match.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/regexp_match.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/reverse_each.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/reverse_each.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/reverse_each.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/reverse_each.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/reverse_first.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/reverse_first.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/reverse_first.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/reverse_first.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/size.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/size.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/size.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/size.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/sort_reverse.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/sort_reverse.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/sort_reverse.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/sort_reverse.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/squeeze.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/squeeze.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/squeeze.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/squeeze.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/start_with.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/start_with.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/start_with.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/start_with.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/string_include.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/string_include.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/string_include.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/string_include.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/string_replacement.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/string_replacement.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/string_replacement.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/string_replacement.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/sum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/sum.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/sum.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/sum.rb index 211b17425c..df336773b3 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/sum.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/sum.rb @@ -150,7 +150,9 @@ module RuboCop replacement = build_good_method(init, block_pass) corrector.remove(sum_range) - corrector.replace(map_range, ".#{replacement}") + + dot = '.' if map.receiver + corrector.replace(map_range, "#{dot}#{replacement}") end def sum_method_range(node) @@ -228,7 +230,11 @@ module RuboCop end def method_call_with_args_range(node) - node.receiver.source_range.end.join(node.source_range.end) + if (receiver = node.receiver) + receiver.source_range.end.join(node.source_range.end) + else + node.source_range + end end end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/times_map.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/times_map.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/times_map.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/times_map.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/unfreeze_string.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/unfreeze_string.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/unfreeze_string.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/unfreeze_string.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/uri_default_parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/uri_default_parser.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance/uri_default_parser.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance/uri_default_parser.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance_cops.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance_cops.rb similarity index 94% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance_cops.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance_cops.rb index 9a37fac7ed..41ca77a3c3 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/cop/performance_cops.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/cop/performance_cops.rb @@ -28,9 +28,11 @@ require_relative 'performance/open_struct' require_relative 'performance/range_include' require_relative 'performance/io_readlines' require_relative 'performance/redundant_block_call' +require_relative 'performance/redundant_equality_comparison_block' require_relative 'performance/redundant_match' require_relative 'performance/redundant_merge' require_relative 'performance/redundant_sort_block' +require_relative 'performance/redundant_split_regexp_argument' require_relative 'performance/redundant_string_chars' require_relative 'performance/regexp_match' require_relative 'performance/reverse_each' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance/inject.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance/inject.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance/inject.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance/inject.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance/version.rb similarity index 91% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance/version.rb index 2f4f2209a9..a7fecaa8ce 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.9.2/lib/rubocop/performance/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-performance-1.10.1/lib/rubocop/performance/version.rb @@ -4,7 +4,7 @@ module RuboCop module Performance # This module holds the RuboCop Performance version information. module Version - STRING = '1.9.2' + STRING = '1.10.1' def self.document_version STRING.match('\d+\.\d+').to_s diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/config/default.yml b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/config/default.yml similarity index 85% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/config/default.yml rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/config/default.yml index 4e1602c037..50ed03d75d 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/config/default.yml +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/config/default.yml @@ -53,6 +53,13 @@ Sorbet/FalseSigil: - db/**/*.rb - script/**/* +Sorbet/ForbidExtendTSigHelpersInShims: + Description: 'Forbid the use of `extend T::Sig` and `extend T::Helpers` in RBI shims' + Enabled: true + VersionAdded: '0.6.0' + Include: + - "**/*.rbi" + Sorbet/ForbidIncludeConstLiteral: Description: 'Forbids include of non-literal constants.' Enabled: false @@ -63,7 +70,9 @@ Sorbet/ForbidSuperclassConstLiteral: Description: 'Forbid superclasses which are non-literal constants.' Enabled: false VersionAdded: 0.2.0 - VersionChanged: 0.5.0 + VersionChanged: 0.6.1 + Exclude: + - db/migrate/*.rb Sorbet/ForbidUntypedStructProps: Description: >- @@ -92,6 +101,11 @@ Sorbet/KeywordArgumentOrdering: Enabled: true VersionAdded: 0.2.0 +Sorbet/OneAncestorPerLine: + Description: 'Enforces one ancestor per call to requires_ancestor' + Enabled: false + VersionAdded: '0.6.0' + Sorbet/ParametersOrderingInSignature: Description: 'Enforces same parameter order between a method and its signature.' Enabled: true @@ -107,6 +121,13 @@ Sorbet/SignatureBuildOrder: Enabled: true VersionAdded: 0.3.0 +Sorbet/SingleLineRbiClassModuleDefinitions: + Description: 'Empty class and module definitions in RBI must be on a single line.' + Enabled: false + VersionAdded: '0.6.0' + Include: + - "**/*.rbi" + Sorbet/StrictSigil: Description: 'All files must be at least at strictness `strict`.' Enabled: false diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop-sorbet.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop-sorbet.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop-sorbet.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop-sorbet.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/constants_from_strings.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/constants_from_strings.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/constants_from_strings.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/constants_from_strings.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_extend_t_sig_helpers_in_shims.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_extend_t_sig_helpers_in_shims.rb new file mode 100644 index 0000000000..2a281fc868 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_extend_t_sig_helpers_in_shims.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Sorbet + # This cop ensures RBI shims do not include a call to extend T::Sig + # or to extend T::Helpers + # + # @example + # + # # bad + # module SomeModule + # extend T::Sig + # extend T::Helpers + # + # sig { returns(String) } + # def foo; end + # end + # + # # good + # module SomeModule + # sig { returns(String) } + # def foo; end + # end + class ForbidExtendTSigHelpersInShims < RuboCop::Cop::Cop + include RangeHelp + + MSG = 'Extending T::Sig or T::Helpers in a shim is unnecessary' + RESTRICT_ON_SEND = [:extend] + + def_node_matcher :extend_t_sig?, <<~PATTERN + (send nil? :extend (const (const nil? :T) :Sig)) + PATTERN + + def_node_matcher :extend_t_helpers?, <<~PATTERN + (send nil? :extend (const (const nil? :T) :Helpers)) + PATTERN + + def autocorrect(node) + -> (corrector) do + corrector.remove( + range_by_whole_lines(node.source_range, include_final_newline: true) + ) + end + end + + def on_send(node) + add_offense(node) if extend_t_helpers?(node) || extend_t_sig?(node) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb new file mode 100644 index 0000000000..cb4d1abc49 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb @@ -0,0 +1,75 @@ +# encoding: utf-8 +# frozen_string_literal: true + +require 'rubocop' + +module RuboCop + module Cop + module Sorbet + # This cop ensures one ancestor per requires_ancestor line + # rather than chaining them as a comma-separated list. + # + # @example + # + # # bad + # module SomeModule + # requires_ancestor Kernel, Minitest::Assertions + # end + # + # # good + # module SomeModule + # requires_ancestor Kernel + # requires_ancestor Minitest::Assertions + # end + class OneAncestorPerLine < RuboCop::Cop::Cop + MSG = 'Cannot require more than one ancestor per line' + + def_node_search :requires_ancestors, <<~PATTERN + (send nil? :requires_ancestor ...) + PATTERN + + def_node_matcher :more_than_one_ancestor, <<~PATTERN + (send nil? :requires_ancestor const const+) + PATTERN + + def_node_search :abstract?, <<~PATTERN + (send nil? :abstract!) + PATTERN + + def on_module(node) + return unless node.body + return unless requires_ancestors(node) + process_node(node) + end + + def on_class(node) + return unless abstract?(node) + return unless requires_ancestors(node) + process_node(node) + end + + def autocorrect(node) + -> (corrector) do + ra_call = node.parent + split_ra_calls = ra_call.source.gsub(/,\s+/, new_ra_line(ra_call.loc.column)) + corrector.replace(ra_call, split_ra_calls) + end + end + + private + + def process_node(node) + requires_ancestors(node).each do |ra| + add_offense(ra.child_nodes[1]) if more_than_one_ancestor(ra) + end + end + + def new_ra_line(indent_count) + indents = " " * indent_count + indented_ra_call = "#{indents}requires_ancestor " + "\n#{indented_ra_call}" + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/false_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/false_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/false_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/false_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/has_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/has_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/has_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/has_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/true_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/true_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/true_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/true_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb similarity index 85% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb index 92e1f73642..16c915df2c 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb @@ -27,6 +27,11 @@ module RuboCop # * `ParameterTypePlaceholder`: placeholders used for parameter types (default: 'T.untyped') # * `ReturnTypePlaceholder`: placeholders used for return types (default: 'T.untyped') class EnforceSignatures < SignatureCop + def initialize(config = nil, options = nil) + super(config, options) + @last_sig_for_scope = {} + end + def_node_matcher(:accessor?, <<-PATTERN) (send nil? {:attr_reader :attr_writer :attr_accessor} ...) PATTERN @@ -40,8 +45,11 @@ module RuboCop end def on_send(node) - return unless accessor?(node) - check_node(node) + check_node(node) if accessor?(node) + end + + def on_block(node) + @last_sig_for_scope[scope(node)] = node if signature?(node) end def autocorrect(node) @@ -63,22 +71,23 @@ module RuboCop end end + def scope(node) + return nil unless node.parent + return node.parent if [:begin, :block, :class, :module].include?(node.parent.type) + scope(node.parent) + end + private def check_node(node) - prev = previous_node(node) - unless signature?(prev) + scope = self.scope(node) + unless @last_sig_for_scope[scope] add_offense( node, message: "Each method is required to have a signature." ) end - end - - def previous_node(node) - parent = node.parent - return nil unless parent - parent.children[node.sibling_index - 1] + @last_sig_for_scope[scope] = nil end def param_type_placeholder diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb similarity index 68% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb index 245cf8fbf3..dafc757e3d 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb @@ -55,7 +55,7 @@ module RuboCop return nil unless can_autocorrect? lambda do |corrector| - tree = call_chain(node_with_index_sends(node)) + tree = call_chain(node_reparsed_with_modern_features(node)) .sort_by { |call| ORDER[call.method_name] } .reduce(nil) do |receiver, caller| caller.updated(nil, [receiver] + caller.children.drop(1)) @@ -68,16 +68,25 @@ module RuboCop end end + # Create a subclass of AST Builder that has modern features turned on + class ModernBuilder < RuboCop::AST::Builder + modernize + end + private_constant :ModernBuilder + private - def node_with_index_sends(node) - # This is really dirty hack to reparse the current node with index send - # emitting enabled, which is necessary to unparse them back as index accessors. - emit_index_value = RuboCop::AST::Builder.emit_index - RuboCop::AST::Builder.emit_index = true - RuboCop::AST::ProcessedSource.new(node.source, target_ruby_version, processed_source.path).ast - ensure - RuboCop::AST::Builder.emit_index = emit_index_value + # This method exists to reparse the current node with modern features enabled. + # Modern features include "index send" emitting, which is necessary to unparse + # "index sends" (i.e. `[]` calls) back to index accessors (i.e. as `foo[bar]``). + # Otherwise, we would get the unparsed node as `foo.[](bar)`. + def node_reparsed_with_modern_features(node) + # Create a new parser with a modern builder class instance + parser = Parser::CurrentRuby.new(ModernBuilder.new) + # Create a new source buffer with the node source + buffer = Parser::Source::Buffer.new(processed_source.path, source: node.source) + # Re-parse the buffer + parser.parse(buffer) end def can_autocorrect? diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/signature_cop.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/signature_cop.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet/signatures/signature_cop.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/signatures/signature_cop.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/single_line_rbi_class_module_definitions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/single_line_rbi_class_module_definitions.rb new file mode 100644 index 0000000000..712e33844b --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet/single_line_rbi_class_module_definitions.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Sorbet + # This cop ensures empty class/module definitions in RBI files are + # done on a single line rather than being split across multiple lines. + # + # @example + # + # # bad + # module SomeModule + # end + # + # # good + # module SomeModule; end + class SingleLineRbiClassModuleDefinitions < RuboCop::Cop::Cop + MSG = 'Empty class/module definitions in RBI files should be on a single line.' + + def on_module(node) + process_node(node) + end + + def on_class(node) + process_node(node) + end + + def autocorrect(node) + -> (corrector) { corrector.replace(node, convert_newlines(node.source)) } + end + + protected + + def convert_newlines(source) + source.sub(/[\r\n]+\s*[\r\n]*/, "; ") + end + + def process_node(node) + return if node.body + return if node.single_line? + add_offense(node) + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet_cops.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet_cops.rb similarity index 85% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet_cops.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet_cops.rb index b61037489f..ae9006a095 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/cop/sorbet_cops.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/cop/sorbet_cops.rb @@ -1,9 +1,12 @@ # frozen_string_literal: true require_relative 'sorbet/binding_constants_without_type_alias' require_relative 'sorbet/constants_from_strings' +require_relative 'sorbet/forbid_extend_t_sig_helpers_in_shims' require_relative 'sorbet/forbid_superclass_const_literal' require_relative 'sorbet/forbid_include_const_literal' require_relative 'sorbet/forbid_untyped_struct_props' +require_relative 'sorbet/single_line_rbi_class_module_definitions' +require_relative 'sorbet/one_ancestor_per_line' require_relative 'sorbet/signatures/allow_incompatible_override' require_relative 'sorbet/signatures/checked_true_in_signature' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet/inject.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet/inject.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet/inject.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet/inject.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet/version.rb similarity index 76% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet/version.rb index ea49b569f3..95e81d1189 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.5.1/lib/rubocop/sorbet/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubocop-sorbet-0.6.1/lib/rubocop/sorbet/version.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true module RuboCop module Sorbet - VERSION = "0.5.1" + VERSION = "0.6.1" end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/warning-1.2.0/lib/warning.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/warning-1.2.0/lib/warning.rb new file mode 100644 index 0000000000..7fac4f5fcf --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/warning-1.2.0/lib/warning.rb @@ -0,0 +1,257 @@ +require 'monitor' + +module Warning + module Processor + # Map of symbols to regexps for warning messages to ignore. + IGNORE_MAP = { + ambiguous_slash: /: warning: ambiguous first argument; put parentheses or a space even after `\/' operator\n\z|: warning: ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `\/' operator\n\z/, + arg_prefix: /: warning: `[&\*]' interpreted as argument prefix\n\z/, + bignum: /: warning: constant ::Bignum is deprecated\n\z/, + fixnum: /: warning: constant ::Fixnum is deprecated\n\z/, + method_redefined: /: warning: method redefined; discarding old .+\n\z|: warning: previous definition of .+ was here\n\z/, + missing_gvar: /: warning: global variable `\$.+' not initialized\n\z/, + missing_ivar: /: warning: instance variable @.+ not initialized\n\z/, + not_reached: /: warning: statement not reached\n\z/, + shadow: /: warning: shadowing outer local variable - \w+\n\z/, + unused_var: /: warning: assigned but unused variable - \w+\n\z/, + useless_operator: /: warning: possibly useless use of [>method /regexp/ + # :bignum :: Ignore warnings when referencing the ::Bignum constant. + # :fixnum :: Ignore warnings when referencing the ::Fixnum constant. + # :keyword_separation :: Ignore warnings related to keyword argument separation. + # :method_redefined :: Ignore warnings when defining a method in a class/module where a + # method of the same name was already defined in that class/module. + # :missing_gvar :: Ignore warnings for accesses to global variables + # that have not yet been initialized + # :missing_ivar :: Ignore warnings for accesses to instance variables + # that have not yet been initialized + # :not_reached :: Ignore statement not reached warnings. + # :safe :: Ignore warnings related to $SAFE and related C-API functions. + # :shadow :: Ignore warnings related to shadowing outer local variables. + # :taint :: Ignore warnings related to taint and related methods and C-API functions. + # :unused_var :: Ignore warnings for unused variables. + # :useless_operator :: Ignore warnings when using operators such as == and > when the + # result is not used. + # :void_context :: Ignore warnings for :: to reference constants when the result is not + # used (often used to trigger autoload). + # + # Examples: + # + # # Ignore all uninitialized instance variable warnings + # Warning.ignore(/instance variable @\w+ not initialized/) + # + # # Ignore all uninitialized instance variable warnings in current file + # Warning.ignore(/instance variable @\w+ not initialized/, __FILE__) + # + # # Ignore all uninitialized instance variable warnings in current file + # Warning.ignore(:missing_ivar, __FILE__) + # + # # Ignore all uninitialized instance variable and method redefined warnings in current file + # Warning.ignore([:missing_ivar, :method_redefined], __FILE__) + def ignore(regexp, path='') + unless regexp = convert_regexp(regexp) + raise TypeError, "first argument to Warning.ignore should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}" + end + + synchronize do + @ignore << [path, regexp] + end + nil + end + + # Handle all warnings starting with the given path, instead of + # the default behavior of printing them to $stderr. Examples: + # + # # Write warning to LOGGER at level warning + # Warning.process do |warning| + # LOGGER.warning(warning) + # end + # + # # Write warnings in the current file to LOGGER at level error level + # Warning.process(__FILE__) do |warning| + # LOGGER.error(warning) + # end + # + # The block can return one of the following symbols: + # + # :default :: Take the default action (call super, printing to $stderr). + # :backtrace :: Take the default action (call super, printing to $stderr), + # and also print the backtrace. + # :raise :: Raise a RuntimeError with the warning as the message. + # + # If the block returns anything else, it is assumed the block completely handled + # the warning and takes no other action. + # + # Instead of passing a block, you can pass a hash of actions to take for specific + # warnings, using regexp as keys and a callable objects as values: + # + # Warning.process(__FILE__, + # /instance variable @\w+ not initialized/ => proc do |warning| + # LOGGER.warning(warning) + # end, + # /global variable `\$\w+' not initialized/ => proc do |warning| + # LOGGER.error(warning) + # end + # ) + # + # Instead of passing a regexp as a key, you can pass a symbol that is recognized + # by Warning.ignore. Instead of passing a callable object as a value, you can + # pass a symbol, which will be treated as a callable object that returns that symbol: + # + # Warning.process(__FILE__, :missing_ivar=>:backtrace, :keyword_separation=>:raise) + def process(path='', actions=nil, &block) + if block + if actions + raise ArgumentError, "cannot pass both actions and block to Warning.process" + end + elsif actions + block = {} + actions.each do |regexp, value| + unless regexp = convert_regexp(regexp) + raise TypeError, "action provided to Warning.process should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}" + end + + block[regexp] = ACTION_PROC_MAP[value] || value + end + else + raise ArgumentError, "must pass either actions or block to Warning.process" + end + + synchronize do + @process << [path, block] + @process.sort_by!(&:first) + @process.reverse! + end + nil + end + + + if RUBY_VERSION >= '3.0' + method_args = ', category: nil' + super_ = "category ? super : super(str)" + else + super_ = "super" + end + + class_eval(<<-END, __FILE__, __LINE__+1) + def warn(str#{method_args}) + synchronize{@ignore.dup}.each do |path, regexp| + if str.start_with?(path) && str =~ regexp + return + end + end + + if @dedup + if synchronize{@dedup[str]} + return + end + + synchronize{@dedup[str] = true} + end + + action = catch(:action) do + synchronize{@process.dup}.each do |path, block| + if str.start_with?(path) + if block.is_a?(Hash) + block.each do |regexp, blk| + if str =~ regexp + throw :action, blk.call(str) + end + end + else + throw :action, block.call(str) + end + end + end + + :default + end + + case action + when :default + #{super_} + when :backtrace + #{super_} + $stderr.puts caller + when :raise + raise str + else + # nothing + end + + nil + end + END + + private + + # Convert the given Regexp, Symbol, or Array of Symbols into a Regexp. + def convert_regexp(regexp) + case regexp + when Regexp + regexp + when Symbol + IGNORE_MAP.fetch(regexp) + when Array + Regexp.union(regexp.map{|re| IGNORE_MAP.fetch(re)}) + else + # nothing + end + end + + def synchronize(&block) + @monitor.synchronize(&block) + end + end + + @ignore = [] + @process = [] + @dedup = false + @monitor = Monitor.new + + extend Processor +end diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index 7eb556a3bc..97de346cc0 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -115,7 +115,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when NullToken @@ -158,7 +158,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when StringToken @@ -184,7 +184,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when NumericToken @@ -216,7 +216,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when AlphaToken @@ -235,7 +235,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when BetaToken @@ -256,7 +256,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when PreToken @@ -277,7 +277,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when RCToken @@ -298,7 +298,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when PatchToken @@ -317,7 +317,7 @@ class Version sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) - return unless other = Token.from(other) + return unless (other = Token.from(other)) case other when PostToken @@ -589,15 +589,15 @@ class Version end # @api public - sig { returns(Version) } + sig { returns(T.self_type) } def major_minor - Version.new([major, minor].compact.join(".")) + self.class.new([major, minor].compact.join(".")) end # @api public - sig { returns(Version) } + sig { returns(T.self_type) } def major_minor_patch - Version.new([major, minor, patch].compact.join(".")) + self.class.new([major, minor, patch].compact.join(".")) end sig { returns(T::Boolean) } diff --git a/Library/Homebrew/warnings.rb b/Library/Homebrew/warnings.rb new file mode 100644 index 0000000000..f0a3ed116f --- /dev/null +++ b/Library/Homebrew/warnings.rb @@ -0,0 +1,36 @@ +# typed: true +# frozen_string_literal: true + +require "warning" + +# Helper module for handling warnings. +# +# @api private +module Warnings + module_function + + COMMON_WARNINGS = { + parser_syntax: [ + %r{warning: parser/current is loading parser/ruby\d+, which recognizes}, + /warning: \d+\.\d+\.\d+-compliant syntax, but you are running \d+\.\d+\.\d+\./, + %r{warning: please see https://github\.com/whitequark/parser#compatibility-with-ruby-mri\.}, + ], + }.freeze + + def ignore(*warnings) + warnings.map! do |warning| + next warning if !warning.is_a?(Symbol) || !COMMON_WARNINGS.key?(warning) + + COMMON_WARNINGS[warning] + end + + warnings.flatten.each do |warning| + Warning.ignore warning + end + return unless block_given? + + result = yield + Warning.clear + result + end +end diff --git a/Library/Homebrew/warnings.rbi b/Library/Homebrew/warnings.rbi new file mode 100644 index 0000000000..5d83b4cc35 --- /dev/null +++ b/Library/Homebrew/warnings.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module Warnings + include Kernel +end diff --git a/Library/README.md b/Library/README.md index 1b39771725..17b76012f8 100644 --- a/Library/README.md +++ b/Library/README.md @@ -1,3 +1,3 @@ # Library -This directory contains all the code run by the official `brew` and `brew cask` commands in `Homebrew` and all formulae (package descriptions) in taps (repositories containing formulae) in `Taps` subdirectories. +This directory contains all the code run by the official `brew` command in `Homebrew` and all formulae (package descriptions) in taps (repositories containing formulae) in `Taps` subdirectories. diff --git a/README.md b/README.md index 0490277333..1a49aa1a8c 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,21 @@ # Homebrew + [![GitHub release](https://img.shields.io/github/release/Homebrew/brew.svg)](https://github.com/Homebrew/brew/releases) Features, usage and installation instructions are [summarised on the homepage](https://brew.sh). Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained here](https://docs.brew.sh/Formula-Cookbook#homebrew-terminology). ## What Packages Are Available? + 1. Type `brew search` for a list. 2. Or visit [formulae.brew.sh](https://formulae.brew.sh) to browse packages online. 3. Or use `brew search --desc ` to browse packages from the command line. ## More Documentation + `brew help`, `man brew` or check [our documentation](https://docs.brew.sh/). ## Troubleshooting + First, please run `brew update` and `brew doctor`. Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting). @@ -19,6 +23,7 @@ Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshootin **If you don't read these it will take us far longer to help you with your problem.** ## Contributing + We'd love you to contribute to Homebrew. First, please read our [Contribution Guide](CONTRIBUTING.md) and [Code of Conduct](https://github.com/Homebrew/.github/blob/HEAD/CODE_OF_CONDUCT.md#code-of-conduct). We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour. @@ -30,6 +35,7 @@ Alternatively, for something more substantial, check out one of the issues label Good luck! ## Donations + Homebrew is a non-profit project run entirely by unpaid volunteers. We need your funds to pay for software, hardware and hosting around continuous integration and future improvements to the project. Every donation will be spent on making Homebrew better for our users. Please consider a regular donation through [GitHub Sponsors](https://github.com/sponsors/Homebrew) or [Patreon](https://www.patreon.com/homebrew). @@ -47,30 +53,35 @@ Alternatively, if you'd rather make a one-off payment: Homebrew is a member of the [Software Freedom Conservancy](https://sfconservancy.org) which provides us with an ability to receive tax-deductible, Homebrew earmarked donations (and [many other services](https://sfconservancy.org/members/services/)). Software Freedom Conservancy, Inc. is a 501(c)(3) organization incorporated in New York, and donations made to it are fully tax-deductible to the extent permitted by law. ## Security + Please report security issues to our [HackerOne](https://hackerone.com/homebrew/). ## Who We Are + Homebrew's [Project Leader](https://docs.brew.sh/Homebrew-Governance#6-project-leader) is [Mike McQuaid](https://github.com/MikeMcQuaid). -Homebrew's [Project Leadership Committee](https://docs.brew.sh/Homebrew-Governance#4-project-leadership-committee) is [Jonathan Chang](https://github.com/jonchang), [Markus Reiter](https://github.com/reitermarkus), [Misty De Meo](https://github.com/mistydemeo), [Sean Molenaar](https://github.com/SMillerDev) and [Shaun Jackman](https://github.com/sjackman). +Homebrew's [Project Leadership Committee](https://docs.brew.sh/Homebrew-Governance#4-project-leadership-committee) is [Issy Long](https://github.com/issyl0), [Jonathan Chang](https://github.com/jonchang), [Markus Reiter](https://github.com/reitermarkus), [Misty De Meo](https://github.com/mistydemeo) and [Sean Molenaar](https://github.com/SMillerDev). -Homebrew's [Technical Steering Committee](https://docs.brew.sh/Homebrew-Governance#7-technical-steering-committee) is [FX Coudert](https://github.com/fxcoudert), [Markus Reiter](https://github.com/reitermarkus), [Michka Popoff](https://github.com/iMichka), [Mike McQuaid](https://github.com/MikeMcQuaid) and [Misty De Meo](https://github.com/mistydemeo). +Homebrew's [Technical Steering Committee](https://docs.brew.sh/Homebrew-Governance#7-technical-steering-committee) is [Bo Anderson](https://github.com/Bo98), [FX Coudert](https://github.com/fxcoudert), [Michka Popoff](https://github.com/iMichka), [Mike McQuaid](https://github.com/MikeMcQuaid) and [Rylan Polster](https://github.com/Rylan12). Homebrew's Linux maintainers are [Daniel Nachun](https://github.com/danielnachun), [Dawid Dziurla](https://github.com/dawidd6), [Issy Long](https://github.com/issyl0), [Jonathan Chang](https://github.com/jonchang), [Michka Popoff](https://github.com/iMichka) and [Shaun Jackman](https://github.com/sjackman). -Homebrew's other current maintainers are [Alexander Bayandin](https://github.com/bayandin), [Bo Anderson](https://github.com/Bo98), [Caleb Xu](https://github.com/alebcay), [Carlo Cabrera](https://github.com/carlocab), [Claudia Pellegrino](https://github.com/claui), [Dustin Rodrigues](https://github.com/dtrodrigues), [Eric Knibbe](https://github.com/EricFromCanada), [Maxim Belkin](https://github.com/maxim-belkin), [Miccal Matthews](https://github.com/miccal), [Nanda H Krishna](https://github.com/nandahkrishna), [Randall](https://github.com/ran-dall), [Rylan Polster](https://github.com/Rylan12), [Sam Ford](https://github.com/samford), [Seeker](https://github.com/SeekingMeaning), [Steve Peters](https://github.com/scpeters), [Thierry Moisan](https://github.com/Moisan), [Tom Schoonjans](https://github.com/tschoonj), [Vítor Galvão](https://github.com/vitorgalvao) and [rui](https://github.com/chenrui333). +Homebrew's other current maintainers are [Alexander Bayandin](https://github.com/bayandin), [Caleb Xu](https://github.com/alebcay), [Carlo Cabrera](https://github.com/carlocab), [Claudia Pellegrino](https://github.com/claui), [Dustin Rodrigues](https://github.com/dtrodrigues), [Eric Knibbe](https://github.com/EricFromCanada), [Maxim Belkin](https://github.com/maxim-belkin), [Miccal Matthews](https://github.com/miccal), [Nanda H Krishna](https://github.com/nandahkrishna), [Randall](https://github.com/ran-dall), [Sam Ford](https://github.com/samford), [Seeker](https://github.com/SeekingMeaning), [Steve Peters](https://github.com/scpeters), [Thierry Moisan](https://github.com/Moisan), [Tom Schoonjans](https://github.com/tschoonj), [Vítor Galvão](https://github.com/vitorgalvao) and [rui](https://github.com/chenrui333). Former maintainers with significant contributions include [Jan Viljanen](https://github.com/javian), [JCount](https://github.com/jcount), [commitay](https://github.com/commitay), [Dominyk Tiller](https://github.com/DomT4), [Tim Smith](https://github.com/tdsmith), [Baptiste Fontaine](https://github.com/bfontaine), [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Brett Koonce](https://github.com/asparagui), [Charlie Sharpsteen](https://github.com/Sharpie), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv), [Andrew Janke](https://github.com/apjanke), [Alex Dunn](https://github.com/dunn), [neutric](https://github.com/neutric), [Tomasz Pajor](https://github.com/nijikon), [Uladzislau Shablinski](https://github.com/vladshablinsky), [Alyssa Ross](https://github.com/alyssais), [ilovezfs](https://github.com/ilovezfs), [Chongyu Zhu](https://github.com/lembacon) and Homebrew's creator: [Max Howell](https://github.com/mxcl). ## Community + - [Homebrew/discussions (forum)](https://github.com/homebrew/discussions/discussions) - [@MacHomebrew (Twitter)](https://twitter.com/MacHomebrew) ## License + Code is under the [BSD 2-clause "Simplified" License](LICENSE.txt). Documentation is under the [Creative Commons Attribution license](https://creativecommons.org/licenses/by/4.0/). ## Sponsors + Our macOS continuous integration infrastructure is hosted by [MacStadium's Orka](https://www.macstadium.com/customers/homebrew). [![Powered by MacStadium](https://cloud.githubusercontent.com/assets/125011/22776032/097557ac-eea6-11e6-8ba8-eff22dfd58f1.png)](https://www.macstadium.com) @@ -87,4 +98,6 @@ Homebrew is a member of the [Software Freedom Conservancy](https://sfconservancy [![Software Freedom Conservancy](https://sfconservancy.org/img/conservancy_64x64.png)](https://sfconservancy.org) -Homebrew is generously supported by [Randy Reddig](https://github.com/ydnar) and 439 other users via [GitHub Sponsors](https://github.com/sponsors/Homebrew). +Homebrew is generously supported by [Substack](https://github.com/substackinc), [GitHub](https://github.com/githubsponsors), [Randy Reddig](https://github.com/ydnar), [embark-studios](https://github.com/embark-studios), [Realist.ai](https://github.com/RealistAI) and many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew). + +[![Substack](https://github.com/substackinc.png?size=64)](https://github.com/substackinc)[![GitHub](https://github.com/githubsponsors.png?size=64)](https://github.com/githubsponsors) diff --git a/bin/brew b/bin/brew index d93497ef3e..404f74a691 100755 --- a/bin/brew +++ b/bin/brew @@ -75,6 +75,11 @@ do export "$VAR_NEW"="${!VAR}" done +export HOMEBREW_BREW_FILE +export HOMEBREW_PREFIX +export HOMEBREW_REPOSITORY +export HOMEBREW_LIBRARY + # Use VISUAL if HOMEBREW_EDITOR and EDITOR are unset. if [[ -z "$HOMEBREW_EDITOR" && -n "$VISUAL" ]] then @@ -108,6 +113,8 @@ then exec /usr/bin/env -i "${FILTERED_ENV[@]}" /bin/bash "$HOMEBREW_LIBRARY/Homebrew/brew.sh" "$@" else + echo "Warning: HOMEBREW_NO_ENV_FILTERING is undocumented, deprecated and will be removed in a future Homebrew release (because it breaks many things)!" >&2 + # Don't need shellcheck to follow this `source`. # shellcheck disable=SC1090 source "$HOMEBREW_LIBRARY/Homebrew/brew.sh" diff --git a/completions/bash/brew b/completions/bash/brew index abd7782871..66675878ef 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -245,21 +245,6 @@ _brew___repository() { __brew_complete_tapped } -_brew___version() { - local cur="${COMP_WORDS[COMP_CWORD]}" - case "$cur" in - -*) - __brewcomp " - --debug - --help - --quiet - --verbose - " - return - ;; - esac -} - _brew__s() { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in @@ -287,21 +272,6 @@ _brew__s() { esac } -_brew__v() { - local cur="${COMP_WORDS[COMP_CWORD]}" - case "$cur" in - -*) - __brewcomp " - --debug - --help - --quiet - --verbose - " - return - ;; - esac -} - _brew_abv() { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in @@ -427,9 +397,13 @@ _brew_bump() { case "$cur" in -*) __brewcomp " + --cask --debug + --formula + --full-name --help --limit + --no-pull-requests --quiet --verbose " @@ -437,6 +411,7 @@ _brew_bump() { ;; esac __brew_complete_formulae + __brew_complete_casks } _brew_bump_cask_pr() { @@ -734,6 +709,7 @@ _brew_dispatch_build_bottle() { --debug --help --issue + --linux --macos --quiet --tap @@ -1288,7 +1264,7 @@ _brew_man() { -*) __brewcomp " --debug - --fail-if-changed + --fail-if-not-changed --help --quiet --verbose @@ -1471,6 +1447,7 @@ _brew_pr_pull() { case "$cur" in -*) __brewcomp " + --archive-item --artifact --autosquash --bintray-mirror @@ -1503,9 +1480,11 @@ _brew_pr_upload() { case "$cur" in -*) __brewcomp " + --archive-item --bintray-org --debug --dry-run + --github-org --help --keep-old --no-commit @@ -2310,9 +2289,7 @@ _brew() { --prefix) _brew___prefix ;; --repo) _brew___repo ;; --repository) _brew___repository ;; - --version) _brew___version ;; -S) _brew__s ;; - -v) _brew__v ;; abv) _brew_abv ;; analytics) _brew_analytics ;; audit) _brew_audit ;; diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index a2c251d9b9..0da4d4dba1 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -271,13 +271,6 @@ __fish_brew_complete_arg '--repository' -l verbose -d 'Make some output more ver __fish_brew_complete_arg '--repository' -a '(__fish_brew_suggest_taps_installed)' -__fish_brew_complete_cmd '--version' 'Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask (if tapped) to standard output' -__fish_brew_complete_arg '--version' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg '--version' -l help -d 'Show this message' -__fish_brew_complete_arg '--version' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg '--version' -l verbose -d 'Make some output more verbose' - - __fish_brew_complete_cmd '-S' 'Perform a substring search of cask tokens and formula names for text' __fish_brew_complete_arg '-S' -l cask -d 'Without text, list all locally available casks (including tapped ones, no online search is performed). With text, search online and locally for casks' __fish_brew_complete_arg '-S' -l closed -d 'Search for only closed GitHub pull requests' @@ -297,13 +290,6 @@ __fish_brew_complete_arg '-S' -l ubuntu -d 'Search for text in the given package __fish_brew_complete_arg '-S' -l verbose -d 'Make some output more verbose' -__fish_brew_complete_cmd '-v' 'Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask (if tapped) to standard output' -__fish_brew_complete_arg '-v' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg '-v' -l help -d 'Show this message' -__fish_brew_complete_arg '-v' -l quiet -d 'Make some output more quiet' -__fish_brew_complete_arg '-v' -l verbose -d 'Make some output more verbose' - - __fish_brew_complete_cmd 'abv' 'Display brief statistics for your Homebrew installation' __fish_brew_complete_arg 'abv' -l all -d 'Print JSON of all available formulae' __fish_brew_complete_arg 'abv' -l analytics -d 'List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)' @@ -387,12 +373,17 @@ __fish_brew_complete_arg 'bottle' -a '(__fish_brew_suggest_formulae_installed)' __fish_brew_complete_cmd 'bump' 'Display out-of-date brew formulae and the latest version available' +__fish_brew_complete_arg 'bump' -l cask -d 'Check only casks' __fish_brew_complete_arg 'bump' -l debug -d 'Display any debugging information' +__fish_brew_complete_arg 'bump' -l formula -d 'Check only formulae' +__fish_brew_complete_arg 'bump' -l full-name -d 'Print formulae/casks with fully-qualified names' __fish_brew_complete_arg 'bump' -l help -d 'Show this message' __fish_brew_complete_arg 'bump' -l limit -d 'Limit number of package results returned' +__fish_brew_complete_arg 'bump' -l no-pull-requests -d 'Do not retrieve pull requests from GitHub' __fish_brew_complete_arg 'bump' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'bump' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'bump' -a '(__fish_brew_suggest_formulae_all)' +__fish_brew_complete_arg 'bump' -a '(__fish_brew_suggest_casks_all)' __fish_brew_complete_cmd 'bump-cask-pr' 'Create a pull request to update cask with a new version' @@ -584,6 +575,7 @@ __fish_brew_complete_cmd 'dispatch-build-bottle' 'Build bottles for these formul __fish_brew_complete_arg 'dispatch-build-bottle' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'dispatch-build-bottle' -l help -d 'Show this message' __fish_brew_complete_arg 'dispatch-build-bottle' -l issue -d 'If specified, post a comment to this issue number if the job fails' +__fish_brew_complete_arg 'dispatch-build-bottle' -l linux -d 'Dispatch bottle for Linux (using GitHub runners)' __fish_brew_complete_arg 'dispatch-build-bottle' -l macos -d 'Version of macOS the bottle should be built for' __fish_brew_complete_arg 'dispatch-build-bottle' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'dispatch-build-bottle' -l tap -d 'Target tap repository (default: `homebrew/core`)' @@ -946,7 +938,7 @@ __fish_brew_complete_arg 'ls' -a '(__fish_brew_suggest_casks_installed)' __fish_brew_complete_cmd 'man' 'Generate Homebrew\'s manpages' __fish_brew_complete_arg 'man' -l debug -d 'Display any debugging information' -__fish_brew_complete_arg 'man' -l fail-if-changed -d 'Return a failing status code if changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)' +__fish_brew_complete_arg 'man' -l fail-if-not-changed -d 'Return a failing status code if no changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)' __fish_brew_complete_arg 'man' -l help -d 'Show this message' __fish_brew_complete_arg 'man' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'man' -l verbose -d 'Make some output more verbose' @@ -1049,6 +1041,7 @@ __fish_brew_complete_arg 'pr-publish' -l workflow -d 'Target workflow filename ( __fish_brew_complete_cmd 'pr-pull' 'Download and publish bottles, and apply the bottle commit from a pull request with artifacts generated by GitHub Actions' +__fish_brew_complete_arg 'pr-pull' -l archive-item -d 'Upload to the specified Internet Archive item (default: `homebrew`)' __fish_brew_complete_arg 'pr-pull' -l artifact -d 'Download artifacts with the specified name (default: `bottles`)' __fish_brew_complete_arg 'pr-pull' -l autosquash -d 'Automatically reformat and reword commits in the pull request to our preferred format' __fish_brew_complete_arg 'pr-pull' -l bintray-mirror -d 'Use the specified Bintray repository to automatically mirror stable URLs defined in the formulae (default: `mirror`)' @@ -1072,10 +1065,12 @@ __fish_brew_complete_arg 'pr-pull' -l warn-on-upload-failure -d 'Warn instead of __fish_brew_complete_arg 'pr-pull' -l workflows -d 'Retrieve artifacts from the specified workflow (default: `tests.yml`). Can be a comma-separated list to include multiple workflows' -__fish_brew_complete_cmd 'pr-upload' 'Apply the bottle commit and publish bottles to Bintray or GitHub Releases' +__fish_brew_complete_cmd 'pr-upload' 'Apply the bottle commit and publish bottles to a host' +__fish_brew_complete_arg 'pr-upload' -l archive-item -d 'Upload to the specified Internet Archive item (default: `homebrew`)' __fish_brew_complete_arg 'pr-upload' -l bintray-org -d 'Upload to the specified Bintray organisation (default: `homebrew`)' __fish_brew_complete_arg 'pr-upload' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'pr-upload' -l dry-run -d 'Print what would be done rather than doing it' +__fish_brew_complete_arg 'pr-upload' -l github-org -d 'Upload to the specified GitHub organisation\'s GitHub Packages (default: `homebrew`)' __fish_brew_complete_arg 'pr-upload' -l help -d 'Show this message' __fish_brew_complete_arg 'pr-upload' -l keep-old -d 'If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL' __fish_brew_complete_arg 'pr-upload' -l no-commit -d 'Do not generate a new commit before uploading' @@ -1225,7 +1220,7 @@ __fish_brew_complete_arg 'sh' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'sh' -l verbose -d 'Make some output more verbose' -__fish_brew_complete_cmd 'sponsors' 'Print a Markdown summary of Homebrew\'s GitHub Sponsors, suitable for pasting into a README' +__fish_brew_complete_cmd 'sponsors' 'Update the list of GitHub Sponsors in the `Homebrew/brew` README' __fish_brew_complete_arg 'sponsors' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'sponsors' -l help -d 'Show this message' __fish_brew_complete_arg 'sponsors' -l quiet -d 'Make some output more quiet' @@ -1273,7 +1268,7 @@ __fish_brew_complete_arg 'tap-info' -a '(__fish_brew_suggest_taps_installed)' __fish_brew_complete_cmd 'tap-new' 'Generate the template files for a new tap' -__fish_brew_complete_arg 'tap-new' -l branch -d 'Initialize Git repository with the specified branch name (default: `main`)' +__fish_brew_complete_arg 'tap-new' -l branch -d 'Initialize Git repository and setup GitHub Actions workflows with the specified branch name (default: `main`)' __fish_brew_complete_arg 'tap-new' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'tap-new' -l help -d 'Show this message' __fish_brew_complete_arg 'tap-new' -l no-git -d 'Don\'t initialize a Git repository for the tap' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 22c4e2e749..87d8287c37 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -185,7 +185,7 @@ __brew_internal_commands() { 'pr-automerge:Find pull requests that can be automatically merged using `brew pr-publish`' 'pr-publish:Publish bottles for a pull request with GitHub Actions' 'pr-pull:Download and publish bottles, and apply the bottle commit from a pull request with artifacts generated by GitHub Actions' - 'pr-upload:Apply the bottle commit and publish bottles to Bintray or GitHub Releases' + 'pr-upload:Apply the bottle commit and publish bottles to a host' 'prof:Run Homebrew with a Ruby profiler' 'readall:Import all items from the specified tap, or from all installed taps if none is provided' 'reinstall:Uninstall and then reinstall a formula or cask using the same options it was originally installed with, plus any appended options specific to a formula' @@ -196,7 +196,7 @@ __brew_internal_commands() { 'search:Perform a substring search of cask tokens and formula names for text' 'sh:Enter an interactive shell for Homebrew'\''s build environment' 'shellenv:Print export statements' - 'sponsors:Print a Markdown summary of Homebrew'\''s GitHub Sponsors, suitable for pasting into a README' + 'sponsors:Update the list of GitHub Sponsors in the `Homebrew/brew` README' 'style:Check formulae or files for conformance to Homebrew style guidelines' 'tap:Tap a formula repository' 'tap-info:Show detailed information about one or more taps' @@ -253,15 +253,17 @@ __brew_diagnostic_checks() { _brew___cache() { _arguments \ '(--force-bottle --cask)--build-from-source[Show the cache file used when building from source]' \ - '(--build-from-source --force-bottle --formula)--cask[Only show cache files for casks]' \ '--debug[Display any debugging information]' \ '(--build-from-source --cask)--force-bottle[Show the cache file used when pouring a bottle]' \ - '(--cask)--formula[Only show cache files for formulae]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Only show cache files for formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--build-from-source --force-bottle --formula)--cask[Only show cache files for casks]' \ + '*::cask:__brew_casks' } # brew --caskroom @@ -271,7 +273,8 @@ _brew___caskroom() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::cask:__brew_casks' + - cask \ + '*::cask:__brew_casks' } # brew --cellar @@ -281,7 +284,8 @@ _brew___cellar() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew --config @@ -302,7 +306,8 @@ _brew___env() { '--quiet[Make some output more quiet]' \ '--shell[Generate a list of environment variables for the specified shell, or `--shell=auto` to detect the current shell]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew --prefix @@ -314,7 +319,8 @@ _brew___prefix() { '--quiet[Make some output more quiet]' \ '(--installed)--unbrewed[List files in Homebrew'\''s prefix not installed by Homebrew]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew --repo @@ -324,7 +330,8 @@ _brew___repo() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew --repository @@ -334,16 +341,8 @@ _brew___repository() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' -} - -# brew --version -_brew___version() { - _arguments \ - '--debug[Display any debugging information]' \ - '--help[Show this message]' \ - '--quiet[Make some output more quiet]' \ - '--verbose[Make some output more verbose]' + - tap \ + '*::tap:__brew_any_tap' } # brew -S @@ -367,33 +366,26 @@ _brew__s() { '--verbose[Make some output more verbose]' } -# brew -v -_brew__v() { - _arguments \ - '--debug[Display any debugging information]' \ - '--help[Show this message]' \ - '--quiet[Make some output more quiet]' \ - '--verbose[Make some output more verbose]' -} - # brew abv _brew_abv() { _arguments \ '(--installed)--all[Print JSON of all available formulae]' \ '--analytics[List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)]' \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--category[Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`]' \ '--days[How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--github[Open the GitHub source page for formula in a browser. To view formula history locally: `brew log -p` formula]' \ '--help[Show this message]' \ '(--all)--installed[Print JSON of formulae that are currently installed]' \ '--json[Print a JSON representation. Currently the default value for version is `v1` for formula. For formula and cask use `v2`. See the docs for examples of using the JSON output: https://docs.brew.sh/Querying-Brew]' \ '--quiet[Make some output more quiet]' \ '--verbose[Show more verbose analytics data for formula]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew analytics @@ -403,7 +395,8 @@ _brew_analytics() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::subcommand:(state on off regenerate-uuid)' + - subcommand \ + '*::subcommand:(state on off regenerate-uuid)' } # brew audit @@ -411,14 +404,12 @@ _brew_audit() { _arguments \ '--appcast[Audit the appcast]' \ '--audit-debug[Enable debugging and profiling of audit methods]' \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '(--skip-style --only-cops --except-cops)--display-cop-names[Include the RuboCop cop name for each violation in the output]' \ '--display-filename[Prefix every line of output with the file or formula name being audited, to make output easy to grep]' \ '(--only)--except[Specify a comma-separated method list to skip running the methods named `audit_`method]' \ '(--only-cops --strict --only-cops --only --display-cop-names)--except-cops[Specify a comma-separated cops list to skip checking for violations of the listed RuboCop cops]' \ '--fix[Fix style violations automatically using RuboCop'\''s auto-correct feature]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--git[Run additional, slower style checks that navigate the Git repository]' \ '--help[Show this message]' \ '--new[Run various additional style checks to determine if a new formula or cask is eligible for Homebrew. This should be used when creating new formula and implies `--strict` and `--online`]' \ @@ -432,8 +423,12 @@ _brew_audit() { '--tap[Check the formulae within the given tap, specified as user`/`repo]' \ '--token-conflicts[Audit for token conflicts]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew autoremove @@ -462,19 +457,28 @@ _brew_bottle() { '--skip-relocation[Do not check if the bottle can be marked as relocatable]' \ '--verbose[Make some output more verbose]' \ '--write[Write changes to the formula file. A new commit will be generated unless `--no-commit` is passed]' \ - '::installed_formula:__brew_installed_formulae' \ - '::file:__brew_formulae_or_ruby_files' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' \ + - file \ + '*::file:__brew_formulae_or_ruby_files' } # brew bump _brew_bump() { _arguments \ '--debug[Display any debugging information]' \ + '--full-name[Print formulae/casks with fully-qualified names]' \ '--help[Show this message]' \ '--limit[Limit number of package results returned]' \ + '--no-pull-requests[Do not retrieve pull requests from GitHub]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '(--cask)--formula[Check only formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Check only casks]' \ + '*::cask:__brew_casks' } # brew bump-cask-pr @@ -497,7 +501,8 @@ _brew_bump_cask_pr() { '--verbose[Make some output more verbose]' \ '--version[Specify the new version for the cask]' \ '(--dry-run)--write[Make the expected file modifications without taking any Git actions]' \ - '::cask:__brew_casks' + - cask \ + '*::cask:__brew_casks' } # brew bump-formula-pr @@ -523,7 +528,8 @@ _brew_bump_formula_pr() { '--verbose[Make some output more verbose]' \ '--version[Use the specified version to override the value parsed from the URL or tag. Note that `--version=0` can be used to delete an existing version override from a formula if it has become redundant]' \ '(--dry-run)--write[Make the expected file modifications without taking any Git actions]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew bump-revision @@ -535,7 +541,8 @@ _brew_bump_revision() { '--message[Append message to the default commit message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew bump-unversioned-casks @@ -548,21 +555,25 @@ _brew_bump_unversioned_casks() { '--quiet[Make some output more quiet]' \ '--state-file[File for caching state]' \ '--verbose[Make some output more verbose]' \ - '::cask:__brew_casks' \ - '::tap:__brew_any_tap' + - cask \ + '*::cask:__brew_casks' \ + - tap \ + '*::tap:__brew_any_tap' } # brew cat _brew_cat() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew cleanup @@ -576,8 +587,10 @@ _brew_cleanup() { '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '-s[Scrub the cache, including downloads for even the latest versions. Note downloads for any installed formulae or casks will still not be deleted. If you want to delete those too: `rm -rf "$(brew --cache)"`]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '*::formula:__brew_formulae' \ + - cask \ + '*::cask:__brew_casks' } # brew command @@ -587,7 +600,8 @@ _brew_command() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::command:__brew_commands' + - command \ + '*::command:__brew_commands' } # brew commands @@ -607,7 +621,8 @@ _brew_completions() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::subcommand:(state link unlink)' + - subcommand \ + '*::subcommand:(state link unlink)' } # brew config @@ -652,10 +667,8 @@ _brew_deps() { '--1[Only show dependencies one level down, instead of recursing]' \ '(--installed)--all[List dependencies for all available formulae]' \ '--annotate[Mark any build, test, optional, or recommended dependencies as such in the output]' \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--for-each[Switch into the mode used by the `--all` option, but only list dependencies for each provided formula, one formula per line. This is used for debugging the `--installed`/`--all` display mode]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--full-name[List dependencies by their full name]' \ '--help[Show this message]' \ '--include-build[Include `:build` dependencies for formula]' \ @@ -669,8 +682,12 @@ _brew_deps() { '--union[Show the union of dependencies for multiple formula, instead of the intersection]' \ '--verbose[Make some output more verbose]' \ '-n[Sort dependencies in topological order]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew desc @@ -683,7 +700,8 @@ _brew_desc() { '--quiet[Make some output more quiet]' \ '(--name --description)--search[Search both names and descriptions for text. If text is flanked by slashes, it is interpreted as a regular expression]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew dispatch-build-bottle @@ -692,13 +710,15 @@ _brew_dispatch_build_bottle() { '--debug[Display any debugging information]' \ '--help[Show this message]' \ '--issue[If specified, post a comment to this issue number if the job fails]' \ - '--macos[Version of macOS the bottle should be built for]' \ + '(--macos)--linux[Dispatch bottle for Linux (using GitHub runners)]' \ + '(--linux)--macos[Version of macOS the bottle should be built for]' \ '--quiet[Make some output more quiet]' \ '--tap[Target tap repository (default: `homebrew/core`)]' \ '--upload[Upload built bottles to Bintray]' \ '--verbose[Make some output more verbose]' \ '--workflow[Dispatch specified workflow (default: `dispatch-build-bottle.yml`)]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew doctor @@ -710,7 +730,8 @@ _brew_doctor() { '--list-checks[List all audit methods, which can be run individually if provided as arguments]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::diagnostic_check:__brew_diagnostic_checks' + - diagnostic_check \ + '*::diagnostic_check:__brew_diagnostic_checks' } # brew dr @@ -722,20 +743,23 @@ _brew_dr() { '--list-checks[List all audit methods, which can be run individually if provided as arguments]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::diagnostic_check:__brew_diagnostic_checks' + - diagnostic_check \ + '*::diagnostic_check:__brew_diagnostic_checks' } # brew edit _brew_edit() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew environment @@ -747,7 +771,8 @@ _brew_environment() { '--quiet[Make some output more quiet]' \ '--shell[Generate a list of environment variables for the specified shell, or `--shell=auto` to detect the current shell]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew extract @@ -759,8 +784,10 @@ _brew_extract() { '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '--version[Extract the specified version of formula instead of the most recent]' \ - '::formula:__brew_formulae' \ - '::tap:__brew_any_tap' + - formula \ + '*::formula:__brew_formulae' \ + - tap \ + '*::tap:__brew_any_tap' } # brew fetch @@ -769,20 +796,22 @@ _brew_fetch() { '(--cask)--HEAD[Fetch HEAD version instead of stable version]' \ '(--build-from-source --force-bottle --cask)--build-bottle[Download source packages (for eventual bottling) rather than a bottle]' \ '(--build-bottle --force-bottle)--build-from-source[Download source packages rather than a bottle]' \ - '(--HEAD --deps --s --build-bottle --force-bottle --formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '(--cask)--deps[Also download dependencies for any listed formula]' \ '--force[Remove a previously cached version and re-fetch]' \ '(--build-from-source --build-bottle --cask)--force-bottle[Download a bottle if it exists for the current or newest version of macOS, even if it would not be used during installation]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--no-quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ '--quarantine[Disable/enable quarantining of downloads (default: enabled)]' \ '--quiet[Make some output more quiet]' \ '--retry[Retry if downloading fails or re-download if the checksum of a previously cached version no longer matches]' \ '--verbose[Do a verbose VCS checkout, if the URL represents a VCS. This is useful for seeing if an existing VCS cache has been updated]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--HEAD --deps --s --build-bottle --force-bottle --formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew formula @@ -792,7 +821,8 @@ _brew_formula() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew gist-logs @@ -805,33 +835,38 @@ _brew_gist_logs() { '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '--with-hostname[Include the hostname in the Gist]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew home _brew_home() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew homepage _brew_homepage() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew info @@ -839,19 +874,21 @@ _brew_info() { _arguments \ '(--installed)--all[Print JSON of all available formulae]' \ '--analytics[List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)]' \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--category[Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`]' \ '--days[How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--github[Open the GitHub source page for formula in a browser. To view formula history locally: `brew log -p` formula]' \ '--help[Show this message]' \ '(--all)--installed[Print JSON of formulae that are currently installed]' \ '--json[Print a JSON representation. Currently the default value for version is `v1` for formula. For formula and cask use `v2`. See the docs for examples of using the JSON output: https://docs.brew.sh/Querying-Brew]' \ '--quiet[Make some output more quiet]' \ '--verbose[Show more verbose analytics data for formula]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew instal @@ -864,7 +901,6 @@ _brew_instal() { '(--cask)--bottle-arch[Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on]' \ '(--cask --build-from-source --force-bottle)--build-bottle[Prepare the formula for eventual bottling during installation, skipping any post-install steps]' \ '(--cask --build-bottle --force-bottle)--build-from-source[Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available]' \ - '(--formulae --env --ignore-dependencies --only-dependencies --cc --build-from-source --force-bottle --include-test --HEAD --fetch-HEAD --keep-tmp --build-bottle --bottle-arch --display-times --interactive --git)--cask[Treat all named arguments as casks]' \ '(--cask)--cc[Attempt to compile using the specified compiler, which should be the name of the compiler'\''s executable, e.g. `gcc-7` for GCC 7. In order to use LLVM'\''s clang, specify `llvm_clang`. To use the Apple-provided clang, specify `clang`. This option will only accept compilers that are provided by Homebrew or bundled with macOS. Please do not file issues if you encounter errors while using this option]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ @@ -875,7 +911,6 @@ _brew_instal() { '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \ '(--cask --build-from-source --build-bottle)--force-bottle[Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation]' \ - '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ '(--cask)--git[Create a Git repository, useful for creating patches to the software]' \ '--help[Show this message]' \ '(--cask --only-dependencies)--ignore-dependencies[An unsupported Homebrew development flag to skip installing any dependencies of any kind. If the dependencies are not already present, the formula will have issues. If you'\''re not developing Homebrew, consider adjusting your PATH rather than using this flag]' \ @@ -900,8 +935,12 @@ _brew_instal() { '--verbose[Print the verification and postinstall steps]' \ '(--formula)--vst-plugindir[Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`)]' \ '(--formula)--vst3-plugindir[Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`)]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formulae --env --ignore-dependencies --only-dependencies --cc --build-from-source --force-bottle --include-test --HEAD --fetch-HEAD --keep-tmp --build-bottle --bottle-arch --display-times --interactive --git)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew install @@ -914,7 +953,6 @@ _brew_install() { '(--cask)--bottle-arch[Optimise bottles for the specified architecture rather than the oldest architecture supported by the version of macOS the bottles are built on]' \ '(--cask --build-from-source --force-bottle)--build-bottle[Prepare the formula for eventual bottling during installation, skipping any post-install steps]' \ '(--cask --build-bottle --force-bottle)--build-from-source[Compile formula from source even if a bottle is provided. Dependencies will still be installed from bottles if they are available]' \ - '(--formulae --env --ignore-dependencies --only-dependencies --cc --build-from-source --force-bottle --include-test --HEAD --fetch-HEAD --keep-tmp --build-bottle --bottle-arch --display-times --interactive --git)--cask[Treat all named arguments as casks]' \ '(--cask)--cc[Attempt to compile using the specified compiler, which should be the name of the compiler'\''s executable, e.g. `gcc-7` for GCC 7. In order to use LLVM'\''s clang, specify `llvm_clang`. To use the Apple-provided clang, specify `clang`. This option will only accept compilers that are provided by Homebrew or bundled with macOS. Please do not file issues if you encounter errors while using this option]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ @@ -925,7 +963,6 @@ _brew_install() { '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \ '(--cask --build-from-source --build-bottle)--force-bottle[Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation]' \ - '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ '(--cask)--git[Create a Git repository, useful for creating patches to the software]' \ '--help[Show this message]' \ '(--cask --only-dependencies)--ignore-dependencies[An unsupported Homebrew development flag to skip installing any dependencies of any kind. If the dependencies are not already present, the formula will have issues. If you'\''re not developing Homebrew, consider adjusting your PATH rather than using this flag]' \ @@ -950,8 +987,12 @@ _brew_install() { '--verbose[Print the verification and postinstall steps]' \ '(--formula)--vst-plugindir[Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`)]' \ '(--formula)--vst3-plugindir[Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`)]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formulae --env --ignore-dependencies --only-dependencies --cc --build-from-source --force-bottle --include-test --HEAD --fetch-HEAD --keep-tmp --build-bottle --bottle-arch --display-times --interactive --git)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew install-bundler-gems @@ -993,7 +1034,8 @@ _brew_link() { '--overwrite[Delete files that already exist in the prefix while linking]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew linkage @@ -1006,15 +1048,14 @@ _brew_linkage() { '--reverse[For every library that a keg references, print its dylib path followed by the binaries that link to it]' \ '--test[Show only missing libraries and exit with a non-zero status if any missing libraries are found]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew list _brew_list() { _arguments \ - '(--formula --multiple --unbrewed --pinned --l --r --t)--cask[List only casks, or treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask --unbrewed)--formula[List only formulae, or treat all named arguments as formulae]' \ '(--versions --unbrewed --pinned --l --r --t)--full-name[Print formulae with fully-qualified names. Unless `--full-name`, `--versions` or `--pinned` are passed, other options (i.e. `-1`, `-l`, `-r` and `-t`) are passed to `ls`(1) which produces the actual output]' \ '--help[Show this message]' \ '(--pinned --cask)--multiple[Only show formulae with multiple versions installed]' \ @@ -1026,17 +1067,19 @@ _brew_list() { '-l[List formulae in long format]' \ '-r[Reverse the order of the formulae sort to list the oldest entries first]' \ '-t[Sort formulae by time modified, listing most recently modified first]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --unbrewed)--formula[List only formulae, or treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula --multiple --unbrewed --pinned --l --r --t)--cask[List only casks, or treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew livecheck _brew_livecheck() { _arguments \ '(--tap --installed)--all[Check all available formulae/casks]' \ - '(--formula)--cask[Only check casks]' \ '(--json)--debug[Display any debugging information]' \ - '(--cask)--formula[Only check formulae]' \ '--full-name[Print formulae/casks with fully-qualified names]' \ '--help[Show this message]' \ '(--tap --all)--installed[Check formulae/casks that are currently installed]' \ @@ -1045,8 +1088,12 @@ _brew_livecheck() { '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ '(--all --installed)--tap[Check formulae/casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[Only check formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Only check casks]' \ + '*::cask:__brew_casks' } # brew ln @@ -1059,7 +1106,8 @@ _brew_ln() { '--overwrite[Delete files that already exist in the prefix while linking]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew log @@ -1074,15 +1122,14 @@ _brew_log() { '--stat[Also print diffstat from commit]' \ '--verbose[Make some output more verbose]' \ '-1[Print only one commit]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew ls _brew_ls() { _arguments \ - '(--formula --multiple --unbrewed --pinned --l --r --t)--cask[List only casks, or treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ - '(--cask --unbrewed)--formula[List only formulae, or treat all named arguments as formulae]' \ '(--versions --unbrewed --pinned --l --r --t)--full-name[Print formulae with fully-qualified names. Unless `--full-name`, `--versions` or `--pinned` are passed, other options (i.e. `-1`, `-l`, `-r` and `-t`) are passed to `ls`(1) which produces the actual output]' \ '--help[Show this message]' \ '(--pinned --cask)--multiple[Only show formulae with multiple versions installed]' \ @@ -1094,15 +1141,19 @@ _brew_ls() { '-l[List formulae in long format]' \ '-r[Reverse the order of the formulae sort to list the oldest entries first]' \ '-t[Sort formulae by time modified, listing most recently modified first]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --unbrewed)--formula[List only formulae, or treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula --multiple --unbrewed --pinned --l --r --t)--cask[List only casks, or treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew man _brew_man() { _arguments \ '--debug[Display any debugging information]' \ - '--fail-if-changed[Return a failing status code if changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)]' \ + '--fail-if-not-changed[Return a failing status code if no changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)]' \ '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' @@ -1116,7 +1167,8 @@ _brew_migrate() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew mirror @@ -1129,7 +1181,8 @@ _brew_mirror() { '--no-publish[Upload to Bintray, but don'\''t publish]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew missing @@ -1140,7 +1193,8 @@ _brew_missing() { '--hide[Act as if none of the specified hidden are installed. hidden should be a comma-separated list of formulae]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew options @@ -1154,23 +1208,26 @@ _brew_options() { '(--all --command)--installed[Show options for formulae that are currently installed]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew outdated _brew_outdated() { _arguments \ - '(--formula)--cask[List only outdated casks]' \ '--debug[Display any debugging information]' \ '--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ - '(--cask)--formula[List only outdated formulae]' \ '--greedy[Print outdated casks with `auto_updates` or `version :latest`]' \ '--help[Show this message]' \ '(--quiet --verbose)--json[Print output in JSON format. There are two versions: `v1` and `v2`. `v1` is deprecated and is currently the default if no version is specified. `v2` prints outdated formulae and casks. ]' \ '(--verbose --json)--quiet[List only the names of outdated kegs (takes precedence over `--verbose`)]' \ '(--quiet --json)--verbose[Include detailed version information]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--cask)--formula[List only outdated formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[List only outdated casks]' \ + '*::cask:__brew_casks' } # brew pin @@ -1180,7 +1237,8 @@ _brew_pin() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew postinstall @@ -1190,7 +1248,8 @@ _brew_postinstall() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew pr-automerge @@ -1225,10 +1284,11 @@ _brew_pr_publish() { # brew pr-pull _brew_pr_pull() { _arguments \ + '(--bintray-org)--archive-item[Upload to the specified Internet Archive item (default: `homebrew`)]' \ '--artifact[Download artifacts with the specified name (default: `bottles`)]' \ '(--clean)--autosquash[Automatically reformat and reword commits in the pull request to our preferred format]' \ '--bintray-mirror[Use the specified Bintray repository to automatically mirror stable URLs defined in the formulae (default: `mirror`)]' \ - '--bintray-org[Upload to the specified Bintray organisation (default: `homebrew`)]' \ + '(--archive-item)--bintray-org[Upload to the specified Bintray organisation (default: `homebrew`)]' \ '--branch-okay[Do not warn if pulling to a branch besides the repository default (useful for testing)]' \ '(--autosquash)--clean[Do not amend the commits from pull requests]' \ '--debug[Display any debugging information]' \ @@ -1251,9 +1311,11 @@ _brew_pr_pull() { # brew pr-upload _brew_pr_upload() { _arguments \ + '--archive-item[Upload to the specified Internet Archive item (default: `homebrew`)]' \ '--bintray-org[Upload to the specified Bintray organisation (default: `homebrew`)]' \ '--debug[Display any debugging information]' \ '--dry-run[Print what would be done rather than doing it]' \ + '--github-org[Upload to the specified GitHub organisation'\''s GitHub Packages (default: `homebrew`)]' \ '--help[Show this message]' \ '--keep-old[If the formula specifies a rebuild version, attempt to preserve its value in the generated DSL]' \ '--no-commit[Do not generate a new commit before uploading]' \ @@ -1272,7 +1334,8 @@ _brew_prof() { '--quiet[Make some output more quiet]' \ '--stackprof[Use `stackprof` instead of `ruby-prof` (the default)]' \ '--verbose[Make some output more verbose]' \ - '::command:__brew_commands' + - command \ + '*::command:__brew_commands' } # brew readall @@ -1284,7 +1347,8 @@ _brew_readall() { '--quiet[Make some output more quiet]' \ '--syntax[Syntax-check all of Homebrew'\''s Ruby files (if no `tap` is passed)]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew reinstall @@ -1294,7 +1358,6 @@ _brew_reinstall() { '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ '(--cask --force-bottle)--build-from-source[Compile formula from source even if a bottle is available]' \ - '(--formulae --build-from-source --interactive --force-bottle --keep-tmp --display-times)--cask[Treat all named arguments as casks]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ @@ -1302,7 +1365,6 @@ _brew_reinstall() { '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install without checking for previously installed keg-only or non-migrated versions]' \ '(--cask --build-from-source)--force-bottle[Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation]' \ - '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '(--formula)--input-methoddir[Target location for Input Methods (default: `~/Library/Input Methods`)]' \ '(--cask)--interactive[Download and patch formula, then open a shell. This allows the user to run `./configure --help` and otherwise determine how to turn the software package into a Homebrew package]' \ @@ -1323,8 +1385,12 @@ _brew_reinstall() { '--verbose[Print the verification and postinstall steps]' \ '(--formula)--vst-plugindir[Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`)]' \ '(--formula)--vst3-plugindir[Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`)]' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - formula \ + '(--casks --binaries --require-sha --quarantine --skip-cask-deps --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formulae --build-from-source --interactive --force-bottle --keep-tmp --display-times)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew release @@ -1351,33 +1417,37 @@ _brew_release_notes() { # brew remove _brew_remove() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--force[Delete all installed versions of formula. Uninstall even if cask is not installed, overwrite existing files and ignore errors when removing files]' \ - '(--cask --zap)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--ignore-dependencies[Don'\''t fail uninstall, even if formula is a dependency of any installed formulae]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '(--formula)--zap[Remove all files associated with a cask. *May remove files which are shared between applications.*]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --zap)--formula[Treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew rm _brew_rm() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--force[Delete all installed versions of formula. Uninstall even if cask is not installed, overwrite existing files and ignore errors when removing files]' \ - '(--cask --zap)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--ignore-dependencies[Don'\''t fail uninstall, even if formula is a dependency of any installed formulae]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '(--formula)--zap[Remove all files associated with a cask. *May remove files which are shared between applications.*]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --zap)--formula[Treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew ruby @@ -1389,7 +1459,8 @@ _brew_ruby() { '--verbose[Make some output more verbose]' \ '-e[Execute the given text string as a script]' \ '-r[Load a library using `require`]' \ - '::file:__brew_formulae_or_ruby_files' + - file \ + '*::file:__brew_formulae_or_ruby_files' } # brew search @@ -1422,7 +1493,8 @@ _brew_sh() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::file:__brew_formulae_or_ruby_files' + - file \ + '*::file:__brew_formulae_or_ruby_files' } # brew sponsors @@ -1437,21 +1509,25 @@ _brew_sponsors() { # brew style _brew_style() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--display-cop-names[Include the RuboCop cop name for each violation in the output]' \ '(--only-cops)--except-cops[Specify a comma-separated cops list to skip checking for violations of the listed RuboCop cops]' \ '--fix[Fix style violations automatically using RuboCop'\''s auto-correct feature]' \ - '(--cask)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '(--except-cops)--only-cops[Specify a comma-separated cops list to check for violations of only the listed RuboCop cops]' \ '--quiet[Make some output more quiet]' \ '--reset-cache[Reset the RuboCop cache]' \ '--verbose[Make some output more verbose]' \ - '::file:__brew_formulae_or_ruby_files' \ - '::tap:__brew_any_tap' \ - '::formula:__brew_formulae' \ - '::cask:__brew_casks' + - file \ + '*::file:__brew_formulae_or_ruby_files' \ + - tap \ + '*::tap:__brew_any_tap' \ + - formula \ + '(--cask)--formula[Treat all named arguments as formulae]' \ + '*::formula:__brew_formulae' \ + - cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::cask:__brew_casks' } # brew tap @@ -1466,7 +1542,8 @@ _brew_tap() { '--repair[Migrate tapped formulae from symlink-based to directory-based structure]' \ '--shallow[Fetch tap as a shallow clone rather than a full clone. Useful for continuous integration]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew tap-info @@ -1478,20 +1555,22 @@ _brew_tap_info() { '--json[Print a JSON representation of tap. Currently the default and only accepted value for version is `v1`. See the docs for examples of using the JSON output: https://docs.brew.sh/Querying-Brew]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew tap-new _brew_tap_new() { _arguments \ - '(--no-git)--branch[Initialize Git repository with the specified branch name (default: `main`)]' \ + '--branch[Initialize Git repository and setup GitHub Actions workflows with the specified branch name (default: `main`)]' \ '--debug[Display any debugging information]' \ '--help[Show this message]' \ - '(--branch)--no-git[Don'\''t initialize a Git repository for the tap]' \ + '--no-git[Don'\''t initialize a Git repository for the tap]' \ '--pull-label[Label name for pull requests ready to be pulled (default: `pr-pull`)]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew tc @@ -1520,7 +1599,8 @@ _brew_test() { '--quiet[Make some output more quiet]' \ '--retry[Retry if a testing fails]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew tests @@ -1565,39 +1645,44 @@ _brew_unbottled() { '--tag[Use the specified bottle tag (e.g. `big_sur`) instead of the current OS]' \ '(--dependents)--total[Print the number of unbottled and total formulae]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew uninstal _brew_uninstal() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--force[Delete all installed versions of formula. Uninstall even if cask is not installed, overwrite existing files and ignore errors when removing files]' \ - '(--cask --zap)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--ignore-dependencies[Don'\''t fail uninstall, even if formula is a dependency of any installed formulae]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '(--formula)--zap[Remove all files associated with a cask. *May remove files which are shared between applications.*]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --zap)--formula[Treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew uninstall _brew_uninstall() { _arguments \ - '(--formula)--cask[Treat all named arguments as casks]' \ '--debug[Display any debugging information]' \ '--force[Delete all installed versions of formula. Uninstall even if cask is not installed, overwrite existing files and ignore errors when removing files]' \ - '(--cask --zap)--formula[Treat all named arguments as formulae]' \ '--help[Show this message]' \ '--ignore-dependencies[Don'\''t fail uninstall, even if formula is a dependency of any installed formulae]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ '(--formula)--zap[Remove all files associated with a cask. *May remove files which are shared between applications.*]' \ - '::installed_formula:__brew_installed_formulae' \ - '::installed_cask:__brew_installed_casks' + - installed_formula \ + '(--cask --zap)--formula[Treat all named arguments as formulae]' \ + '*::installed_formula:__brew_installed_formulae' \ + - installed_cask \ + '(--formula)--cask[Treat all named arguments as casks]' \ + '*::installed_cask:__brew_installed_casks' } # brew unlink @@ -1608,7 +1693,8 @@ _brew_unlink() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew unpack @@ -1622,7 +1708,8 @@ _brew_unpack() { '(--git)--patch[Patches for formula will be applied to the unpacked source]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew unpin @@ -1632,7 +1719,8 @@ _brew_unpin() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::installed_formula:__brew_installed_formulae' + - installed_formula \ + '*::installed_formula:__brew_installed_formulae' } # brew untap @@ -1643,7 +1731,8 @@ _brew_untap() { '--help[Show this message]' \ '--quiet[Make some output more quiet]' \ '--verbose[Make some output more verbose]' \ - '::tap:__brew_any_tap' + - tap \ + '*::tap:__brew_any_tap' } # brew up @@ -1701,7 +1790,8 @@ _brew_update_python_resources() { '--silent[Suppress any output]' \ '--verbose[Make some output more verbose]' \ '--version[Use the specified version when finding resources for formula. If no version is specified, the current version for formula will be used]' \ - '::formula:__brew_formulae' + - formula \ + '*::formula:__brew_formulae' } # brew update-report @@ -1735,7 +1825,6 @@ _brew_upgrade() { '(--formula)--audio-unit-plugindir[Target location for Audio Unit Plugins (default: `~/Library/Audio/Plug-Ins/Components`)]' \ '(--formula)--binaries[Disable/enable linking of helper executables (default: enabled)]' \ '(--cask --force-bottle)--build-from-source[Compile formula from source even if a bottle is available]' \ - '(--formulae --build-from-source --interactive --force-bottle --fetch-HEAD --ignore-pinned --keep-tmp --display-times)--cask[Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks]' \ '(--formula)--colorpickerdir[Target location for Color Pickers (default: `~/Library/ColorPickers`)]' \ '--debug[If brewing fails, open an interactive debugging session with access to IRB or a shell inside the temporary build directory]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ @@ -1745,7 +1834,6 @@ _brew_upgrade() { '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \ '(--cask --build-from-source)--force-bottle[Install from a bottle if it exists for the current or newest version of macOS, even if it would not normally be used for installation]' \ - '(--casks --binaries --require-sha --quarantine --skip-cask-deps --greedy --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae. If no named arguments are specified, upgrade only outdated formulae]' \ '(--formula)--greedy[Also include casks with `auto_updates true` or `version :latest`]' \ '--help[Show this message]' \ '(--cask)--ignore-pinned[Set a successful exit status even if pinned formulae are not upgraded]' \ @@ -1768,8 +1856,12 @@ _brew_upgrade() { '--verbose[Print the verification and postinstall steps]' \ '(--formula)--vst-plugindir[Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`)]' \ '(--formula)--vst3-plugindir[Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`)]' \ - '::outdated_formula:__brew_outdated_formulae' \ - '::outdated_cask:__brew_outdated_casks' + - outdated_formula \ + '(--casks --binaries --require-sha --quarantine --skip-cask-deps --greedy --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae. If no named arguments are specified, upgrade only outdated formulae]' \ + '*::outdated_formula:__brew_outdated_formulae' \ + - outdated_cask \ + '(--formulae --build-from-source --interactive --force-bottle --fetch-HEAD --ignore-pinned --keep-tmp --display-times)--cask[Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks]' \ + '*::outdated_cask:__brew_outdated_casks' } # brew uses @@ -1777,7 +1869,6 @@ _brew_uses() { _arguments \ '(--formula)--cask[Include only casks]' \ '--debug[Display any debugging information]' \ - '(--cask)--formula[Include only formulae]' \ '--help[Show this message]' \ '--include-build[Include all formulae that specify formula as `:build` type dependency]' \ '--include-optional[Include all formulae that specify formula as `:optional` type dependency]' \ @@ -1787,7 +1878,9 @@ _brew_uses() { '--recursive[Resolve more than one level of dependencies]' \ '--skip-recommended[Skip all formulae that specify formula as `:recommended` type dependency]' \ '--verbose[Make some output more verbose]' \ - '::formula:__brew_formulae' + - formula \ + '(--cask)--formula[Include only formulae]' \ + '*::formula:__brew_formulae' } # brew vendor-gems diff --git a/docs/Acceptable-Casks.md b/docs/Acceptable-Casks.md index ac2184c991..3c8c893ae8 100644 --- a/docs/Acceptable-Casks.md +++ b/docs/Acceptable-Casks.md @@ -2,8 +2,8 @@ Some casks should not go in [homebrew/cask](https://github.com/Homebrew/homebrew-cask). But there are -additional [Interesting Taps and Forks](Interesting-Taps-and-Forks.md) and anyone can start their -own! +additional [Interesting Taps and Forks](Interesting-Taps-and-Forks.md) and anyone can [start their +own](Taps.md)! ## Finding a Home For Your Cask @@ -14,7 +14,7 @@ We maintain separate Taps for different types of binaries. Our nomenclature is: + **Nightly**: Constantly up-to-date versions of the current development state. + **Legacy**: Any **stable** version that is not the most recent. + **Regional, Localized**: Any version that isn’t the US English one, when that exists. -+ **Trial**: Date-limited version that stops working entirely after it expires, requiring payment to lift the limitation. ++ **Trial**: Time-limited version that stops working entirely after it expires, requiring payment to lift the limitation. + **Freemium**: Gratis version that works indefinitely but with limitations that can be removed by paying. + **Fork**: An alternate version of an existing project, with a based-on but modified source and binary. + **Unofficial**: An *allegedly* unmodified compiled binary, by a third-party, of a binary that has no existing build by the owner of the source code. @@ -70,13 +70,13 @@ for details. Unfortunately, in the world of software there are bad actors that bundle malware with their apps. Even so, Homebrew Cask has long decided it will not be an active gatekeeper ([macOS already has one](https://support.apple.com/en-us/HT202491)) and [users are expected to know about the software they are installing](#homebrew-cask-is-not-a-discoverability-service). This means we will not always remove casks that link to these apps, in part because there is no clear line between useful app, potentially unwanted program, and the different shades of malware — what is useful to one user may be seen as malicious by another. -Within that context, we would still like for users to enjoy some kind of protection while minimising occurrences of legitimate developers being branded as malware carriers. To do so, we evaluate casks on a case-by-case basis, and any user is free to bring a potential malware case to our attention. It is, however, important to never forget the last line of defence is *always* the user. +But we’d still like for users to enjoy some kind of protection while minimising occurrences of legitimate developers being branded as malware carriers. To do so, we evaluate casks on a case-by-case basis and any user is free to bring a potential malware case to our attention. However, it is important to never forget the last line of defence is *always* the user. -If an app that bundles malware was not signed with an Apple Developer ID and you purposefully disabled or bypassed Gatekeeper, no action will be taken on our part. When you disable security features, you do so at your own risk. If, however, an app that bundles malware is signed, Apple can revoke its permissions and it will no longer run on the computers of users that keep security features on — we all benefit, Homebrew Cask users or not. To report a signed app that bundles malware, use [Apple’s Bug Reporter](https://bugreport.apple.com/) +If an app that bundles malware was not signed with an Apple Developer ID and you purposefully disabled or bypassed Gatekeeper, no action will be taken on our part. When you disable security features, you do so at your own risk. If, however, an app that bundles malware is signed, Apple can revoke its permissions and it will no longer run on the computers of users that keep security features on — we all benefit, Homebrew Cask users or not. To report a signed app that bundles malware, use [Apple’s Feedback Assistant](https://feedbackassistant.apple.com) We are also open to removing casks where we feel there is enough evidence that the app is malicious. To suggest a cask for removal, submit a Pull Request to delete it, together with your reasoning. Typically, this will mean presenting a [VirusTotal](https://www.virustotal.com) scan of the app showing it is malicious, ideally with some other reporting indicating it’s not a false positive. -Likewise, software that provides both “clean” and malware-infested versions might be removed from the repo — even if we could have access to the *good* version — if its developers push for users to install the *bad* version. We do so because in these cases, there’s a higher than normal risk that both versions are (or will soon become) compromised in some manner. +Likewise, software which provides both “clean” and malware-infested versions might be removed from the repo — even if we could have access to the *good* version — if its developers push for users to install the *bad* version. We do so because in these cases there’s a higher than normal risk that both versions are (or will soon become) compromised in some manner. If a cask you depend on was removed due to these rules, fear not. Removal of a cask from the official repositories means we won’t support it, but you can do so by hosting your own [tap](How-to-Create-and-Maintain-a-Tap.md). @@ -112,10 +112,10 @@ Common reasons to reject a Cask entirely: + Similarly (and trickier to spot), the app has moved to the Mac App Store but still provides old versions via direct download. We reject these in all official repos so users don’t get stuck using an old version, wrongly thinking they’re using the most up-to-date one (which, amongst other things, might be a security risk). + The app is both open-source and CLI-only (i.e. it only uses the `binary` artifact). In that case, and [in the spirit of deduplication](https://github.com/Homebrew/homebrew-cask/issues/15603), submit it first to [Homebrew/core](https://github.com/Homebrew/homebrew-core) as a formula that builds from source. If it is rejected, you may then try again as a cask (link us to the issue so we can see the discussion and reasoning for rejection). + The app is open-source and has a GUI but no compiled versions (or only old ones) are provided. It’s better to have them in [Homebrew](https://github.com/Homebrew/homebrew) so users don’t get perpetually outdated versions. See [`gedit`](https://github.com/Homebrew/homebrew-cask/pull/23360) for example. -+ The app has been rejected before due to an issue we cannot fix, and this new submission doesn’t fix that . An example would be [the first submission of `soapui`](https://github.com/Homebrew/homebrew-cask/pull/4939), whose installation problems were not fixed in the two subsequent submissions ([#9969](https://github.com/Homebrew/homebrew-cask/pull/9969), [#10606](https://github.com/Homebrew/homebrew-cask/pull/10606)). ++ The app has been rejected before due to an issue we cannot fix, and the new submission doesn’t fix that. An example would be [the first submission of `soapui`](https://github.com/Homebrew/homebrew-cask/pull/4939), whose installation problems were not fixed in the two subsequent submissions ([#9969](https://github.com/Homebrew/homebrew-cask/pull/9969), [#10606](https://github.com/Homebrew/homebrew-cask/pull/10606)). + The Cask is a duplicate. These submissions mostly occur when the [token reference](https://github.com/Homebrew/homebrew-cask/blob/HEAD/doc/cask_language_reference/token_reference.md) was not followed. -+ The download URL for the app is both behind a login/registration form and from a host that differs from the homepage, meaning users can’t easily verify its authenticity. [alehouse/homebrew-unofficial](https://github.com/alehouse/homebrew-unofficial) is a sister repo where you may wish to submit your cask. -+ The Cask is for an app that is unmaintained (no releases in the last year, or [explicitly discontinued](https://github.com/Homebrew/homebrew-cask/pull/22699)). ++ The download URL for the app is both behind a login/registration form and from a host that differs from the homepage, meaning users can’t easily verify its authenticity. ++ The Cask is for an unmaintained app (no releases in the last year, or [explicitly discontinued](https://github.com/Homebrew/homebrew-cask/pull/22699)). + The Cask is for an app that is too obscure. Examples: + An app from a code repository that is not notable enough (under 30 forks, 30 watchers, 75 stars). + [Electronic Identification (eID) software](https://github.com/Homebrew/homebrew-cask/issues/59021). diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index dee1251fdd..852e5ad35c 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.3.4) + activesupport (6.0.3.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -31,11 +31,11 @@ GEM multipart-post (>= 1.2, < 3) ruby2_keywords faraday-net_http (1.0.1) - ffi (1.14.2) + ffi (1.15.0) forwardable-extended (2.6.0) gemoji (3.0.1) - github-pages (211) - github-pages-health-check (= 1.16.1) + github-pages (212) + github-pages-health-check (= 1.17.0) jekyll (= 3.9.0) jekyll-avatar (= 0.7.0) jekyll-coffeescript (= 1.1.1) @@ -78,16 +78,16 @@ GEM nokogiri (>= 1.10.4, < 2.0) rouge (= 3.26.0) terminal-table (~> 1.4) - github-pages-health-check (1.16.1) + github-pages-health-check (1.17.0) addressable (~> 2.3) dnsruby (~> 1.60) octokit (~> 4.0) - public_suffix (~> 3.0) + public_suffix (>= 2.0.2, < 5.0) typhoeus (~> 1.3) html-pipeline (2.14.0) activesupport (>= 2) nokogiri (>= 1.4) - html-proofer (3.18.5) + html-proofer (3.18.8) addressable (~> 2.3) mercenary (~> 0.3) nokogumbo (~> 2.0) @@ -231,7 +231,7 @@ GEM parallel (1.20.1) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (3.1.1) + public_suffix (4.0.6) racc (1.5.2) rainbow (3.0.0) rake (13.0.3) diff --git a/docs/Homebrew-Governance.md b/docs/Homebrew-Governance.md index 2b574729d3..ea54e90066 100644 --- a/docs/Homebrew-Governance.md +++ b/docs/Homebrew-Governance.md @@ -54,7 +54,7 @@ 1. The governance and operation of Homebrew is determined by the PLC. The PLC will represent Homebrew in all dealings with the Software Freedom Conservancy (SFC). The PLC has final authority in all matters related to the operation of Homebrew, and will comply with all Software Freedom Conservancy policies. -2. The PLC consists of five members. Committee members are elected by majority vote of Homebrew members. Each PLC member will serve a term of two years or until the member's successor is elected. Any sudden vacancy in the PLC will be filled by the usual procedure for electing PLC members at the next general meeting, typically the next AGM. +2. The PLC consists of five members. Committee members are elected by Homebrew members in a [Meek Single Transferable Vote](https://en.wikipedia.org/wiki/Counting_single_transferable_votes#Meek) election using the Droop quota. Each PLC member will serve a term of two years or until the member's successor is elected. Any sudden vacancy in the PLC will be filled by the usual procedure for electing PLC members at the next general meeting, typically the next AGM. 3. Three weeks prior to the AGM, the PLC will nominate at least one candidate for each upcoming vacant seat. Any member may also nominate any other member as a candidate for the PLC at this time. @@ -84,7 +84,7 @@ 1. The Project Leader will represent Homebrew publicly, manage all day-to-day technical decisions, and resolve disputes related to the operation of Homebrew between maintainers, members, other contributors, and users. -2. The Project Leader will be elected annually by a majority vote of Homebrew members. The PLC will nominate at least one candidate for Project Leader. Any member may nominate a candidate, or self-nominate. Nominations must be announced to the membership three weeks before the AGM. +2. The Project Leader will be elected annually by Homebrew members in a [Schulze Condorcet method](https://en.wikipedia.org/wiki/Schulze_method) election. The PLC will nominate at least one candidate for Project Leader. Any member may nominate a candidate, or self-nominate. Nominations must be announced to the membership three weeks before the AGM. 3. Any vacancy of the Project Leader will be filled by appointment of the PLC. diff --git a/docs/Homebrew-and-Java.md b/docs/Homebrew-and-Java.md new file mode 100644 index 0000000000..3852e9c4c0 --- /dev/null +++ b/docs/Homebrew-and-Java.md @@ -0,0 +1,9 @@ +# Homebrew and Java + +This page describes how Java is handled in Homebrew for users. Prospective formula authors may refer to existing Java-based formulae for examples of how to install packages written in Java via Homebrew, or visit the [Homebrew discussion forum](https://github.com/Homebrew/discussions/discussions) to seek guidance for their specific situation. + +Most Java-based packages in Homebrew use the default Homebrew-provided `openjdk` package for their JDK dependency, although some packages with specific version requirements may use a versioned package such as `openjdk@8`. + +## Executing commands using a different JDK + +In situations where the user wants to override the use of the Homebrew-provided JDK, setting the `JAVA_HOME` environment variable will cause the specified location to be used as the Java home directory instead of the version of `openjdk` specified as a dependency. diff --git a/docs/Installation.md b/docs/Installation.md index 326bbfe0f8..7e9a937b7f 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -18,6 +18,18 @@ it does it too. You have to confirm everything it will do before it starts. [Xcode](https://itunes.apple.com/us/app/xcode/id497799835) [3](#3) * A Bourne-compatible shell for installation (e.g. `bash` or `zsh`) [4](#4) +## Git Remote Mirroring + +You can set `HOMEBREW_BREW_GIT_REMOTE` and/or `HOMEBREW_CORE_GIT_REMOTE` in your shell environment to use geolocalized Git mirrors to speed up Homebrew's installation with this script and, after installation, `brew update`. + +```bash +export HOMEBREW_BREW_GIT_REMOTE="..." # put your Git mirror of Homebrew/brew here +export HOMEBREW_CORE_GIT_REMOTE="..." # put your Git mirror of Homebrew/homebrew-core here +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" +``` + +The default Git remote will be used if the corresponding environment variable is unset. + ## Alternative Installs ### Linux or Windows 10 Subsystem for Linux diff --git a/docs/Manpage.md b/docs/Manpage.md index e977015f9d..9c9773efd1 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -734,8 +734,7 @@ Display Homebrew's install path. *Default:* - macOS ARM: `/opt/homebrew` - Linux: `/home/linuxbrew/.linuxbrew` -If *`formula`* is provided, display the location in the Cellar where *`formula`* -is or would be installed. +If *`formula`* is provided, display the location where *`formula`* is or would be installed. * `--unbrewed`: List files in Homebrew's prefix not installed by Homebrew. @@ -750,8 +749,7 @@ If *`user`*`/`*`repo`* are provided, display where tap *`user`*`/`*`repo`*'s dir ### `--version`, `-v` -Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask -(if tapped) to standard output. +Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask (if tapped) to standard output. ## DEVELOPER COMMANDS @@ -826,11 +824,19 @@ value, while `--no-rebuild` will remove it. * `--root-url`: Use the specified *`URL`* as the root of the bottle's URL instead of Homebrew's default. -### `bump` [*`--limit`*`=`] [*`formula`* ...] +### `bump` [*`options`*] [*`formula`*|*`cask`* ...] Display out-of-date brew formulae and the latest version available. Also displays whether a pull request has been opened with the URL. +* `--full-name`: + Print formulae/casks with fully-qualified names. +* `--no-pull-requests`: + Do not retrieve pull requests from GitHub. +* `--formula`: + Check only formulae. +* `--cask`: + Check only casks. * `--limit`: Limit number of package results returned. @@ -1013,6 +1019,8 @@ Build bottles for these formulae with GitHub Actions. Dispatch specified workflow (default: `dispatch-build-bottle.yml`). * `--upload`: Upload built bottles to Bintray. +* `--linux`: + Dispatch bottle for Linux (using GitHub runners). ### `edit` [*`--formula`*] [*`--cask`*] [*`formula`*|*`cask`* ...] @@ -1094,14 +1102,14 @@ casks to check is taken from `HOMEBREW_LIVECHECK_WATCHLIST` or * `--cask`: Only check casks. -### `man` [*`--fail-if-changed`*] +### `man` [*`--fail-if-not-changed`*] Generate Homebrew's manpages. *Note:* Not (yet) working on Apple Silicon. -* `--fail-if-changed`: - Return a failing status code if changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date). +* `--fail-if-not-changed`: + Return a failing status code if no changes are detected in the manpage outputs. This can be used to notify CI when the manpages are out of date. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date). ### `mirror` [*`options`*] *`formula`* [...] @@ -1175,6 +1183,8 @@ Requires write access to the repository. Message to include when autosquashing revision bumps, deletions, and rebuilds. * `--artifact`: Download artifacts with the specified name (default: `bottles`). +* `--archive-item`: + Upload to the specified Internet Archive item (default: `homebrew`). * `--bintray-org`: Upload to the specified Bintray organisation (default: `homebrew`). * `--tap`: @@ -1190,7 +1200,7 @@ Requires write access to the repository. ### `pr-upload` [*`options`*] -Apply the bottle commit and publish bottles to Bintray or GitHub Releases. +Apply the bottle commit and publish bottles to a host. * `--no-publish`: Apply the bottle commit and upload the bottles, but don't publish them. @@ -1202,15 +1212,21 @@ Apply the bottle commit and publish bottles to Bintray or GitHub Releases. Do not generate a new commit before uploading. * `--warn-on-upload-failure`: Warn instead of raising an error if the bottle upload fails. Useful for repairing bottle uploads that previously failed. +* `--archive-item`: + Upload to the specified Internet Archive item (default: `homebrew`). * `--bintray-org`: Upload to the specified Bintray organisation (default: `homebrew`). +* `--github-org`: + Upload to the specified GitHub organisation's GitHub Packages (default: `homebrew`). * `--root-url`: Use the specified *`URL`* as the root of the bottle's URL instead of Homebrew's default. -### `prof` [*`--stackprof`*] [*`command`* ...] +### `prof` [*`--stackprof`*] *`command`* [...] Run Homebrew with a Ruby profiler. For example, `brew prof readall`. +*Note:* Not (yet) working on Apple Silicon. + * `--stackprof`: Use `stackprof` instead of `ruby-prof` (the default). @@ -1259,7 +1275,7 @@ which build systems would not find otherwise. ### `sponsors` -Print a Markdown summary of Homebrew's GitHub Sponsors, suitable for pasting into a README. +Update the list of GitHub Sponsors in the `Homebrew/brew` README. ### `style` [*`options`*] [*`file`*|*`tap`*|*`formula`*|*`cask`* ...] @@ -1293,7 +1309,7 @@ Generate the template files for a new tap. * `--pull-label`: Label name for pull requests ready to be pulled (default: `pr-pull`). * `--branch`: - Initialize Git repository with the specified branch name (default: `main`). + Initialize Git repository and setup GitHub Actions workflows with the specified branch name (default: `main`). ### `test` [*`options`*] *`installed_formula`* [...] @@ -1718,7 +1734,7 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just
If set, use Bootsnap to speed up repeated `brew` calls. A no-op when using Homebrew's vendored, relocatable Ruby on macOS (as it doesn't work). - `HOMEBREW_BOTTLE_DOMAIN` -
Use this URL as the download mirror for bottles. For example, `HOMEBREW_BOTTLE_DOMAIN=http://localhost:8080` will cause all bottles to download from the prefix `http://localhost:8080/`. +
Use this URL as the download mirror for bottles. If bottles at that URL are temporarily unavailable, the default bottle domain will be used as a fallback mirror. For example, `HOMEBREW_BOTTLE_DOMAIN=http://localhost:8080` will cause all bottles to download from the prefix `http://localhost:8080/`. If bottles are not available at `HOMEBREW_BOTTLE_DOMAIN` they will be downloaded from the default bottle domain. *Default:* macOS: `https://homebrew.bintray.com/`, Linux: `https://linuxbrew.bintray.com/`. @@ -1817,6 +1833,12 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just *Note:* Homebrew doesn't require permissions for any of the scopes, but some developer commands may require additional permissions. +- `HOMEBREW_GITHUB_PACKAGES_TOKEN` +
Use this GitHub personal access token when accessing the GitHub Packages Registry (where bottles may be stored). + +- `HOMEBREW_GITHUB_PACKAGES_USER` +
Use this username when accessing the GitHub Packages Registry (where bottles may be stored). + - `HOMEBREW_GIT_EMAIL`
Set the Git author and committer email to this value. @@ -1828,6 +1850,9 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just *Default:* The "Beer Mug" emoji. +- `HOMEBREW_INTERNET_ARCHIVE_KEY` +
Use this API key when accessing the Internet Archive S3 API, where bottles are stored. The format is access:secret. See https://archive.org/account/s3.php + - `HOMEBREW_LIVECHECK_WATCHLIST`
Consult this file for the list of formulae to check by default when no formula argument is passed to `brew livecheck`. @@ -1847,14 +1872,11 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just
If set, do not send analytics. For more information, see: - `HOMEBREW_NO_AUTO_UPDATE` -
If set, do not automatically update before running `brew install`, `brew upgrade` or `brew tap`. +
If set, do not automatically update before running some commands e.g. `brew install`, `brew upgrade` and `brew tap`. - `HOMEBREW_NO_BOOTSNAP`
If set, do not use Bootsnap to speed up repeated `brew` calls. -- `HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK` -
If set, fail on the failure of installation from a bottle rather than falling back to building from source. - - `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK`
If set, do not check for broken dependents after installing, upgrading or reinstalling formulae. @@ -1885,6 +1907,9 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just - `HOMEBREW_PRY`
If set, use Pry for the `brew irb` command. +- `HOMEBREW_SIMULATE_MACOS_ON_LINUX` +
If set, running Homebrew on Linux will simulate certain macOS code paths. This is useful when auditing macOS formulae while on Linux. Implies `HOMEBREW_FORCE_HOMEBREW_ON_LINUX`. + - `HOMEBREW_SKIP_OR_LATER_BOTTLES`
If set along with `HOMEBREW_DEVELOPER`, do not use bottles from older versions of macOS. This is useful in development on new macOS versions. @@ -1961,13 +1986,13 @@ Homebrew API: Homebrew's Project Leader is Mike McQuaid. -Homebrew's Project Leadership Committee is Jonathan Chang, Markus Reiter, Misty De Meo, Sean Molenaar and Shaun Jackman. +Homebrew's Project Leadership Committee is Issy Long, Jonathan Chang, Markus Reiter, Misty De Meo and Sean Molenaar. -Homebrew's Technical Steering Committee is FX Coudert, Markus Reiter, Michka Popoff, Mike McQuaid and Misty De Meo. +Homebrew's Technical Steering Committee is Bo Anderson, FX Coudert, Michka Popoff, Mike McQuaid and Rylan Polster. Homebrew's Linux maintainers are Daniel Nachun, Dawid Dziurla, Issy Long, Jonathan Chang, Michka Popoff and Shaun Jackman. -Homebrew's other current maintainers are Alexander Bayandin, Bo Anderson, Caleb Xu, Carlo Cabrera, Claudia Pellegrino, Dustin Rodrigues, Eric Knibbe, Maxim Belkin, Miccal Matthews, Nanda H Krishna, Randall, Rylan Polster, Sam Ford, Seeker, Steve Peters, Thierry Moisan, Tom Schoonjans, Vítor Galvão and rui. +Homebrew's other current maintainers are Alexander Bayandin, Caleb Xu, Carlo Cabrera, Claudia Pellegrino, Dustin Rodrigues, Eric Knibbe, Maxim Belkin, Miccal Matthews, Nanda H Krishna, Randall, Sam Ford, Seeker, Steve Peters, Thierry Moisan, Tom Schoonjans, Vítor Galvão and rui. Former maintainers with significant contributions include Jan Viljanen, JCount, commitay, Dominyk Tiller, Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski, Alyssa Ross, ilovezfs, Chongyu Zhu and Homebrew's creator: Max Howell. diff --git a/docs/New-Maintainer-Checklist.md b/docs/New-Maintainer-Checklist.md index 3abaa59625..de4cb9eb1a 100644 --- a/docs/New-Maintainer-Checklist.md +++ b/docs/New-Maintainer-Checklist.md @@ -18,7 +18,7 @@ issues, or reviewing user pull requests. You should also be making contributions to Homebrew at least once per quarter. You should watch or regularly check Homebrew/brew and/or -Homebrew/homebrew-core and/or Homebrew/homebrew-cask. Let us know which so we +Homebrew/homebrew-core and/or Homebrew/homebrew-cask. Let us know which so we can grant you commit access appropriately. If you're no longer able to perform all of these tasks, please continue to @@ -63,7 +63,6 @@ If they accept, follow a few steps to get them set up: - Invite them to the [`machomebrew` private maintainers Slack](https://machomebrew.slack.com/admin/invites) (and ensure they've read the [communication guidelines](Maintainer-Guidelines.md#communication)) and ask them to use their real name there (rather than a pseudonym they may use on e.g. GitHub). - Ask them to disable SMS as a 2FA device or fallback on their GitHub account in favour of using one of the other authentication methods. - Ask them to (regularly) review remove any unneeded [GitHub personal access tokens](https://github.com/settings/tokens). -- Add them to Homebrew/brew's README, run `brew man` and commit the changes. - Start the process to [add them as Homebrew members](#members), for formal voting rights and the ability to hold office for Homebrew. If they are interested in doing system administration work: @@ -77,7 +76,7 @@ If they are elected to the Homebrew's [Project Leadership Committee](https://doc - Email their name, email and employer to the [Software Freedom Conservancy](https://sfconservancy.org) at homebrew@sfconservancy.org - Make them [owners on the Homebrew GitHub organisation](https://github.com/orgs/Homebrew/people) - Invite them to the [**@Homebrew/plc** team](https://github.com/orgs/Homebrew/teams/plc/members) -- Invite them to [Google Analytics](https://analytics.google.com/analytics/web/#management/Settings/a76679469w115400090p120682403/%3Fm.page%3DAccountUsers/) and add them to the relevant section of the [Homebrew/brew's README](https://github.com/Homebrew/brew/edit/master/README.md). +- Invite them to [Google Analytics](https://analytics.google.com/analytics/web/#management/Settings/a76679469w115400090p120682403/%3Fm.page%3DAccountUsers/). - Invite them to the [`homebrew` private 1Password](https://homebrew.1password.com/people). - Make them owners on the [`machomebrew` private maintainers Slack](https://machomebrew.slack.com/admin)). diff --git a/docs/Rename-A-Formula.md b/docs/Rename-A-Formula.md index e4123e7125..b117f46116 100644 --- a/docs/Rename-A-Formula.md +++ b/docs/Rename-A-Formula.md @@ -3,7 +3,7 @@ Sometimes software and formulae need to be renamed. To rename a formula you need to: -1. Rename the formula file and its class to a new formula. The new name must meet all the usual rules of formula naming. Fix any test failures that may occur due to the stricter requirements for new formulae than existing formulae (i.e. `brew audit --strict` must pass for that formula). +1. Rename the formula file and its class to a new formula. The new name must meet all the usual rules of formula naming. Fix any test failures that may occur due to the stricter requirements for new formulae than existing formulae (i.e. `brew audit --online --new-formula` must pass for that formula). 2. Create a pull request to the corresponding tap deleting the old formula file, adding the new formula file, and adding it to `formula_renames.json` with a commit message like `newack: renamed from ack`. Use the canonical name (e.g. `ack` instead of `user/repo/ack`). diff --git a/manpages/brew.1 b/manpages/brew.1 index cfb2168156..02053bfdc0 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW" "1" "February 2021" "Homebrew" "brew" +.TH "BREW" "1" "March 2021" "Homebrew" "brew" . .SH "NAME" \fBbrew\fR \- The Missing Package Manager for macOS (or Linux) @@ -997,7 +997,7 @@ Linux: \fB/home/linuxbrew/\.linuxbrew\fR .IP "" 0 . .P -If \fIformula\fR is provided, display the location in the Cellar where \fIformula\fR is or would be installed\. +If \fIformula\fR is provided, display the location where \fIformula\fR is or would be installed\. . .TP \fB\-\-unbrewed\fR @@ -1132,10 +1132,26 @@ When passed with \fB\-\-write\fR, a new commit will not generated after writing \fB\-\-root\-url\fR Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew\'s default\. . -.SS "\fBbump\fR [\fI\-\-limit\fR\fB=\fR] [\fIformula\fR \.\.\.]" +.SS "\fBbump\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR \.\.\.]" Display out\-of\-date brew formulae and the latest version available\. Also displays whether a pull request has been opened with the URL\. . .TP +\fB\-\-full\-name\fR +Print formulae/casks with fully\-qualified names\. +. +.TP +\fB\-\-no\-pull\-requests\fR +Do not retrieve pull requests from GitHub\. +. +.TP +\fB\-\-formula\fR +Check only formulae\. +. +.TP +\fB\-\-cask\fR +Check only casks\. +. +.TP \fB\-\-limit\fR Limit number of package results returned\. . @@ -1414,6 +1430,10 @@ Dispatch specified workflow (default: \fBdispatch\-build\-bottle\.yml\fR)\. \fB\-\-upload\fR Upload built bottles to Bintray\. . +.TP +\fB\-\-linux\fR +Dispatch bottle for Linux (using GitHub runners)\. +. .SS "\fBedit\fR [\fI\-\-formula\fR] [\fI\-\-cask\fR] [\fIformula\fR|\fIcask\fR \.\.\.]" Open a \fIformula\fR or \fIcask\fR in the editor set by \fBEDITOR\fR or \fBHOMEBREW_EDITOR\fR, or open the Homebrew repository for editing if no formula is provided\. . @@ -1510,15 +1530,15 @@ Only check formulae\. \fB\-\-cask\fR Only check casks\. . -.SS "\fBman\fR [\fI\-\-fail\-if\-changed\fR]" +.SS "\fBman\fR [\fI\-\-fail\-if\-not\-changed\fR]" Generate Homebrew\'s manpages\. . .P \fINote:\fR Not (yet) working on Apple Silicon\. . .TP -\fB\-\-fail\-if\-changed\fR -Return a failing status code if changes are detected in the manpage outputs\. This can be used to notify CI when the manpages are out of date\. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)\. +\fB\-\-fail\-if\-not\-changed\fR +Return a failing status code if no changes are detected in the manpage outputs\. This can be used to notify CI when the manpages are out of date\. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)\. . .SS "\fBmirror\fR [\fIoptions\fR] \fIformula\fR [\.\.\.]" Reupload the stable URL of a formula to Bintray for use as a mirror\. @@ -1633,6 +1653,10 @@ Message to include when autosquashing revision bumps, deletions, and rebuilds\. Download artifacts with the specified name (default: \fBbottles\fR)\. . .TP +\fB\-\-archive\-item\fR +Upload to the specified Internet Archive item (default: \fBhomebrew\fR)\. +. +.TP \fB\-\-bintray\-org\fR Upload to the specified Bintray organisation (default: \fBhomebrew\fR)\. . @@ -1657,7 +1681,7 @@ Retrieve artifacts from the specified workflow (default: \fBtests\.yml\fR)\. Can Comma\-separated list of workflows which can be ignored if they have not been run\. . .SS "\fBpr\-upload\fR [\fIoptions\fR]" -Apply the bottle commit and publish bottles to Bintray or GitHub Releases\. +Apply the bottle commit and publish bottles to a host\. . .TP \fB\-\-no\-publish\fR @@ -1680,16 +1704,27 @@ Do not generate a new commit before uploading\. Warn instead of raising an error if the bottle upload fails\. Useful for repairing bottle uploads that previously failed\. . .TP +\fB\-\-archive\-item\fR +Upload to the specified Internet Archive item (default: \fBhomebrew\fR)\. +. +.TP \fB\-\-bintray\-org\fR Upload to the specified Bintray organisation (default: \fBhomebrew\fR)\. . .TP +\fB\-\-github\-org\fR +Upload to the specified GitHub organisation\'s GitHub Packages (default: \fBhomebrew\fR)\. +. +.TP \fB\-\-root\-url\fR Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew\'s default\. . -.SS "\fBprof\fR [\fI\-\-stackprof\fR] [\fIcommand\fR \.\.\.]" +.SS "\fBprof\fR [\fI\-\-stackprof\fR] \fIcommand\fR [\.\.\.]" Run Homebrew with a Ruby profiler\. For example, \fBbrew prof readall\fR\. . +.P +\fINote:\fR Not (yet) working on Apple Silicon\. +. .TP \fB\-\-stackprof\fR Use \fBstackprof\fR instead of \fBruby\-prof\fR (the default)\. @@ -1737,7 +1772,7 @@ Use the standard \fBPATH\fR instead of superenv\'s when \fBstd\fR is passed\. Execute commands in a non\-interactive shell\. . .SS "\fBsponsors\fR" -Print a Markdown summary of Homebrew\'s GitHub Sponsors, suitable for pasting into a README\. +Update the list of GitHub Sponsors in the \fBHomebrew/brew\fR README\. . .SS "\fBstyle\fR [\fIoptions\fR] [\fIfile\fR|\fItap\fR|\fIformula\fR|\fIcask\fR \.\.\.]" Check formulae or files for conformance to Homebrew style guidelines\. @@ -1786,7 +1821,7 @@ Label name for pull requests ready to be pulled (default: \fBpr\-pull\fR)\. . .TP \fB\-\-branch\fR -Initialize Git repository with the specified branch name (default: \fBmain\fR)\. +Initialize Git repository and setup GitHub Actions workflows with the specified branch name (default: \fBmain\fR)\. . .SS "\fBtest\fR [\fIoptions\fR] \fIinstalled_formula\fR [\.\.\.]" Run the test method provided by an installed formula\. There is no standard output or return code, but generally it should notify the user if something is wrong with the installed formula\. @@ -2392,7 +2427,7 @@ If set, use Bootsnap to speed up repeated \fBbrew\fR calls\. A no\-op when using \fBHOMEBREW_BOTTLE_DOMAIN\fR . .br -Use this URL as the download mirror for bottles\. For example, \fBHOMEBREW_BOTTLE_DOMAIN=http://localhost:8080\fR will cause all bottles to download from the prefix \fBhttp://localhost:8080/\fR\. +Use this URL as the download mirror for bottles\. If bottles at that URL are temporarily unavailable, the default bottle domain will be used as a fallback mirror\. For example, \fBHOMEBREW_BOTTLE_DOMAIN=http://localhost:8080\fR will cause all bottles to download from the prefix \fBhttp://localhost:8080/\fR\. If bottles are not available at \fBHOMEBREW_BOTTLE_DOMAIN\fR they will be downloaded from the default bottle domain\. . .IP \fIDefault:\fR macOS: \fBhttps://homebrew\.bintray\.com/\fR, Linux: \fBhttps://linuxbrew\.bintray\.com/\fR\. @@ -2575,6 +2610,18 @@ Use this personal access token for the GitHub API, for features such as \fBbrew \fINote:\fR Homebrew doesn\'t require permissions for any of the scopes, but some developer commands may require additional permissions\. . .TP +\fBHOMEBREW_GITHUB_PACKAGES_TOKEN\fR +. +.br +Use this GitHub personal access token when accessing the GitHub Packages Registry (where bottles may be stored)\. +. +.TP +\fBHOMEBREW_GITHUB_PACKAGES_USER\fR +. +.br +Use this username when accessing the GitHub Packages Registry (where bottles may be stored)\. +. +.TP \fBHOMEBREW_GIT_EMAIL\fR . .br @@ -2596,6 +2643,12 @@ Print this text before the installation summary of each successful build\. \fIDefault:\fR The "Beer Mug" emoji\. . .TP +\fBHOMEBREW_INTERNET_ARCHIVE_KEY\fR +. +.br +Use this API key when accessing the Internet Archive S3 API, where bottles are stored\. The format is access:secret\. See https://archive\.org/account/s3\.php +. +.TP \fBHOMEBREW_LIVECHECK_WATCHLIST\fR . .br @@ -2632,7 +2685,7 @@ If set, do not send analytics\. For more information, see: \fIhttps://docs\.brew \fBHOMEBREW_NO_AUTO_UPDATE\fR . .br -If set, do not automatically update before running \fBbrew install\fR, \fBbrew upgrade\fR or \fBbrew tap\fR\. +If set, do not automatically update before running some commands e\.g\. \fBbrew install\fR, \fBbrew upgrade\fR and \fBbrew tap\fR\. . .TP \fBHOMEBREW_NO_BOOTSNAP\fR @@ -2641,12 +2694,6 @@ If set, do not automatically update before running \fBbrew install\fR, \fBbrew u If set, do not use Bootsnap to speed up repeated \fBbrew\fR calls\. . .TP -\fBHOMEBREW_NO_BOTTLE_SOURCE_FALLBACK\fR -. -.br -If set, fail on the failure of installation from a bottle rather than falling back to building from source\. -. -.TP \fBHOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK\fR . .br @@ -2704,6 +2751,12 @@ If set, \fBbrew install\fR, \fBbrew upgrade\fR and \fBbrew reinstall\fR will nev If set, use Pry for the \fBbrew irb\fR command\. . .TP +\fBHOMEBREW_SIMULATE_MACOS_ON_LINUX\fR +. +.br +If set, running Homebrew on Linux will simulate certain macOS code paths\. This is useful when auditing macOS formulae while on Linux\. Implies \fBHOMEBREW_FORCE_HOMEBREW_ON_LINUX\fR\. +. +.TP \fBHOMEBREW_SKIP_OR_LATER_BOTTLES\fR . .br @@ -2843,16 +2896,16 @@ Homebrew API: \fIhttps://rubydoc\.brew\.sh\fR Homebrew\'s Project Leader is Mike McQuaid\. . .P -Homebrew\'s Project Leadership Committee is Jonathan Chang, Markus Reiter, Misty De Meo, Sean Molenaar and Shaun Jackman\. +Homebrew\'s Project Leadership Committee is Issy Long, Jonathan Chang, Markus Reiter, Misty De Meo and Sean Molenaar\. . .P -Homebrew\'s Technical Steering Committee is FX Coudert, Markus Reiter, Michka Popoff, Mike McQuaid and Misty De Meo\. +Homebrew\'s Technical Steering Committee is Bo Anderson, FX Coudert, Michka Popoff, Mike McQuaid and Rylan Polster\. . .P Homebrew\'s Linux maintainers are Daniel Nachun, Dawid Dziurla, Issy Long, Jonathan Chang, Michka Popoff and Shaun Jackman\. . .P -Homebrew\'s other current maintainers are Alexander Bayandin, Bo Anderson, Caleb Xu, Carlo Cabrera, Claudia Pellegrino, Dustin Rodrigues, Eric Knibbe, Maxim Belkin, Miccal Matthews, Nanda H Krishna, Randall, Rylan Polster, Sam Ford, Seeker, Steve Peters, Thierry Moisan, Tom Schoonjans, Vítor Galvão and rui\. +Homebrew\'s other current maintainers are Alexander Bayandin, Caleb Xu, Carlo Cabrera, Claudia Pellegrino, Dustin Rodrigues, Eric Knibbe, Maxim Belkin, Miccal Matthews, Nanda H Krishna, Randall, Sam Ford, Seeker, Steve Peters, Thierry Moisan, Tom Schoonjans, Vitor Galvao and rui\. . .P Former maintainers with significant contributions include Jan Viljanen, JCount, commitay, Dominyk Tiller, Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski, Alyssa Ross, ilovezfs, Chongyu Zhu and Homebrew\'s creator: Max Howell\.